Cómo configurar URL base para descansar en el arranque de spring?

Estoy tratando de mezclar mvc y descansar en un solo proyecto de arranque de spring.

Quiero establecer la ruta base para todos los controladores de reposo (por ejemplo, example.com/api) en un solo lugar (no quiero anotar cada controlador con @RequestMapping('api/products') , sino simplemente @RequestMapping('/products') .

Los controladores de Mvc deben ser accesibles por example.com/whatever

¿Es posible?

(No uso el rest de datos de spring, solo mvc de spring)

Con Spring Boot 1.2+, todo lo que necesita es una sola propiedad en application.properties:

 spring.data.rest.basePath=/api 

ref link: http://docs.spring.io/spring-data/rest/docs/current/reference/html/#_changing_the_base_uri

Un poco tarde, pero la misma pregunta me trajo aquí antes de llegar a la respuesta, así que la publico aquí. Crea (si aún no lo tienes) una aplicación.propiedades y agrega

 server.contextPath=/api 

Entonces, en el ejemplo anterior, si tiene un RestController con @RequestMapping("/test") , tendrá acceso como localhost:8080/api/test/{your_rest_method}

fuente de la pregunta: cómo elijo la URL de mi webapp de arranque de spring

Dado que este es el primer hit de Google para el problema y supongo que más personas buscarán esto. Hay una nueva opción desde Spring Boot ‘1.4.0’. Ahora es posible definir un RequestMappingHandlerMapping personalizado que permita definir una ruta diferente para las clases anotadas con @RestController

Una versión diferente con anotaciones personalizadas que combina @RestController con @RequestMapping se puede encontrar en esta publicación de blog

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

No puedo creer lo complicada que es la respuesta a esta pregunta aparentemente simple. Aquí hay algunas referencias:

  • Entrada Spring JIRA
  • Otra pregunta SO
  • Sin embargo, otra pregunta SO
  • Muy buen GitRepository que muestra el problema

Hay muchas cosas diferentes a considerar:

  1. Al configurar server.context-path=/api en application.properties , puede configurar un prefijo para todo . (Su server.context-path not server.contextPath!)
  2. Los controladores de Spring Data anotados con @RepositoryRestController que exponen un repository como punto final de rest utilizarán la variable de entorno spring.data.rest.base-path en application.properties . Pero el @RestController simple no tendrá esto en cuenta. De acuerdo con la documentación de reposo de datos de spring hay una anotación @BasePathAwareController que puede usar para eso. Pero tengo problemas en relación con Spring-security cuando bash asegurar un controlador de este tipo. Ya no se encuentra.

Otra solución es un truco simple. No puede prefijar una cadena estática en una anotación, pero puede usar expresiones como esta:

 @RestController public class PingController { /** * Simple is alive test * @return 
{"Hello":"World"}

*/ @RequestMapping("${spring.data.rest.base-path}/_ping") public String isAlive() { return "{\"Hello\":\"World\"}"; } }

Encontré una solución limpia, que solo afecta a los controladores de descanso.

 @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 registrará dos servlets de despachador – dispatcherServlet por defecto para los controladores, y restApi dispatcher para @RestControllers definidos en rest.xml :

 2016-06-07 09:06:16.205 INFO 17270 --- [ main] osbceServletRegistrationBean : Mapping servlet: 'restApi' to [/rest/*] 2016-06-07 09:06:16.206 INFO 17270 --- [ main] osbceServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 

El ejemplo rest.xml :

                 

Pero, no estás limitado a :

  • use XmlWebApplicationContext , puede usar cualquier otro tipo de contexto disponible, es decir. AnnotationConfigWebApplicationContext , GenericWebApplicationContext , GroovyWebApplicationContext , …
  • define jsonMessageConverter , jsonMessageConverter beans en contexto de reposo, se pueden definir en el contexto principal

Podría llegar un poco tarde, PERO … creo que es la mejor solución. Configúralo en tu application.yml (o archivo de configuración analógica):

 spring: data: rest: basePath: /api 

Como puedo recordar, todos los repositorys estarán expuestos debajo de este URI.

Para Boot 2.0.0+ esto funciona para mí: server.servlet.context-path = / api

Puede crear una anotación personalizada para sus controladores:

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

Úselo en lugar del habitual @RestController en sus clases de controlador y anote los métodos con @RequestMapping.

¡Solo probado: funciona en Spring 4.2!

Puede crear una clase base con anotaciones @RequestMapping("rest") y extender todas las demás clases con esta clase base.

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

Ahora todas las clases que amplíen esta clase base estarán accesibles en rest/** .

Esta solución se aplica si:

  1. Desea prefijar RestController pero no Controller .
  2. No estás usando 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); } } 

    }

Esto es similar a la solución publicada por mh-dev, pero creo que esto es un poco más limpio y esto debería ser compatible con cualquier versión de Spring Boot 1.4.0+, incluyendo 2.0.0+.

Para el marco de arranque de spring versión 2.0.4.RELEASE+ . Agregue esta línea a application.properties

 server.servlet.context-path=/api