Comment définir l’URL de base pour le repos au démarrage du spring?

J’essaie de mélanger le mvc et de me reposer dans un seul projet de démarrage au spring.

Je veux définir un chemin de base pour tous les contrôleurs de repos (par exemple, exemple.com/api) en un seul endroit (je ne veux pas annoter chaque contrôleur avec @RequestMapping('api/products') , mais simplement @RequestMapping('/products') .

Les contrôleurs Mvc doivent être accessibles par example.com/whatever

C’est possible?

(Je n’utilise pas de données de spring, juste du spring mvc)

Avec Spring Boot 1.2+, il suffit d’une seule propriété dans application.properties:

 spring.data.rest.basePath=/api 

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

Un peu en retard mais la même question m’a amené ici avant d’atteindre la réponse alors je la poste ici. Créez (si vous ne l’avez toujours pas) une application.properties et ajoutez

 server.contextPath=/api 

Donc, dans l’exemple précédent, si vous avez un RestController avec @RequestMapping("/test") vous y accéderez comme localhost:8080/api/test/{your_rest_method}

source de la question: comment puis-je choisir l’URL pour mon webapp web boot

Étant donné que c’est le premier hit de Google pour le problème et que je suppose que plus de personnes vont le rechercher. Il y a une nouvelle option depuis Spring Boot ‘1.4.0’. Il est maintenant possible de définir un RequestMappingHandlerMapping personnalisé qui permet de définir un chemin différent pour les classes annotées avec @RestController

Une version différente avec des annotations personnalisées combinant @RestController avec @RequestMapping peut être trouvée sur cet article de blog.

 @Configuration public class WebConfig { @Bean public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() { return new WebMvcRegistrationsAdapter() { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new RequestMappingHandlerMapping() { private final static Ssortingng 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); } }; } }; } } 

Je ne pouvais pas croire à quel point la réponse à cette question apparemment simple est compliquée. Voici quelques références:

  • Billet du spring JIRA
  • Une autre question de SO
  • Encore une autre question SO
  • Très beau GitRepository qui présente le problème

Il y a beaucoup de choses à considérer:

  1. En définissant server.context-path=/api dans application.properties vous pouvez configurer un préfixe pour tout . (Son server.context-path pas server.contextPath!)
  2. Les contrôleurs Spring Data annotés avec @RepositoryRestController qui exposent un référentiel en tant que sharepoint terminaison utilisent la variable d’environnement spring.data.rest.base-path dans application.properties . Mais plain @RestController n’en tiendra pas compte. Selon la documentation de @BasePathAwareController il existe une annotation @BasePathAwareController que vous pouvez utiliser pour cela. Mais j’ai des problèmes en relation avec la sécurité Spring lorsque je tente de sécuriser un tel contrôleur. Il n’est plus trouvé.

Une autre solution est une astuce simple. Vous ne pouvez pas préfixer une chaîne statique dans une annotation, mais vous pouvez utiliser des expressions telles que:

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

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

J’ai trouvé une solution propre, qui ne concerne que les contrôleurs de repos.

 @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(Ssortingng[] args) throws Exception { SpringApplication.run(WebApp.class,args); } } 

Spring boot enregistrera deux servlets du répartiteur – dispatcherServlet par défaut pour les contrôleurs et restApi dispatcher pour @RestControllers défini dans 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 [/] 

L’exemple rest.xml :

                 

Mais vous n’êtes pas limité à :

  • Utilisez XmlWebApplicationContext , vous pouvez utiliser n’importe quel autre type de contexte disponible, c.-à-d. AnnotationConfigWebApplicationContext , GenericWebApplicationContext , GroovyWebApplicationContext , …
  • définir jsonMessageConverter , messageConverters beans dans le contexte de repos, ils peuvent être définis dans le contexte parent

Je suis peut-être un peu en retard, MAIS … Je crois que c’est la meilleure solution. Configurez-le dans votre application.yml (ou fichier de configuration analogique):

 spring: data: rest: basePath: /api 

Si je me souviens bien, tous vos référentiels seront exposés sous cet URI.

Pour Boot 2.0.0+, cela fonctionne pour moi: server.servlet.context-path = / api

Vous pouvez créer une annotation personnalisée pour vos contrôleurs:

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

Utilisez-le à la place de @RestController habituel sur vos classes de contrôleur et annotez les méthodes avec @RequestMapping.

Juste testé – fonctionne au spring 4.2!

Vous pouvez créer une classe de base avec des @RequestMapping("rest") et étendre toutes les autres classes avec cette classe de base.

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

Maintenant, toutes les classes qui étendent cette classe de base seront accessibles au rest/** .

Cette solution s’applique si:

  1. Vous souhaitez préfixer RestController mais pas Controller .
  2. Vous n’utilisez pas 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 Ssortingng 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); } } 

    }

Ceci est similaire à la solution publiée par mh-dev, mais je pense que c’est un peu plus propre et cela devrait être supporté sur n’importe quelle version de Spring Boot 1.4.0+, y compris 2.0.0+.

Pour le framework de démarrage du spring version 2.0.4.RELEASE+ . Ajoutez cette ligne à application.properties

 server.servlet.context-path=/api