web-dev-qa-db-fra.com

Peut-on activer/désactiver un @RestController de démarrage printanier à l'aide de propriétés?

Étant donné une application "standard" de démarrage à ressort avec un @RestController, par exemple

@RestController
@RequestMapping(value = "foo", produces = "application/json;charset=UTF-8")
public class MyController {
    @RequestMapping(value = "bar")
    public ResponseEntity<String> bar(
        return new ResponseEntity<>("Hello world", HttpStatus.OK);
    }
}

Existe-t-il une annotation ou une technique empêchant le noeud final de démarrer du tout si/sauf si une propriété d'application donnée existe/n'existe pas.

Remarque: Le test et l'explosion d'une propriété dans la méthode ne constituent pas une solution, car le noeud final existera.

Je me moque de la granularité: c’est-à-dire que l’activation/la désactivation d’une méthode ou de la classe entière convient à la fois.


Parce qu'un profil n'est pas une propriété, le contrôle via profils ne résout pas mon problème.

32
Bohemian

J'ai trouvé une solution simple en utilisant @ConditionalOnExpression:

@RestController
@ConditionalOnExpression("${my.controller.enabled:false}")
@RequestMapping(value = "foo", produces = "application/json;charset=UTF-8")
public class MyController {
    @RequestMapping(value = "bar")
    public ResponseEntity<String> bar(
        return new ResponseEntity<>("Hello world", HttpStatus.OK);
    }
}

Avec cette annotation ajoutée, sauf si j'ai

my.controller.enabled=true

dans mon fichier application.properties, le contrôleur ne démarre pas du tout.

Vous pouvez également utiliser le plus pratique:

@ConditionalOnProperty("my.property")

Qui se comporte exactement comme ci-dessus; si la propriété est présente et "true", le composant démarre, sinon il ne le fait pas.

48
Bohemian

Ajout à cette question et une autre question ici.

Voici ma réponse:

En fait, j'utilisais le bean @RefreshScope. Lorsque vous souhaitez arrêter le Rest Controller au moment de l'exécution, il vous suffit de changer la propriété dudit contrôleur en false.

SO's link referenceing to change property au moment de l'exécution. 

Voici mes extraits de code de travail:

@RefreshScope
@RestController
class MessageRestController(
    @Value("\${message.get.enabled}") val getEnabled: Boolean,
    @Value("\${message:Hello default}") val message: String
) {
    @GetMapping("/message")
    fun get(): String {
        if (!getEnabled) {
            throw NoHandlerFoundException("GET", "/message", null)
        }
        return message
    }
}

Et il existe d'autres alternatives d'utilisation du filtre:

@Component
class EndpointsAvailabilityFilter @Autowired constructor(
    private val env: Environment
): OncePerRequestFilter() {
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        val requestURI = request.requestURI
        val requestMethod = request.method
        val property = "${requestURI.substring(1).replace("/", ".")}." +
                "${requestMethod.toLowerCase()}.enabled"
        val enabled = env.getProperty(property, "true")
        if (!enabled.toBoolean()) {
            throw NoHandlerFoundException(requestMethod, requestURI, ServletServerHttpRequest(request).headers)
        }
        filterChain.doFilter(request, response)
    }
}

Mon Github expliquant comment désactiver au moment de l'exécution

0
David Budiman