[英]Unable to use custom HttpMessageNotReadableException error message in Spring Boot
I'm currently trying to provide custom messages for exceptions, but ran into an issue with HttpMessageNotReadableException.我目前正在尝试为异常提供自定义消息,但遇到了 HttpMessageNotReadableException 的问题。
I have an ErrorDetails class:我有一个 ErrorDetails 类:
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
I also have a custom exception handler:我还有一个自定义异常处理程序:
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
@RestController
public class CustomizedExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
@Override
public final ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request){
ErrorDetails errorDetails = new ErrorDetails(new Date(), "hello",request.getDescription(true));
errorDetails.setMessage("Testing message");
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_ACCEPTABLE);
}
}
But when i try to post a bad request, for example, with a field that should have a integer value I pass a string in the JSON it still returns the default error message of:但是,当我尝试发布错误请求时,例如,使用应该具有整数值的字段时,我在 JSON 中传递了一个字符串,它仍然返回以下默认错误消息:
{
"timestamp": "2019-03-12T00:15:14.210+0000",
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Cannot deserialize value of type `int` from String \"lala\": not a valid Integer value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `int` from String \"lala\": not a valid Integer value\n at [Source: (PushbackInputStream); line: 5, column: 17] (through reference chain: com.tdl.model.ToDoNote[\"priority\"])",
"path": "/todos"
}
The JSON request: JSON 请求:
{
"name": "An workout",
"dateToComplete": "Today",
"description": "Sleep Day",
"priority": "lala",
"completed": false
}
The desired effect would just be the test message appearing instead of the long description.所需的效果只是出现测试消息而不是长描述。
I also get this in my Eclipse console:我也在我的 Eclipse 控制台中得到了这个:
WARN 16508 --- [nio-5000-exec-4] .wsmsDefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type
int
from String "lala": not a valid Integer value; WARN 16508 --- [nio-5000-exec-4] .wsmsDefaultHandlerExceptionResolver:已解决 [org.springframework.http.converter.HttpMessageNotReadableException:JSON 解析错误:无法从字符串“lala”反序列化int
类型的值:不是有效的整数值; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of typeint
from String "lala": not a valid Integer value at [Source: (PushbackInputStream);嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串“lala”反序列化int
类型的值:在 [Source: (PushbackInputStream); 处不是有效的整数值; line: 5, column: 17] (through reference chain: com.tdl.model.ToDoNote["priority"])] line: 5, column: 17] (通过引用链: com.tdl.model.ToDoNote["priority"])]
I changed the status to NOT_ACCEPTABLE just to see more clearly if my custom error is returned.我将状态更改为 NOT_ACCEPTABLE 只是为了更清楚地查看是否返回了我的自定义错误。
Any help would be appreciated.任何帮助,将不胜感激。 Thank you.谢谢你。
EDIT编辑
Added ExceptionHandler for InvalidFormatException, but nothing changed.为 InvalidFormatException 添加了 ExceptionHandler,但没有任何改变。 I still get the default error(exception) message same as before.我仍然收到与以前相同的默认错误(异常)消息。
@ExceptionHandler(InvalidFormatException.class)
public final ResponseEntity<Object> handleInvalidFormat(InvalidFormatException ex, HttpHeaders headers, HttpStatus status, WebRequest request){
ErrorDetails errorDetails = new ErrorDetails(new Date(), "hello",request.getDescription(true));
errorDetails.setMessage("Testing message");
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_ACCEPTABLE);
}
I ran into this error HttpMessageNotReadableException and I felt the need of customizing it.我遇到了这个错误 HttpMessageNotReadableException,我觉得需要自定义它。 After a few trials, I ended up with a better and more readable format.经过几次试验,我最终得到了一种更好、更易读的格式。 Step 1: Create a Custom Error Details class with the fields that you would want to expose to the client.第 1 步:创建一个自定义错误详细信息类,其中包含您希望向客户端公开的字段。 Below is what I created.下面是我创建的。
public class ErrorDetails {
private final Date timestamp;
private final String message;
private final String details;
public ErrorDetails(Date timestamp, String message, String details) {
this.timestamp = timestamp;
this.message = message;
this.details=details;
}
// getters not included for brevity // 为简洁起见,不包括 getter
Step 2: Create a class that will extend the ResponseEntityHandler which has the exceptions that can be overridden.第 2 步:创建一个将扩展 ResponseEntityHandler 的类,该类具有可以被覆盖的异常。 Here, override the handleHttpMessageNotReadbale method, and then in the method have an implementation of your own custom error handler.在这里,重写handleHttpMessageNotReadbale 方法,然后在该方法中实现您自己的自定义错误处理程序。
@ControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ControllerAdvice 公共类 GlobalExceptionHandler 扩展 ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(
HttpMessageNotReadableException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(),request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
} }
Step 3: Run your POST or PUT method with the wrong input fields and check the result.第 3 步:使用错误的输入字段运行 POST 或 PUT 方法并检查结果。 For instance, gender is an enum class with only FEMALE and MALE.例如,gender 是一个只有 FEMALE 和 MALE 的枚举类。
{
"firstName":"Dell",
"lastName":"HP",
"birthYear":"2000-02-12",
"email":"dell@gmail.com",
"gender":"BOY"
} }
The response is like below:响应如下:
{ "timestamp": "2022-06-06T08:08:53.906+00:00", "message": "JSON parse error: Cannot deserialize value of type com.io.clinic.utils.Gender
from String "BOY": not one of the values accepted for Enum class: [FEMALE, MALE]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.io.clinic.utils.Gender
from String "BOY": not one of the values accepted for Enum class: [FEMALE, MALE]\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 6, column: 14] (through reference chain: com.io.clinic.payloadDTO.PatientDTO["gender"])", "details": "uri=/api/v1/patients" } I was satisfied with having the message in that state for debugging but you can also customize the message response in the overridden method. { "timestamp": "2022-06-06T08:08:53.906+00:00", "message": "JSON 解析错误:无法从字符串 "BOY" 反序列化com.io.clinic.utils.Gender
类型的值:不是枚举类接受的值之一:[FEMALE,MALE];嵌套异常是 com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串“BOY”反序列化com.io.clinic.utils.Gender
类型的值:不是枚举类接受的值之一:[FEMALE,MALE]\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 6, column: 14] (通过参考链:com.io .clinic.payloadDTO.PatientDTO["gender"])", "details": "uri=/api/v1/patients" } 我很满意让消息处于该状态以进行调试,但您也可以自定义消息响应被覆盖的方法。
The problem is solved.问题已经解决了。 I had my custom exception classes in a badly named package.我将自定义异常类放在一个命名错误的包中。 It was called just exception.它被称为只是例外。 While it should have been com.app.exception where the whole project is.虽然它应该是整个项目所在的 com.app.exception。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.