Сообщение об исключении из-за отсутствия параметра метода @RequestBody
Во-первых, если у вас есть какие-либо идеи или решения, спасибо вам представить здесь. Я использую @RequestBody на одном из моих контроллеров для обязательного параметра, мне нужен какой-то полезный способ сказать, какой параметр отсутствовал, если его там нет. Когда пропущены некоторые параметры, генерируется исключение NullPointerException, поэтому я создаю новое исключение для экземпляра этого нулевого исключения (см. Http emun и httphandler). Это основные коды, относящиеся к этому вопросу.
мой контроллер:
public ResponseEntity<?> createOrder(@RequestBody Cart cart) throws Exception {
// ......
}
моя сущность корзина:
public class Cart{
private String channel
private String cartId;
private String status;
private String currency;
getters...
setters...
}
мой Http Emun класс:
public enum HttpStatusEnum {
CRE_CART_INCOMPLETE_BODY(400,"E001","Incomplete request body","");
private HttpStatusEnum(int statusCode, String code,
String message, String detail) {
this.statusCode = statusCode;
this.code = code;
this.message = message;
this.detail = detail;
}
private final int statusCode;
private final String code;
private final String message;
private String detail;
public int getStatusCode() {
return statusCode;
}
public String getCode() {
return code;
}
public String getMessage() {
return message;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getDetail() {
if(detail.isEmpty()) {
return message;
}else {
return detail;
}
}
}
У меня также есть один дескриптор исключения
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseEntity<Object> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
if(e instanceof NullPointerException)
{if(req.getRequestURL().toString().contains(HttpSourceEnum.CART.toString()) && req.getMethod().equals(RequestMethod.POST.toString())){
errorBodyVo.setMessage(HttpStatusEnum.CRE_CART_INCOMPLETE_BODY.getMessage());
errorBodyVo.setDetails(HttpStatusEnum.CRE_CART_INCOMPLETE_BODY.getDetail());
errorBodyVo.setCode(HttpStatusEnum.CRE_CART_INCOMPLETE_BODY.getCode());
}else {
errorBodyVo.setMessage(HttpStatusEnum.COMMON_MISSING_FIELD.getMessage());
errorBodyVo.setDetails(HttpStatusEnum.COMMON_MISSING_FIELD.getDetail());
errorBodyVo.setCode(HttpStatusEnum.COMMON_MISSING_FIELD.getCode());
}
httpStatus = HttpStatus.BAD_REQUEST;
}
}
сейчас мой запрос API:
{
"channel": "XX",
"cartId": "109",
"status": "1",
}
Я получаю ответ API, как показано ниже:
{
"error": {
"code": "E001",
"message": "Incomplete request body",
"details": ""
}
}
но это не соответствует моим ожиданиям. если канал отсутствует в моем запросе, как показано ниже:
{
"cartId": "109",
"status": "1",
}
Я ожидаю, что в подробностях появится сообщение "Требуется содержание тела запроса: канал":
{
"error": {
"code": "E001",
"message": "Incomplete request body",
"details": "Required request body content is missing: Channel"
}
}
Как я мог это сделать? Спасибо, парни!
1 ответ
Лучшим подходом, если вы можете сделать это, вероятно, будет использование JSR 303 Validation, которая, вероятно, включена в ваши существующие зависимости Spring, если вы используете последние версии.
Здесь есть хорошее, хотя и довольно простое учебное пособие: https://www.mkyong.com/spring-mvc/spring-rest-api-validation/ и многое другое в Интернете с более подробной информацией.
Официальные документы Spring по этому вопросу находятся здесь: https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
Вам нужно всего лишь внести изменения в несколько классов, и вы можете удалить большую часть обработки исключений, в зависимости от того, какой уровень контроля вы хотите получить, или от того, насколько вы готовы использовать стандартные настройки Spring. Основные изменения, которые вам нужно сделать, это:
Чтобы сообщить Spring, какая проверка требуется, вы добавляете одну или несколько аннотаций к Cart
class, например, если вы хотите убедиться, что канал указан, вы можете сделать что-то вроде:
public class Cart{
@NotNull
private String channel
private String cartId;
private String status;
private String currency;
Затем, чтобы проинструктировать Spring для проверки Cart
объект, прежде чем передать его в свой контроллер, вам нужно добавить @Valid
аннотация к вашей подписи метода контроллера:
public ResponseEntity<?> createOrder(@Valid @RequestBody Cart cart) throws Exception {
Наконец, измените createOrder
подпись еще раз, чтобы принять Errors
объект:
public ResponseEntity<?> createOrder(@Valid @RequestBody Cart cart, Errors errors) throws Exception {
в createOrder
Метод, который вы можете запросить Errors
возражать и отвечать соответственно. Это может означать отправку определенного ответа от контроллера или выдачу исключения для обработки вашим существующим механизмом обработки исключений.