HttpMediaTypeNotAcceptException with text/plain message responses?

2022-09-02 11:02:48

我有一个简单的Web服务,它将内容返回为或作为(取决于客户端的http标头)。jsonplain textaccept

问题:如果在请求期间发生错误,Spring会以某种方式返回.这有点错误,因为spring也可以将错误写成纯错误文本,而且绝对应该保留错误状态:text/plain406 Not Acceptable400

@RestController
public class TestServlet {
    @PostMapping(value = "/test", produces = {APPLICATION_JSON_VALUE, TEXT_PLAIN_VALUE, "text/csv"})
    public Object post() {
        throw new BadRequestException("bad req");
    }
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {
    public BadRequestException(String msg) {
        super(msg);
    }
}

带有 :accept=application/json

{
    "timestamp": "2018-07-30T14:26:02",
    "status": 400,
    "error": "Bad Request",
    "message": "bad req",
    "path": "/test"
}

但带有(或)显示带有状态的空响应。accept=text/csvtext/plain406 Not Acceptable

我还注意到被调用了两次:第一次是我的例外,第二次是.很明显,我的自定义异常的呈现失败了,但为什么呢?DispatcherServlet.processDispatchResult()BadRequestHttpMediaTypeNotAcceptableException


答案 1

问题是限制性的 Accept 标头只允许一种内容类型作为响应。如果出现错误,Spring MVC 需要使用已注册的 处理并生成所需的内容类型。BadRequestExceptionHttpMessageConverter

默认情况下,Spring Boot 没有直接从任何对象生成的消息转换器。你可以注册一个(因为bean应该为Spring Boot工作)来允许这样做,你会得到作为响应体的结果。text/plainObjectToStringHttpMessageConverterBadRequestException.toString()

我假设有类似的问题,但我不确定您的CSV消息转换设置是什么样的。text/csv


答案 2

“produces”中写入的条件确定用于响应的媒体类型为“text/csv”。因此,对于成功方案,它工作正常,**

但是当你去渲染一个带有JSON正文的异常时,这成为一个问题,并给你一个406。

**


推荐