如何为内容类型text / csv返回正确的错误响应?

时间:2017-11-16 15:59:56

标签: java json spring csv spring-mvc

我有一个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响应,那也没关系!

2 个答案:

答案 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

中写入错误消息