J'ai mis à jour une application Spring Boot de 1.4.x à 1.5.1 et les points de terminaison Spring Actuator renvoient maintenant un type MIME différent:
Par exemple, /health
est maintenant application/vnd.spring-boot.actuator.v1+json
à la place simplement application/json
.
Comment puis-je changer cela à nouveau?
Les points de terminaison renvoient un type de contenu qui respecte ce que la demande du client dit qu'il peut accepter. Vous obtiendrez un application/json
réponse si le client envoie un en-tête Accept
qui le demande:
Accept: application/json
En réponse au commentaire de https://stackoverflow.com/users/2952093/kap (ma réputation est trop faible pour créer un commentaire): lors de l'utilisation de Firefox pour vérifier les points de terminaison qui retournent JSON, j'utilise le Module complémentaire JSONView. Dans les paramètres, il existe une option pour spécifier d'autres types de contenu JSON, ajoutez simplement application/vnd.spring-boot.actuator.v1+json
et vous verrez le JSON retourné en jolie impression dans votre navigateur.
Comme vous l'avez remarqué, le type de contenu des actionneurs a changé en 1.5.x.
Si vous mettez "application/json" dans l'en-tête "Accept:", vous devriez obtenir le type de contenu habituel.
Mais si vous n'avez aucun moyen de modifier les clients, cet extrait renvoie la santé (sans détails) et le type de contenu d'origine (la manière 1.4.x).
@RestController
@RequestMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE)
public class HealthController {
@Inject
HealthEndpoint healthEndpoint;
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Health > health() throws IOException {
Health health = healthEndpoint.health();
Health nonSensitiveHealthResult = Health.status(health.getStatus()).build();
if (health.getStatus().equals(Status.UP)) {
return ResponseEntity.status(HttpStatus.OK).body(nonSensitiveHealthResult);
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(nonSensitiveHealthResult);
}
}
}
Configuration (éloignez la santé existante)
endpoints.health.path: internal/health
Basé sur le code https://github.com/spring-projects/spring-boot/issues/2449 (qui fonctionne également très bien mais supprime complètement le nouveau type), j'ai trouvé
@Component
public class ActuatorCustomizer implements EndpointHandlerMappingCustomizer {
static class Fix extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Object attribute = request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
if (attribute instanceof LinkedHashSet) {
@SuppressWarnings("unchecked")
LinkedHashSet<MediaType> lhs = (LinkedHashSet<MediaType>) attribute;
if (lhs.remove(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON)) {
lhs.add(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON);
}
}
return true;
}
}
@Override
public void customize(EndpointHandlerMapping mapping) {
mapping.setInterceptors(new Object[] {new Fix()});
}
}
ce qui place le nouveau fournisseur-mediatype en dernier afin qu'il utilise application/json
pour tous les points de terminaison de l'actionneur lorsque rien n'est spécifié.
Testé avec Spring-Boot 1.5.3
Soutenir application/vnd.spring-boot.actuator.v1+json
dans la visionneuse JSON intégrée à Firefox, vous pouvez installer cet addon: json-content-type-override . Il convertira les types de contenu qui contiennent "json" en "application/json".
Mise à jour: Firefox 58+ a un support intégré pour ces types de mime, et aucun addon n'est plus nécessaire. Voir https://bugzilla.mozilla.org/show_bug.cgi?id=1388335
Depuis SpringBoot 2.0.x, la solution suggérée pour implémenter le EndpointHandlerMappingCustomizer
ne fonctionne plus.
La bonne nouvelle est que la solution est maintenant plus simple.
Le Bean EndpointMediaTypes
doit être fourni. Il est fourni par la classe SpringBoot WebEndpointAutoConfiguration
par défaut.
Fournir le vôtre pourrait ressembler à ceci:
@Configuration
public class ActuatorEndpointConfig {
private static final List<String> MEDIA_TYPES = Arrays
.asList("application/json", ActuatorMediaType.V2_JSON);
@Bean
public EndpointMediaTypes endpointMediaTypes() {
return new EndpointMediaTypes(MEDIA_TYPES, MEDIA_TYPES);
}
}