2017-02-20 83 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); 
    } 
}