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

Spring Boot中如何判断Swagger UI选择的Produces响应类型?

好问题!当你的Spring Boot控制器方法同时配置了produces = {"text/html", "application/json"},并且在Swagger UI中允许用户选择响应类型时,其实可以通过几种简单直接的方式判断用户最终选择的是哪一种:

1. 直接读取Accept请求头

Swagger UI在用户选择响应类型后,会自动在请求的Accept头中填入对应的类型值。你可以通过注入HttpServletRequest来获取这个头信息:

@PostMapping(value = "/demo-endpoint", 
              produces = {"text/html", "application/json"},
              consumes = {"application/json"})
public ResponseEntity<?> handleRequest(@RequestBody DemoRequest request, 
                                      HttpServletRequest servletRequest) {
    String acceptHeader = servletRequest.getHeader("Accept");
    
    if (MediaType.TEXT_HTML_VALUE.equals(acceptHeader)) {
        // 处理HTML响应逻辑
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_HTML)
                .body("<div><h2>Hello from HTML Response!</h2></div>");
    } else if (MediaType.APPLICATION_JSON_VALUE.equals(acceptHeader)) {
        // 处理JSON响应逻辑
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(new DemoResponse("Hello from JSON Response!"));
    }
    
    // 默认返回JSON(应对Accept头为*/*的情况)
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(new DemoResponse("Default JSON Response"));
}

2. 用@RequestHeader注解简化获取

不想注入HttpServletRequest?可以直接用@RequestHeader注解绑定Accept头,代码会更简洁:

@PostMapping(value = "/demo-endpoint", 
              produces = {"text/html", "application/json"},
              consumes = {"application/json"})
public ResponseEntity<?> handleRequest(@RequestBody DemoRequest request, 
                                      @RequestHeader("Accept") String acceptHeader) {
    if (MediaType.TEXT_HTML_VALUE.equals(acceptHeader)) {
        // HTML响应逻辑
    } else if (MediaType.APPLICATION_JSON_VALUE.equals(acceptHeader)) {
        // JSON响应逻辑
    }
    // ... 默认逻辑
}

这里推荐使用MediaType类的常量(比如MediaType.TEXT_HTML_VALUE),避免硬编码字符串带来的拼写错误。

3. 进阶:用ContentNegotiationManager处理复杂场景

如果遇到用户设置了通配符Accept头(比如*/*),或者需要更灵活的内容协商逻辑,可以借助Spring提供的ContentNegotiationManager:

@Autowired
private ContentNegotiationManager contentNegotiationManager;

@PostMapping(value = "/demo-endpoint", 
              produces = {"text/html", "application/json"},
              consumes = {"application/json"})
public ResponseEntity<?> handleRequest(@RequestBody DemoRequest request, 
                                      HttpServletRequest servletRequest) {
    ServletWebRequest webRequest = new ServletWebRequest(servletRequest);
    List<MediaType> resolvedMediaTypes = contentNegotiationManager.resolveMediaTypes(webRequest);
    
    // 取第一个匹配的MediaType(Spring会按优先级排序)
    MediaType selectedType = resolvedMediaTypes.get(0);
    
    if (selectedType.equals(MediaType.TEXT_HTML)) {
        // HTML响应逻辑
    } else if (selectedType.equals(MediaType.APPLICATION_JSON)) {
        // JSON响应逻辑
    }
    // ... 默认逻辑
}

这种方式能自动处理各种Accept头的匹配规则,比手动判断更健壮。

补充:Swagger UI中的操作逻辑

在Swagger UI的接口页面,点击「Try it out」后,你会看到「Response content type」的下拉框——用户选择的类型会被自动填入请求的Accept头中,所以上面的三种方法都能准确捕获到用户的选择。

内容的提问来源于stack exchange,提问作者Vibhash Jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:05:46