【问题标题】:How to disable content negotiation for Spring Actuators?如何禁用 Spring 执行器的内容协商?
【发布时间】:2019-11-22 17:30:00
【问题描述】:

我想在调用执行器端点 /info/health 时禁用内容协商

这是我的配置文件

@Configuration
public class InterceptorAppConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor);
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_XML)
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xml", MediaType.APPLICATION_XML);
    }
}

当我curl http://localhost:8081/health

我收到:

DefaultHandlerExceptionResolver Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]

但是,当我在 Chrome 中触发相同的 url 时,我会收到有效的响应。

在我的情况下,执行器应该在没有标题的情况下调用(没有 -H 'Accept: ...')

【问题讨论】:

  • configurer.ignoreAcceptHeader(true) 是否满足您的需求?
  • 不,我仍然需要能够发送带有标头的 GET 请求,例如-H '接受:应用程序/json' 和 xml

标签: java spring-boot spring-boot-actuator content-negotiation


【解决方案1】:

很遗憾,我只能提供一个次优的解决方案。

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
            .mediaType("json", MediaType.APPLICATION_JSON)
            .mediaType("xml", MediaType.APPLICATION_XML)
            .defaultContentTypeStrategy((webRequest) -> {
                final String servletPath = ((HttpServletRequest) webRequest.getNativeRequest()).getServletPath();
                final MediaType defaultContentType = Arrays.asList("/info", "/health").contains(servletPath)
                        ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML;
                return Collections.singletonList(defaultContentType);
            });
}

如果/info/health 端点被调用application/json,则返回。在所有其他请求上,使用默认的 application/xml

【讨论】:

    【解决方案2】:

    添加 defaultContentTypeStrategy 并处理 null 或通配符接受。

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_XML)
        .mediaType("json", MediaType.APPLICATION_JSON)
        .mediaType("xml", MediaType.APPLICATION_XML);
    
        configurer.defaultContentTypeStrategy(new ContentNegotiationStrategy() {
            @Override
            public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
                // If you want handle different cases by getting header with webRequest.getHeader("accept")
                return Arrays.asList(MediaType.APPLICATION_JSON);
            }
        });       
    }
    

    【讨论】:

    • 谢谢,但这只是覆盖默认内容类型,设置为 XML configurer.defaultContentType(MediaType.APPLICATION_XML)
    猜你喜欢
    • 2016-01-05
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多