Как установить базовый url для rest в spring boot?
Я пытаюсь смешать mvc и rest в одном проекте spring boot.
Я хочу установить базовый путь для всех остальных контроллеров (например. example.com/api)
в одном месте (я не хочу комментировать каждый контроллер с @RequestMapping('api/products'), а @RequestMapping('/products').
контроллеры Mvc должны быть доступны example.com/whatever
это возможно?
(Я не использую spring data rest, просто spring mvc)
11 ответов:
С Spring Boot 1.2+, все, что требуется, это одно свойство в приложении.свойства:
spring.data.rest.basePath=/apiссылка ссылки: https://docs.spring.io/spring-data/rest/docs/current/reference/html/#getting-started.changing-base-uri
немного поздно, но тот же вопрос привел меня сюда, прежде чем достичь ответа, поэтому я размещаю его здесь. Создать (если еще нет) приложение.свойства и добавить
server.contextPath=/apiТак, в предыдущем примере, если у вас есть RestController с
@RequestMapping("/test")доступ к нему, какlocalhost:8080/api/test/{your_rest_method}вопрос источник: как выбрать url для моего spring boot webapp
Так как это первый хит google для этой проблемы, и я предполагаю, что больше людей будут искать это. Существует новая опция с весны загрузки '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); } }; } }; } }
Я не мог поверить, насколько сложен ответ на этот, казалось бы, простой вопрос. Вот некоторые ссылки:
- весенний билет Джира
- еще один такой вопрос
- еще один такой вопрос
- очень хороший GitRepository, который демонстрирует проблему
есть много различных вещей, чтобы рассмотреть:
- By установка
server.context-path=/apiinapplication.propertiesвы можете настроить префикс все.(Свой сервер.контекст-путь не сервер.самом contextpath !)- контроллеры данных Spring с аннотацией @RepositoryRestController, которые предоставляют репозиторий в качестве конечной точки rest, будут использовать переменную среды
spring.data.rest.base-pathнаapplication.properties. Но просто@RestControllerне принимать это во внимание. Согласно spring data rest documentation есть аннотации@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\"}"; } }
я нашел чистое решение, которое влияет только на контроллеры rest.
@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бобы в контексте rest, они могут быть определены в Родительском контексте
Я могу немного опоздать, но ... .. Я считаю, что это лучшее решение. Установите его в своем приложении.yml (или аналогичный конфигурационный файл):
spring: data: rest: basePath: /apiКак я помню, это все-все ваши репозитории будут выставлены под этим URI.
вы можете создать пользовательскую аннотацию для ваших контроллеров:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @RestController @RequestMapping("/test") public @interface MyRestController { }используйте его вместо обычного @RestController на ваших классах контроллера и аннотировать методы с @RequestMapping.
только что проверил - работает весной 4.2!
вы можете создать базовый класс с
@RequestMapping("rest")аннотации и расширить все другие классы с этим базовым классом.@RequestMapping("rest") public abstract class BaseController {}Теперь все классы, которые расширяют этот базовый класс, будут доступны по адресу
rest/**.
для версии Spring boot framework
2.0.4.RELEASE+. Добавьте эту строкуapplication.propertiesserver.servlet.context-path=/api
такое решение применяется, если:
- вы хотите, чтобы префикс
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+.
Comments