春のブーツで残りのベースURLを設定するにはどうすればよいですか?


118

私は単一の春のブートプロジェクトでmvcと休憩を混合しようとしています。

すべての残りのコントローラー(例:example.com/api)のベースパスを1か所に設定したい(@RequestMapping('api/products')代わりに、で各コントローラーに注釈を付けたくありません)@RequestMapping('/products')

MVCコントローラーは、example.com / whateverからアクセスできる必要があります

出来ますか?

(私はSpring Data Restを使用せず、Spring MVCのみを使用しています)



server.servlet.contextPath = / api
ダニエルT.ソブロサ

スプリングブートバージョン2.1.4.RELEASE、spring.mvc.servlet.path = / apiおよびserver.servlet.context-path = / apiの両方が機能します
Prayag Sharma

server.servlet.context-path = / apiソリューションはAPPLICATION用であり、RESTだけではありません。SOAPサービスにも有効です。あなたはSOAPやRESTサービスのパスをsperateしたい場合は、( 'API / ...')を@RequestMapping使用する必要があります... medium.com/@bm.celalkartal/...
bmck

回答:


89

Spring Boot 1.2+(2.0未満)では、application.propertiesの単一のプロパティのみが必要です。

spring.data.rest.basePath=/api

参照リンク:https : //docs.spring.io/spring-data/rest/docs/current/reference/html/#getting-started.changing-base-uri

2.xの場合は、

server.servlet.context-path=/api

4
これは、thorinkorが与えた正確な答えです。
ジャン=フランソワ・Beauchef

8
おかげで、これはSpring Bootバージョンv1.5.7.RELEASEでは機能しません。他の回答server.contextPath = / apiが機能しました
Jay

10
@Surojそのソリューションは、RestControllerではなく、RepositoryRestController注釈付きコントローラーでのみ機能します...
Nano

jira.spring.io/browse/DATAREST-1211このJiraチケットは、「Spring Boot 2.0.0のspring.data.rest.base-path」であることを述べています。残念ながら、どちらもうまくいきません。
Carsten Hagemann、

6
SB 2+の場合、それはserver.servlet.context-path = / urlです
vicky '15年

95

少し遅れましたが、同じ質問が答えに到達する前にここに来たので、ここに投稿します。(まだ持っていない場合は)application.propertiesを作成して追加します。

server.contextPath=/api

したがって、前の例でRestControllerを使用している場合は、次の@RequestMapping("/test")ようにアクセスします。localhost:8080/api/test/{your_rest_method}

質問の出典:スプリングブートWebアプリのURLを選択するには


19
これを強制してRestControllersでのみ機能し、「/ api」なしで通常のコントローラーにアクセスする方法
Siya Sosibo

@Stoan解決策を見つけました。私の答えを確認してください:-)
kravemir

これを行わないでください!トーリンカーの答えを見てください。
Stefan

Thorinkorの回答は、Spring Data REST専用です。

8
server.contextPathは非推奨になりました

46

春のブートフレームワークのバージョン2.0.4.RELEASE+。この行を追加application.properties

server.servlet.context-path=/api

1
これはパブリックフォルダにも影響します:-(
Michel

5
これはSpring boot 2+の正解です。spring.data.rest.basePathSpring boot 2では機能しません
jackycflau 2018年

27

これは問題に対する最初のgoogleヒットであり、より多くの人々がこれを検索することになると思います。Spring Boot '1.4.0'以降、新しいオプションがあります。アノテーションが付けられたクラスに異なるパスを定義できるカスタムRequestMappingHandlerMappingを定義できるようになりましたました

@RestController@RequestMappingを組み合わせたカスタムアノテーション付きの別のバージョンは、このブログ投稿にあります。

@Configuration
public class WebConfig {

    @Bean
    public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() {
        return new WebMvcRegistrationsAdapter() {
            @Override
            public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
                return new RequestMappingHandlerMapping() {
                    private final static String API_BASE_PATH = "api";

                    @Override
                    protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
                        Class<?> beanType = method.getDeclaringClass();
                        if (AnnotationUtils.findAnnotation(beanType, RestController.class) != null) {
                            PatternsRequestCondition apiPattern = new PatternsRequestCondition(API_BASE_PATH)
                                    .combine(mapping.getPatternsCondition());

                            mapping = new RequestMappingInfo(mapping.getName(), apiPattern,
                                    mapping.getMethodsCondition(), mapping.getParamsCondition(),
                                    mapping.getHeadersCondition(), mapping.getConsumesCondition(),
                                    mapping.getProducesCondition(), mapping.getCustomCondition());
                        }

                        super.registerHandlerMethod(handler, method, mapping);
                    }
                };
            }
        };
    }
}

2
Spring Boot 2.0.0以降では、WebMvcRegistrationsインターフェイスを直接操作します。WebMvcRegistrationsAdapterが削除され、デフォルトのメソッドがインターフェースに追加されました。
Gilbert Arenas Dagger

27

この一見単純な質問の答えがどれほど複雑かは信じられませんでした。ここにいくつかの参照があります:

考慮すべき点は数多くあります。

  1. を設定server.context-path=/apiするapplication.propertiesことで、すべてのプレフィックスを構成できます(server.contextPathではなく、server.context-path!)
  2. 残りのエンドポイントとしてリポジトリを公開@RepositoryRestControllerでアノテート春データコントローラは、環境変数を使用しますspring.data.rest.base-pathapplication.properties。しかし、プレーン@RestControllerはこれを考慮に入れません。春のデータの残りのドキュメントによると、@BasePathAwareControllerそのために使用できる注釈があります。しかし、このようなコントローラーを保護しようとすると、Springのセキュリティに関して問題があります。もう見つかりません。

別の回避策は単純なトリックです。アノテーションで静的な文字列をプレフィックスすることはできませんが、次のような式を使用できます。

@RestController
public class PingController {

  /**
   * Simple is alive test
   * @return <pre>{"Hello":"World"}</pre>
   */
  @RequestMapping("${spring.data.rest.base-path}/_ping")
  public String isAlive() {
    return "{\"Hello\":\"World\"}";
  }
}

どのようにしてAnnotationに入れますか?
Teimuraz 2016

2
ええと、新しいコントローラを作成するたびに、必ずこのプレフィックスを追加することを忘れないでください
Gilbert Arenas Dagger


9

残りのコントローラーのみに影響するクリーンなソリューションを見つけました。

@SpringBootApplication
public class WebApp extends SpringBootServletInitializer {

    @Autowired
    private ApplicationContext context;

    @Bean
    public ServletRegistrationBean restApi() {
        XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
        applicationContext.setParent(context);
        applicationContext.setConfigLocation("classpath:/META-INF/rest.xml");

        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.setApplicationContext(applicationContext);

        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/rest/*");
        servletRegistrationBean.setName("restApi");

        return servletRegistrationBean;
    }

    static public void main(String[] args) throws Exception {
        SpringApplication.run(WebApp.class,args);
    }
}

春ブーツは2つのディスパッチャサーブレットを登録します-デフォルトdispatcherServletのコントローラのための、およびrestApiディスパッチャのため@RestControllersに定義されていますrest.xml

2016-06-07 09:06:16.205  INFO 17270 --- [           main] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'restApi' to [/rest/*]
2016-06-07 09:06:16.206  INFO 17270 --- [           main] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]

rest.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="org.example.web.rest"/>
    <mvc:annotation-driven/>

    <!-- Configure to plugin JSON as request and response in method handler -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter"/>
            </list>
        </property>
    </bean>

    <!-- Configure bean to convert JSON to POJO and vice versa -->
    <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </bean>
</beans>

ただし、これに限定されません

  • use XmlWebApplicationContext、使用可能な他のコンテキストタイプを使用できます。AnnotationConfigWebApplicationContextGenericWebApplicationContextGroovyWebApplicationContext、...
  • define jsonMessageConvertermessageConvertersbeanは残りのコンテキストで、親コンテキストで定義できます

XMLを使用せずにプログラムでこれを行うことは可能ですか?
アリアン

@ArianHosseinzadehはい。プログラムで行うことは可能です。Springコンテキストを設定する方法はたくさんあります。この例では、REST API処理の子コンテキストを作成する方法を示しました。Java内でコンテキストをセットアップする方法を学び、そのような知識をこの回答の知識と組み合わせるだけです。それはプログラミングと呼ばれています。
クラベミール2017年

7

コントローラのカスタムアノテーションを作成できます。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
@RequestMapping("/test")
public @interface MyRestController {
}

コントローラークラスで通常の@RestControllerの代わりに使用し、@ RequestMappingでメソッドに注釈を付けます。

テスト済み-Spring 4.2で動作します!


ありがとうございました。私はこれを試しました。しかし、今度は各メソッドに@RequestMapping( "/ products")、@ RequestMapping( "/ products / {id}")で注釈を付ける必要があります。代わりに、@ RequestMapping( "/ products")でコントローラに注釈を付け、@ RequestMapping、@RequestMapping( "/:id")でメソッドに注釈を付ける必要があります。また、製品コントローラーはapi / productsでアクセス可能である必要があります(たとえば、APIプレフィックスを1か所に設定する)
Teimuraz

2
その場合、いいえ、そのままでは解決策はありません、AFAIK。独自の実装を試すことができますRequestMappingHandlerMapping。Spring Data RESTには、必要なマッパーに似たマッパーがありますBasePathAwareHandlerMapping
Ilya Novoseltsev

@moreo、適切な解決策を見つけましたか?返信として投稿いただければ幸いです。ここでも同じ要件があります。
fischermatte

@fischermatte、いいえ、必要なものが正確に見つかりませんでした。@ RequestMapping( "/ api / products")または@RequestMapping( "/ api / users")を各コントローラクラスの前に置き、次にメソッドの前に別の@を置きますRequestMapping( "/ {id}")。しかし、これは大きな問題ではないと思います。「api」を何かに変更したい場合は、各クラスの最初に変更します。
Teimuraz、2015

@IlyaNovoseltsev解決策があります。私の答えを見てください:-)
kravemir

7

少し遅れるかもしれませんが、それが最善の解決策だと思います。application.yml(または類似の設定ファイル)で設定します:

spring:
    data:
        rest:
            basePath: /api

私はそれを覚えているので、あなたのすべてのリポジトリはこのURIの下に公開されます。


これについて少し説明したり、関連ドキュメントを示したりできますか?
Dmitry Serdiuk 2016年


11
environemnt変数 spring.data.rest.base-path は、spring-data-restとspring-hateoasにのみ影響します。プレーンな@RestControllerはまだルートにあります!
ロバート

4
@thorinkorは、ほとんどの場合、人々はSpring Data RESTリポジトリを構築すると言っていることに基づいていますか?そしてOPは明らかに彼は残りのコントローラを持っていると言っている...
ジャン=フランソワ・Beauchef

1
SpringDataRestを使用している場合にのみ機能すると思います。
Jaumzera 2017

6

PathMatchConfigurer(Spring Boot 2.x)を使用してみてください:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer  {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("api", HandlerTypePredicate.forAnnotation(RestController.class));
    }
}

1
ありがとう、これはまさに私が探していたものでした!これにより、spring.data.rest.base-pathと同様に、このWebMvcConfigを介して構成されたすべてのRestControllerのコンテキストパス要素を設定できます。
Buurman、

あなたの答えは@HaraldWendelにスポットされます:+1:コードを正確に説明する(私のコメントで試みたように)および/またはおそらくリンクするなど、少し拡張することでさらに改善できますこの使用法を説明するjavadocまたはドキュメント。
Buurman、

これは、コントローラーインターフェイスを使用しているときに機能した唯一のソリューションです
Anatoly Yakimchuk

4

@RequestMapping("rest")アノテーション付きの基本クラスを作成し、この基本クラスを使用して他のすべてのクラスを拡張できます。

@RequestMapping("rest")
public abstract class BaseController {}

これで、この基本クラスを拡張するすべてのクラスにでアクセスできるようになりますrest/**


3
これは正解ではありません。ユーザーがControllerアノテーションを参照しています。RequestMappingアノテーションを使用して抽象クラスを拡張し、新しいクラスにもRequestMappingがある場合、この最後は最初のものをオーバーライドし、2つを連結しません。
マッシモ

メタアノテーションを継承していない限り、アノテーションはJavaで継承されないことをご存知ですか?これを確認してください:stackoverflow.com/a/21409651。:そして@RequestMappingはその持っていないようですdocs.spring.io/spring-framework/docs/current/javadoc-api/org/...
Mashrur

3

YAML設定(application.yaml)を使用する人向け。

:これは、Spring Boot 2.x.x

server:
  servlet:
    contextPath: /api

まだ使用している場合 Spring Boot 1.x

server:
  contextPath: /api


1

server.servlet.context-path=/api私が推測する解決策でしょう。私は同じ問題を抱えていましたが、これで解決しました。server.context-pathを使用しました。しかし、それは非推奨であるように思われ、私server.servlet.context-pathはこれで問題を解決することがわかりました。別の回避策として、フロントエンド(H5)ページにベースタグを追加しました。これが誰かの役に立てば幸いです。

乾杯


0

このソリューションは、次の場合に適用されます。

  1. 接頭辞は付けたいRestControllerが、付けたくないController
  2. Spring Data Restを使用していません。

    @Configuration
    public class WebConfig extends WebMvcConfigurationSupport {
    
    @Override
    protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
        return new ApiAwareRequestMappingHandlerMapping();
    }
    
    private static class ApiAwareRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    
        private static final String API_PATH_PREFIX = "api";
    
        @Override
        protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
            Class<?> beanType = method.getDeclaringClass();
            if (AnnotationUtils.findAnnotation(beanType, RestController.class) != null) {
                PatternsRequestCondition apiPattern = new PatternsRequestCondition(API_PATH_PREFIX)
                        .combine(mapping.getPatternsCondition());
    
                mapping = new RequestMappingInfo(mapping.getName(), apiPattern, mapping.getMethodsCondition(),
                        mapping.getParamsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(),
                        mapping.getProducesCondition(), mapping.getCustomCondition());
            }
            super.registerHandlerMethod(handler, method, mapping);
        }
    }

    }

これはmh-devによって投稿されたソリューションに似ていますが、これは少しすっきりしていて、2.0.0 +を含むすべてのバージョンのSpring Boot 1.4.0+でサポートされるはずです。


RestControlerでPageableを使用している場合、api / somethingにより、インターフェイスorg.springframework.data.domain.Pageableのプライマリコンストラクターまたはデフォルトコンストラクターが見つかりません
K. Ayoub

0

Spring Data REST ドキュメントごとに、application.propertiesを使用している場合は、このプロパティを使用してベースパスを設定します。

spring.data.rest.basePath=/api

ただし、Spring リラックスしたバインディングを使用するため、このバリエーションを使用できます。

spring.data.rest.base-path=/api

...または必要に応じてこれ:

spring.data.rest.base_path=/api

使用している場合application.ymlを、あなたはキー区切りのためのコロンを使用します。

spring:
  data:
    rest:
      basePath: /api

(参考までに、ドキュメントを明確にするために、関連するチケットが2018年3月に作成されました。)



0

コントローラのカスタムアノテーションを作成できます。

コントローラークラスで通常の@RestControllerの代わりに使用し、@ RequestMappingでメソッドに注釈を付けます。

Spring 4.2では問題なく動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.