没有ControllerAdvice调用HttpMessageConverter的响应主体

时间:2015-01-30 14:26:54

标签: java spring spring-mvc spring-4

编辑:错误发生在客户端而不是服务器上。响应机构正在编写,但客户端没有在400响应中阅读它。

我有一个自定义消息转换器,可以从text/csv对象生成application/csvErrorResponse。当ErrorResponse直接从@RequestMapping带注释的方法返回时,它可以正常工作,但是当ErrorResponse@ExceptionHandler带注释的方法返回@ControllerAdvice时,它不返回任何响应体1}}对象。我已经验证了正在调用消息转换器writerInternal方法并且正在写入响应正文,但是它永远不会回到客户端。

错误响应:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="response")
public class ErrorResponse {
    private String statusCode;
    private String userMessage;
    private String developerMessage;

    public String getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(final String statusCode) {
        this.statusCode = statusCode;
    }

    public String getUserMessage() {
        return userMessage;
    }

    public void setUserMessage(final String userMessage) {
        this.userMessage = userMessage;
    }

    public String getDeveloperMessage() {
        return developerMessage;
    }

    public void setDeveloperMessage(final String developerMessage) {
        this.developerMessage = developerMessage;
    }

    public ErrorResponse() {
        super();
    }

    public ErrorResponse(final String statusCode, final String userMessage, final String developerMessage) {
        super();
        this.statusCode = statusCode;
        this.userMessage = userMessage;
        this.developerMessage = developerMessage;
    }

}

的MessageConverter:

public class ErrorResponseCsvMessageConverter extends AbstractHttpMessageConverter<ErrorResponse> {

    public ErrorResponseCsvMessageConverter() {
        super(new MediaType("application", "csv", Charset.forName("UTF-8")),
                new MediaType("text", "csv", Charset.forName("UTF-8")),
                MediaType.TEXT_PLAIN);
    }

    @Override
    protected ErrorResponse readInternal(final Class<? extends ErrorResponse> clazz, final HttpInputMessage httpInputMessage)
            throws IOException, HttpMessageNotReadableException {

        // not supported

        return null;
    }

    @Override
    protected boolean supports(final Class<?> clazz) {
        return ErrorResponse.class.isAssignableFrom(clazz);
    }

    @Override
    protected void writeInternal(final ErrorResponse errorResponse, final HttpOutputMessage httpOutputMessage)
            throws IOException, HttpMessageNotWritableException {

        System.out.println(errorResponse);

        try(CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(httpOutputMessage.getBody(), "UTF-8"))) {
            csvWriter.writeNext(new String[] { "statusCode", "userMessage", "developerMessage" });
            csvWriter.writeNext(new String[] {
                    errorResponse.getStatusCode(),
                    errorResponse.getUserMessage(),
                    errorResponse.getDeveloperMessage() });
        }
    }

}

控制器建议:

...
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody()
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ErrorResponse handleMissingParamterException(final HttpServletRequest request, final HttpServletResponse httpServletResponse, final MissingServletRequestParameterException e) {
        LOG.warn("Bad Request:" +
                request.getRequestURI() +
                ((request.getQueryString()==null) ? "" : "?" + request.getQueryString()));

        return new ErrorResponse(
                "400",
                "There was an error with the request.",
                "Required parameter '" + e.getParameterName() + "' is missing.");
    }
...

1 个答案:

答案 0 :(得分:1)

我认为邮件正在写入但没有刷新...

所以你的转换器可能缺少类似的东西:

outputMessage.getBody().flush();

甚至可以使用Spring AbstractHttpMessageConverter