编辑:错误发生在客户端而不是服务器上。响应机构正在编写,但客户端没有在400响应中阅读它。
我有一个自定义消息转换器,可以从text/csv
对象生成application/csv
,ErrorResponse
。当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.");
}
...
答案 0 :(得分:1)
我认为邮件正在写入但没有刷新...
所以你的转换器可能缺少类似的东西:
outputMessage.getBody().flush();
甚至可以使用Spring AbstractHttpMessageConverter?