私は1つの春のブートプロジェクトでmvcと休息を混在させようとしています。
すべての残りのコントローラ(example.com/apiなど)のベースパスを1か所に設定したい(各コントローラに@RequestMapping('api/products')
のアノテーションを付けるのではなく、単に@RequestMapping('/products')
を付けたくない)。
Mvcコントローラーはexample.com/whateverからアクセス可能であるべきです
出来ますか?
(私は春のデータ残りを使わない、ただ春のmvc)
Spring Boot 1.2以降では、application.properties内の単一のプロパティだけで済みます。
spring.data.rest.basePath=/api
ちょっと遅くなりましたが、同じ質問で答えが出る前にここに来ましたので、ここに投稿します。 application.propertiesを作成し(まだ持っていない場合)、追加します。
server.contextPath=/api
したがって、前の例で@RequestMapping("/test")
を持つRestControllerがある場合は、localhost:8080/api/test/{your_rest_method}
のようにアクセスします。
春のブートフレームワークのバージョン2.0.4.RELEASE+
。この行をapplication.properties
に追加します
server.servlet.context-path=/api
これが問題の最初のグーグルヒットであり、私はより多くの人々がこれを検索すると思います。 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);
}
};
}
};
}
}
この一見単純な質問に対する答えがどれほど複雑になるか私は信じられませんでした。ここにいくつかの参照があります:
考慮すべき点がたくさんあります。
server.context-path=/api
にapplication.properties
を設定することで、すべてのプレフィックスを設定できます(server.context-pathではなくserver.contextPath!)。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\"}";
}
}
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
と@RestControllers
のrestApi
ディスパッチャは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
を使用すると、利用可能な他のコンテキストタイプを使用できます。 AnnotationConfigWebApplicationContext
、GenericWebApplicationContext
、GroovyWebApplicationContext
、...jsonMessageConverter
、messageConverters
Beanをrestコンテキストで定義し、それらはparentコンテキストで定義することができます。私は少し遅れるかもしれません、しかし...私はそれが最善の解決策であると信じます。あなたのapplication.yml(または類似の設定ファイル)でそれを設定してください:
spring:
data:
rest:
basePath: /api
覚えていると思いますが、すべてのリポジトリはこのURIの下に公開されます。
あなたはあなたのコントローラ用のカスタムアノテーションを作成することができます:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
@RequestMapping("/test")
public @interface MyRestController {
}
あなたのコントローラクラスで通常の@RestControllerの代わりにそれを使い、@RequestMappingでメソッドにアノテーションを付けてください。
たった今テストされました - Spring 4.2で動きます!
@RequestMapping("rest")
アノテーションを使って基本クラスを作成し、この基本クラスを使って他のすべてのクラスを拡張することができます。
@RequestMapping("rest")
public abstract class BaseController {}
この基本クラスを拡張するすべてのクラスはrest/**
でアクセス可能になります。
Spring-boot 2.xでは、application.propertiesで設定できます。
spring.mvc.servlet.path=/api
働いたserver.contextPath =/path
Per Spring Data REST docs 、application.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月に作成されました。)
この解決策は以下の場合に適用されます。
RestController
を望むがController
を望まない。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以降のどのバージョンでもサポートされるはずです。