2017-02-20 80 views
20

我已经更新的1.4.x从一个Spring应用程序启动1.5.1和弹簧操动终点回到现在不同的MIME类型:响应MIME类型春季启动执行端点

例如,/health现在application/vnd.spring-boot.actuator.v1+json代替只需application/json

我该如何改变这种情况?

回答

13

端点返回一个内容类型,该内容类型表示客户机的请求表示它可以接受的内容。你会得到一个application/json响应,如果客户端发送一个Accept头,询问它:使用Firefox检查端点时:

Accept: application/json 
+3

好吧,这至少适用于我自己的应用程序,并且表现良好的人。对于Firefox我不得不寻找一些设置,它总是下载端点而不是显示它们。谢谢。 – kap

+4

我也被这个咬了。请问为什么改变了?改变我们公司使用的所有浏览器的设置有点像PITA。我甚至还没有发现如何在Safari或智能手机上的浏览器中做到这一点。任何机会的变化是否与以下问题有关? https://github.com/spring-projects/spring-boot/issues/7648 –

+0

这仍然会更改不提供应用程序/ json的客户端中收到的内容类型。你为什么不保留v1的行为,只是在v2中改变它? 请参阅https://github.com/spring-projects/spring-boot/issues/7967,“我们打算在2.0中打破东西,因此返回1.x中的内容类型将是一件好事。 “ (所以让我们在v1中打破思维也:>) 无论如何定制健康端点现在实现。 – hirro

12

针对的https://stackoverflow.com/users/2952093/kap评论(我的名声是低创建注释)返回JSON我使用附加JSONView。在设置中,您可以选择指定备用JSON内容类型,只需添加application/vnd.spring-boot.actuator.v1+json即可在浏览器中看到返回的JSON。

5

正如您注意到执行器的内容类型在1.5.x中发生了变化。

如果你把“application/json”放在“Accept:”头中,你应该得到通常的内容类型。

但是,如果您没有任何修改客户端的方式,此代码段会返回健康状态(没有详细信息)和原始内容类型(1.4.x方式)。

@RestController 
@RequestMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE) 
public class HealthController { 

    @Inject 
    HealthEndpoint healthEndpoint; 

    @RequestMapping(method = RequestMethod.GET) 
    @Timed 
    public Health health() throws IOException { 
     Health health = healthEndpoint.invoke(); 
     return Health.status(health.getStatus()).build(); 
    } 
} 

配置(搬开现有卫生)

endpoints.health.path: internal/health 
4

基于对https://github.com/spring-projects/spring-boot/issues/2449代码(也工作正常,但完全消除新型),我想出了

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

这使得新的供应商 - 介质类型最后使得它将使用application/json作为全部当没有任何东西时致动器端点指定。

弹簧引导1.5.3

+0

快速问题:if(.. 。被删除...){...重新添加...}'? 'HashSet.remove()'[只在元素出现时才会移除](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html#remove-java.lang.Object - )。这有效,但为什么? :-) – crusy

+0

你的代码将'[application/vnd.spring-boot.actuator.v1 + json,application/json]'切换到'[application/json,application/vnd.spring-boot.actuator.v1 + json]' 。什么工作(以及可能不那么令人困惑):'lhs.remove(ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON); lhs.add(MediaType.APPLICATION_JSON);' – crusy

+0

@crusy我不知道这个特殊的新类型是用于/预期的,所以我不想删除它。它可以保留在受支持的mediatype列表中,因此需要它的代码仍然可以请求它,但它应该出现在“application/json”之后,因为我想使用默认浏览器来获取json。由于'LinkedHashSet'不断插入,所以我只需将其删除并重新添加即可将其排序。用'if'来确保我不会修改没有这个新类型的东西。 – zapl

2

经测试支持在Firefox的内置JSON观众application/vnd.spring-boot.actuator.v1+json,可以安装这个插件:json-content-type-override。它会将包含“json”的内容类型转换为“application/json”。

更新: Firefox 58+内置了对这些MIME类型的支持,不再需要插件。请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1388335

+0

它说它赢得'对于Firefox 58+来说是必要的:“这个插件的目的已经被本地整合到Firefox 58中。” – AndreLDM

+0

@AndreLDM是的,我已经更新了答案。 –

0

自SpringBoot 2.0.x起,实施EndpointHandlerMappingCustomizer的建议解决方案不再有效。

好消息是,解决方案现在更简单。需要提供豆EndpointMediaTypes。它由默认的SpringBoot类WebEndpointAutoConfiguration提供。

提供自己看起来是这样的:

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