缺少@RequestBody方法参数的异常消息

时间:2017-09-07 06:34:09

标签: json spring-mvc exception-handling nullpointerexception httpexception

首先,如果您有任何想法或解决方案,谢谢您在这里介绍。 我在我的一个控制器上使用@RequestBody获取所需的参数,我需要一些有用的方法来说明如果它不存在则缺少哪个参数。 当缺少某些参数时,它会抛出NullPointerException,所以我为这个null异常的实例创建了一个新的异常(请参阅httpemun和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",
}

我希望显示&#34;所需的请求正文内容丢失:频道&#34;在细节中:

{
    "error": {
        "code": "E001",
        "message": "Incomplete request body",
        "details": "Required request body content is missing: Channel"
    }
}

我怎么能这样做?谢谢你们!

1 个答案:

答案 0 :(得分:2)

如果你能做到这一点,更好的方法可能就是使用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/#validation-beanvalidation

您应该只需要对几个类进行更改,并且可能会删除大量的异常处理,具体取决于您需要多少控制,或者您愿意使用Spring&#39;默认值。您需要做的基本更改是:

要告诉Spring需要进行哪些验证,可以向Cart类添加一个或多个注释,例如,如果要确保指定通道,则可以执行以下操作:

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对象并做出相应的响应。这可能意味着从控制器发送特定响应或抛出异常以由现有异常处理机制处理。