web-dev-qa-db-ja.com

春のブーツで安静のためにベースURLを設定する方法?

私は1つの春のブートプロジェクトでmvcと休息を混在させようとしています。

すべての残りのコントローラ(example.com/apiなど)のベースパスを1か所に設定したい(各コントローラに@RequestMapping('api/products')のアノテーションを付けるのではなく、単に@RequestMapping('/products')を付けたくない)。

Mvcコントローラーはexample.com/whateverからアクセス可能であるべきです

出来ますか?

(私は春のデータ残りを使わない、ただ春のmvc)

82
Teimuraz

Spring Boot 1.2以降では、application.properties内の単一のプロパティだけで済みます。

spring.data.rest.basePath=/api

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

45
Suroj

ちょっと遅くなりましたが、同じ質問で答えが出る前にここに来ましたので、ここに投稿します。 application.propertiesを作成し(まだ持っていない場合)、追加します。

server.contextPath=/api

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

質問のソース: どのように私は私の春のブートWebアプリケーションのためのURLを選ぶのですか

90
OriolBG

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

server.servlet.context-path=/api
32
shellhub

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

@ RestController@ RequestMappingを組み合わせたカスタムアノテーション付きの別のバージョンはこちらで見つけることができます blog post =

@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);
                    }
                };
            }
        };
    }
}
25
mh-dev

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

考慮すべき点がたくさんあります。

  1. server.context-path=/apiapplication.propertiesを設定することで、すべてのプレフィックスを設定できます(server.context-pathではなくserver.contextPath!)。
  2. リポジトリを残りのエンドポイントとして公開する@RepositoryRestControllerのアノテーションが付けられたSpring Dataコントローラーは、spring.data.rest.base-path内の環境変数application.propertiesを使用します。しかし、普通の@RestControllerはこれを考慮に入れません。 spring data rest documentation によれば、そのために使用できるアノテーション@BasePathAwareControllerがあります。しかし、そのようなコントローラを保護しようとすると、Spring-securityに関して問題が生じます。もう見つかりません。

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

@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\"}";
  }
}
22
Robert

Boot 2.0.0以降では、これは私にはうまくいく:server.servlet.context-path =/api

私はきれいな解決策を見つけました。

@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);
    }
}

Springブートは2つのディスパッチャサーブレットを登録します - コントローラのデフォルトのdispatcherServlet@RestControllersrestApiディスパッチャは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>

しかし、あなたは限定されない

  • XmlWebApplicationContextを使用すると、利用可能な他のコンテキストタイプを使用できます。 AnnotationConfigWebApplicationContextGenericWebApplicationContextGroovyWebApplicationContext、...
  • jsonMessageConvertermessageConverters Beanをrestコンテキストで定義し、それらはparentコンテキストで定義することができます。
9
kravemir

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

spring:
    data:
        rest:
            basePath: /api

覚えていると思いますが、すべてのリポジトリはこのURIの下に公開されます。

7
thorinkor

あなたはあなたのコントローラ用のカスタムアノテーションを作成することができます:

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

あなたのコントローラクラスで通常の@RestControllerの代わりにそれを使い、@RequestMappingでメソッドにアノテーションを付けてください。

たった今テストされました - Spring 4.2で動きます!

6

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

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

この基本クラスを拡張するすべてのクラスはrest/**でアクセス可能になります。

5
Saket Mehta

Spring-boot 2.xでは、application.propertiesで設定できます。

spring.mvc.servlet.path=/api
1
Bulgar Sadykov

働いたserver.contextPath =/path

0
Pravin

Per Spring Data REST docsapplication.propertiesを使用する場合は、このプロパティを使用してベースを設定します。パス:

spring.data.rest.basePath=/api

しかし、Spring sesrelaxed binding なので、このバリエーションは使用できます。

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

あなたが好むなら... ...またはこれ

spring.data.rest.base_path=/api

application.ymlを使用する場合は、キーの区切り文字にコロンを使用します。

spring:
  data:
    rest:
      basePath: /api

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

0
J Woodchuck

この解決策は以下の場合に適用されます。

  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が投稿した solution に似ていますが、これはもう少しきれいで、2.0.0以降を含むSpring Boot 1.4.0以降のどのバージョンでもサポートされるはずです。