检查@PathVariable Data Binder结果是否为空并抛出404

时间:2019-01-30 09:45:49

标签: spring spring-boot spring-mvc spring-data-jpa spring-data

在我的spring boot应用程序中,我有一个spring mvc方法,该方法通过spring安全性进行保护 我将id传递给此方法,作为路径变量和spring数据参数解析器查找并绑定实体 但是当id无效时实体为null;我想在实体为null时抛出404;因为Spring安全性PreAuthorize需要一个非null的实体来检查用户授权; 我的代码是:

 @PutMapping(value = "/{address}")
    @PreAuthorize("isAuthenticated() and (#address.user.id == #user.id)")
    public ResponseEntity<ResponseModel> update(@Valid @RequestBody AddressModel addressModel, @PathVariable Address address, @AuthenticationPrincipal User user) {

        try {
            addressService.update(user, address, addressModel);
        } catch (Exception e) {
            return new ResponseEntity<>(new ResponseModel(e.getMessage(), ResponseModel.ResponseStatus.ERROR), HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(new ResponseModel(messages.get("def.op.success"), ResponseModel.ResponseStatus.SUCCESS), HttpStatus.OK);
    }

我也测试过

@PreAuthorize("isAuthenticated() and (#address != null and #address.user.id == #user.id)")

但它返回403错误;

1 个答案:

答案 0 :(得分:1)

您不能简单地将注释移至您的服务吗?

 @PutMapping(value = "/{address}")
    //@PreAuthorize("isAuthenticated() and 
          //(#address.user.id == #user.id)") <-- move to service method
    public ResponseEntity<ResponseModel> update(
             @Valid @RequestBody AddressModel addressModel, @PathVariable Address address, 
                        @AuthenticationPrincipal User user) {

        if(address == null){
           //throw some exception that gets translated to 404
        }

        try {
            //check will be applied on call to service
            addressService.update(user, address, addressModel);
        } catch (Exception e) {
            return new ResponseEntity<>(new ResponseModel(e.getMessage(), 
                     ResponseModel.ResponseStatus.ERROR), HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(new ResponseModel(messages.get("def.op.success"), 
                 ResponseModel.ResponseStatus.SUCCESS), HttpStatus.OK);
    }