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
相关产品推荐
相关产品推荐

