我已經更新的1.4.x從一個Spring應用程序啓動1.5.1和彈簧操動終點回到現在不同的MIME類型:響應MIME類型春季啓動執行端點
例如,/health
現在application/vnd.spring-boot.actuator.v1+json
代替只需application/json
。
我該如何改變這種情況?
我已經更新的1.4.x從一個Spring應用程序啓動1.5.1和彈簧操動終點回到現在不同的MIME類型:響應MIME類型春季啓動執行端點
例如,/health
現在application/vnd.spring-boot.actuator.v1+json
代替只需application/json
。
我該如何改變這種情況?
端點返回一個內容類型,該內容類型表示客戶機的請求表示它可以接受的內容。你會得到一個application/json
響應,如果客戶端發送一個Accept
頭,詢問它:使用Firefox檢查端點時:
Accept: application/json
針對的https://stackoverflow.com/users/2952093/kap評論(我的名聲是低創建註釋)返回JSON我使用附加JSONView。在設置中,您可以選擇指定備用JSON內容類型,只需添加application/vnd.spring-boot.actuator.v1+json
即可在瀏覽器中看到返回的JSON。
正如您注意到執行器的內容類型在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
基於對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
快速問題:if(.. 。被刪除...){...重新添加...}'? 'HashSet.remove()'[只在元素出現時纔會移除](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html#remove-java.lang.Object - )。這有效,但爲什麼? :-) – crusy
你的代碼將'[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
@crusy我不知道這個特殊的新類型是用於/預期的,所以我不想刪除它。它可以保留在受支持的mediatype列表中,因此需要它的代碼仍然可以請求它,但它應該出現在「application/json」之後,因爲我想使用默認瀏覽器來獲取json。由於'LinkedHashSet'不斷插入,所以我只需將其刪除並重新添加即可將其排序。用'if'來確保我不會修改沒有這個新類型的東西。 – zapl
經測試支持在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
它說它贏得'對於Firefox 58+來說是必要的:「這個插件的目的已經被本地整合到Firefox 58中。」 – AndreLDM
@AndreLDM是的,我已經更新了答案。 –
自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);
}
}
好吧,這至少適用於我自己的應用程序,並且表現良好的人。對於Firefox我不得不尋找一些設置,它總是下載端點而不是顯示它們。謝謝。 – kap
我也被這個咬了。請問爲什麼改變了?改變我們公司使用的所有瀏覽器的設置有點像PITA。我甚至還沒有發現如何在Safari或智能手機上的瀏覽器中做到這一點。任何機會的變化是否與以下問題有關? https://github.com/spring-projects/spring-boot/issues/7648 –
這仍然會更改不提供應用程序/ json的客戶端中收到的內容類型。你爲什麼不保留v1的行爲,只是在v2中改變它? 請參閱https://github.com/spring-projects/spring-boot/issues/7967,「我們打算在2.0中打破東西,因此返回1.x中的內容類型將是一件好事。 「 (所以讓我們在v1中打破思維也:>) 無論如何定製健康端點現在實現。 – hirro