【发布时间】:2017-11-16 15:59:55
【问题描述】:
我有一个 servlet,通常我会返回 text/csv 作为响应。所以一个普通的逗号分隔字符串。
但是:如果出现异常,我只想显示一些错误文本作为响应。但是 Spring 会生成一个自定义的 ResponseEntity 对象,然后尝试将此响应转换为显然失败的 csv。
是否可以将请求的格式替换为format=json,然后只返回默认的Spring错误响应?
@RestController
public class CsvServlet {
@RequestMapping(value = "/test", produces = "text/csv")
@ResponseBody
public String errorCsv(HttpServletRequest request) {
return "some, plain, text";
}
}
用法:localhost:8080/test?format=csv
当拥有spring.security.enabled=true 时,这将首先验证基本身份验证凭据。如果失败,spring 会自动重定向到/error servlet。
因此BasicErrorController.error() 方法进入,捕获错误并生成带有timestamp, exception, path, etc 等错误属性的ResponseEntity。
问题:现在返回 ResponseEntity 类型的 Object。只要格式参数是?format=json/xml,这很好。因为响应可以被正确转换。
但在我的特殊情况下,我请求?format=csv,对话将失败,导致:
无法创建响应: org.springframework.web.HttpMediaTypeNotAcceptableException:不能 找到可接受的代表
这部分正确,而且具有误导性,因为用户应该直接看到身份验证凭据无效。因为一般我接受csv,但Spring 和映射器不知道如何将ResponseEntity 转换为像csv 这样的普通格式。
问题:如何保留原始异常?这样我就可以返回纯文本错误消息。在这种情况下,如果我可以返回 application/json 响应也很好!
【问题讨论】:
-
您是否尝试使用
@ControllerAdvice添加 ExecptionHandlerAdvice? -
是的,但这只会捕获
HttpMediaTypeNotAcceptableException,而不是BadCredentialsException(如上所述,BasicErrorController会捕获)。
标签: java json spring csv spring-mvc