web-dev-qa-db-fra.com

Comment spécifier le préfixe pour tous les contrôleurs dans Spring Boot?

J'ai des mappages de contrôleur sur /user et /order:

@RestController
@RequestMapping("/users")
public class UserController {
    ...
}

@RestController
@RequestMapping("/orders")
public class OrderController {
    ...
}

Je veux accéder à ceux-ci par URL à http://localhost:8080/api/users et http://localhost:8080/api/orders, respectivement.

Comment puis-je atteindre cet objectif dans Spring Boot? 

39
Murali

Vous pouvez mapper le chemin du contexte racine de votre application de démarrage printanier sur /api/* dans votre configuration personnalisée. 

import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;

@Configuration
public class DispatcherServletCustomConfiguration {

    @Bean
    public DispatcherServlet dispatcherServlet() {
        return new DispatcherServlet();
    }

    @Bean
    public ServletRegistrationBean dispatcherServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(
                dispatcherServlet(), "/api/");
        registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
        return registration;
    }
}

ou ajoutez ceci à votre dossier application.properties in src\main\resources

server.contextPath=/api/*

Plus vous trouvez ici Racine de contexte de démarrage du printemps et ici Ajoutez le mappage de servlet à DispatcherServlet

41
Tomasz Janek

Si vous voulez ajouter un préfixe juste pour certains contrôleurs, j'ai trouvé deux autres solutions 

Option 1 - Utilisez SPEL à ressort pour ajouter une variable de préfixe à vos contrôleurs

@RestController
@RequestMapping(path = "${v1API}/users")
public class V1FruitsController {

    @GetMapping(path = "")
    @ResponseBody
    public String list(){
        return "[\"Joe\", \"Peter\"]";
    }
}

application.properties

v1API=/api/v1

Option 2 - Créer une annotation de contrôleur personnalisée

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@RequestMapping("/api/v1")
public @interface V1APIController {
    @AliasFor(annotation = Component.class)
    String value() default "";
}


@V1APIController
public class UserController {

    @RequestMapping("/users")
    @ReponseBody
    public String index(){
        return "[\"Joe\", \"Peter\"]";
    }
}

puis testez

curl -X GET localhost:8080/api/v1/users
12
deFreitas

Si vous utilisez une botte à ressort 2 (cadre de ressort 5), la propriété est remplacée dans votre application.properties:

server.contextPath

pour:

server.servlet.context-path=
2
Eduardo

Pour ceux qui sont intéressés, voici une prise Kotlin sur Composant Option 2 de deFreitas car je n’ai pas pu utiliser spring.data.rest.basePath ou server.servlet.contextPath dans application.yaml. (Ceci est avec Spring Boot 2.1.2 et Kotlin 1.13.11)

package com.myproject.controller

import org.springframework.core.annotation.AliasFor
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.RequestMapping

import kotlin.annotation.MustBeDocumented
import kotlin.annotation.Retention
import kotlin.annotation.Target
import kotlin.annotation.AnnotationRetention

@Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
@RequestMapping("/api/v1")
annotation class V1ApiController(
    @get:AliasFor(annotation = Component::class)
    val value: String = ""
)

Si vous utilisez IntelliJ, l'optimisation des importations supprimera probablement les importations d'annotations Kotlin par souci de brièveté.

0
geeves