You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot如何按URL配置不同默认Content-Type或用过滤器补充请求头

两种实现方案均可行,可根据业务场景选择

方案1:自定义内容协商策略(优先推荐)

不需要额外新增过滤器/拦截器,直接替换原有全局固定默认Content-Type的配置,通过Spring MVC原生提供的默认ContentType策略扩展点,按路径匹配返回对应媒体类型即可,该逻辑直接内嵌在内容协商流程中,性能损耗最低。
修改原有配置代码如下:

@Override
public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
    configurer.defaultContentTypeStrategy(new ContentNegotiationStrategy() {
        @Override
        public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
            HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
            String requestPath = request.getRequestURI();
            // 按实际业务规则匹配需要返回JSON的路径,支持前缀、正则、精确路径匹配
            if (requestPath.startsWith("/your-json-prefix/") || requestPath.matches(".*/json-interface-rule")) {
                return Collections.singletonList(MediaType.APPLICATION_JSON);
            }
            // 其余路径默认返回XML
            return Collections.singletonList(MediaType.APPLICATION_XML);
        }
    });
}

方案2:Servlet过滤器提前补全Content-Type请求头

如果需要在请求体解析(如JSON/XML报文反序列化阶段)也能读取到正确的Content-Type,可通过最高优先级的Servlet过滤器,在请求进入Spring MVC核心流程前,对未携带Content-Type的请求按路径补全对应头信息。
注意:不要使用HandlerInterceptor实现该逻辑,拦截器执行时机晚于内容协商、参数解析流程,会出现配置不生效的问题。
实现代码如下:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ContentTypeFillFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 仅处理未携带Content-Type的请求
        if (StringUtils.isBlank(request.getContentType())) {
            String requestPath = request.getRequestURI();
            String targetContentType = requestPath.startsWith("/your-json-prefix/")
                    ? MediaType.APPLICATION_JSON_VALUE
                    : MediaType.APPLICATION_XML_VALUE;
            // 通过RequestWrapper包装请求,覆写头读取逻辑
            filterChain.doFilter(new ContentTypeRequestWrapper(request, targetContentType), response);
            return;
        }
        filterChain.doFilter(request, response);
    }

    private static class ContentTypeRequestWrapper extends HttpServletRequestWrapper {
        private final String contentType;

        public ContentTypeRequestWrapper(HttpServletRequest request, String contentType) {
            super(request);
            this.contentType = contentType;
        }

        @Override
        public String getContentType() {
            return contentType;
        }

        @Override
        public String getHeader(String name) {
            if (HttpHeaders.CONTENT_TYPE.equals(name)) {
                return contentType;
            }
            return super.getHeader(name);
        }

        @Override
        public Enumeration<String> getHeaders(String name) {
            if (HttpHeaders.CONTENT_TYPE.equals(name)) {
                return Collections.enumeration(Collections.singletonList(contentType));
            }
            return super.getHeaders(name);
        }
    }
}

选型参考

  • 仅需要差异化设置响应默认媒体类型,选方案1,代码更轻量无侵入。
  • 需要请求参数解析、报文转换阶段也能读取到正确Content-Type,选方案2。

内容的提问来源于stack exchange,提问作者Ramachandran Murugaian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:42:58