Ответ 1
В Spring Boot 1. 2+ (& lt; 2.0) требуется только одно свойство в application.properties:
spring.data.rest.basePath=/api
Для 2.x используйте
server.servlet.context-path=/api
Я пытаюсь смешивать mvc и отдыхать в одном проекте загрузки spring.
Я хочу установить базовый путь для всех контроллеров останова (например, example.com/api)
в одном месте (я не хочу комментировать каждый контроллер с @RequestMapping('api/products')
, а просто @RequestMapping('/products')
.
Контроллеры Mvc должны быть доступны на example.com/whatever
Возможно ли это?
(я не использую spring данных, просто spring mvc)
В Spring Boot 1. 2+ (& lt; 2.0) требуется только одно свойство в application.properties:
spring.data.rest.basePath=/api
Для 2.x используйте
server.servlet.context-path=/api
Немного поздно, но тот же вопрос привел меня сюда, прежде чем ответить на него, поэтому я размещаю его здесь. Создайте (если у вас его еще нет) application.properties и добавьте
server.contextPath=/api
Итак, в предыдущем примере, если у вас есть RestController с @RequestMapping("/test")
, вы получите доступ к нему как localhost:8080/api/test/{your_rest_method}
источник вопроса: как выбрать URL-адрес для моего spring boot webapp
Для весенней загрузки фреймворка версия 2.0.4.RELEASE+
. Добавьте эту строку в application.properties
server.servlet.context-path=/api
Так как это первый хит Google для проблемы, и я предполагаю, что больше людей будут искать это. Существует новая опция с Spring Boot '1.4.0'. Теперь можно определить настраиваемое RequestMappingHandlerMapping, которое позволяет определить другой путь для классов, аннотированных с помощью @RestController
В этой блоге можно найти другую версию с пользовательскими аннотациями, которая объединяет @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);
}
};
}
};
}
}
Я не мог поверить, насколько сложен ответ на этот, казалось бы, простой вопрос. Вот несколько ссылок:
Есть много разных вещей, чтобы рассмотреть:
server.context-path=/api
в application.properties
вы можете настроить префикс для всего (его server.context-path не server.contextPath!)spring.data.rest.base-path
в application.properties
. Но обычный @RestController
не примет это во внимание. В соответствии с документацией по остальным данным spring есть аннотация @BasePathAwareController
которую вы можете использовать для этого. Но у меня возникают проблемы в связи со Spring-security, когда я пытаюсь защитить такой контроллер. Это больше не найдено.Другой обходной путь - простой трюк. Вы не можете использовать префикс статической строки в аннотации, но вы можете использовать такие выражения:
@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 boot зарегистрирует два диспетчерских сервлета - по умолчанию 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>
Но вы не ограничены:
XmlWebApplicationContext
, вы можете использовать любой доступный тип контекста, т.е. AnnotationConfigWebApplicationContext
, GenericWebApplicationContext
, GroovyWebApplicationContext
,...jsonMessageConverter
, messageConverters
beans в контексте отдыха, они могут быть определены в родительском контекстеВозможно, я немного опоздаю, НО... Я считаю, что это лучшее решение. Установите его в свой файл 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
Попробуйте использовать PathMatchConfigurer (Spring Boot 2.x):
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("api", HandlerTypePredicate.forAnnotation(RestController.class));
}
}
Это решение применяется, если:
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, но я думаю, что это немного чище, и это должно поддерживаться в любой версии Spring Boot 1.4. 0+, включая 2.0. 0+.
Для документов Spring Spring 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 года для уточнения документов.)
работал server.contextPath =/путь