我有一个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()
方法,捕获错误并生成包含ResponseEntity
等错误属性的timestamp, exception, path, etc
。
问题:现在返回Object
类型ResponseEntity
。只要format参数是?format=json/xml
,这就没问题。然后可以正确转换响应。
但在我的特殊情况下,我请求?format=csv
,会话将失败,导致:
无法创建响应: org.springframework.web.HttpMediaTypeNotAcceptableException:不能 找到可接受的代表
这部分属实,而且具有误导性,因为用户应直接看到身份验证凭据无效。因为我一般都接受csv
,但Spring和mappers不知道如何将ResponseEntity
转换为像csv这样的普通格式。
问题:如何保留原始异常?这样我就可以返回纯文本错误消息。如果我能在这种情况下返回application/json
响应,那也没关系!
答案 0 :(得分:0)
目前解决方法如下:覆盖/error
servlet处理程序,如果?format
参数不是json/xml
,则只返回原始的http状态错误,而不是正文。< / p>
因此,当将正文转换为纯格式并正确返回响应时,spring不会失败(但在正文中没有异常细节)。
@Controller
public class WorkaroundBasicErrorController extends BasicErrorController {
//default constructor from ErrorMvcAutoConfiguration
public DefaultBasicErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,
ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
super(errorAttributes, serverProperties.getError(), errorViewResolversProvider.getIfAvailable());
}
@RequestMapping
@ResponseBody
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
String format = request.getParameter("format");
return (StringUtils.containsAny(format, "json", "xml"))
? super.error(request)
: new ResponseEntity<>(getStatus(request)); //neglect body for plain formats
}
}
答案 1 :(得分:-1)
尝试使用void @ExceptionHandler
,并直接在HttpResponse