SpringBoot はパラメーターの検証に @Validated を使用しなくなりましたが、コントローラー層を使用したくない場合はどうすればよいですか?

目次

シーン再現:

どうやってするの?

どうしたの?

それを達成するにはどうすればよいでしょうか?


シーン再現:

APIインターフェースは暗号化されたjson文字列を受け取ります。文字列を受け取った後、まず復号化処理が実行されます。復号化後、パラメータ検証処理が実行されます。パラメータが仕様を満たしていない場合は、プロンプトメッセージが直接返されます。

どうやってするの?

最初にコントローラー層で文字列を受け入れ、次にそれを復号化し、次にサービス層でパラメータを検証すれば、非常に満足できますが、ここで問題があります。つまり、復号化された JSON 文字列がオブジェクトになり、その後、ただし、フィールドが数十個あるため、通常の方法で確認すると、各パラメータに if 文が必要になり、大変なことになります。そこで、パラメーターの検証を支援するために Validated を使用することを検討します。

どうしたの?

問題は、通常、このように Validated パラメーターの検証をコントローラー層で直接使用していることです。

    @PostMapping("/resume-info")
    public ResponseResult<String>
    insertResumeInfo(@Validated(ValidatedGroup.Insert.class) @RequestBody ResumeMainInfoDTO dto) {
        return resumeInfoService.InsertInfo(dto);
    }
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResumeMainInfoDTO {

    @NotBlank(message = "!",groups = ValidatedGroup.Update.class)
    private Long id;

    /**
     * 姓名
     */
    @Length(max = 20,message ="!",groups = ValidatedGroup.Select.class)
    @NotBlank(message = "!",groups = ValidatedGroup.Insert.class)
    @NotBlank(message = "!",groups = ValidatedGroup.Update.class)
    private String userName;
}

サービスでも同じ方法を使用していますが、うまくいきません。では、サービス層はどうすればよいのでしょうか?

それを達成するにはどうすればよいでしょうか?

コントローラー層は文字列パラメーターを受け取り、それらをオブジェクトに変換します。



    @Autowired
    ss service;
    
@PostMapping("/getJson")
    public ResponseResult<String>  getJson(@RequestBody String dto) {
        RequestDTO requestDTO = JSON.parseObject(dto, RequestDTO.class);
        return service.startTask(requestDTO);
    }

 サービス層インターフェース

    public ResponseResult<String> startTask(@Valid @RequestBody RequestDTO dto);

インターフェースの実装

@Validated
在当前类的头上加上  

  @Override
    public ResponseResult<String> startTask(@Valid @RequestBody  RequestDTO dto) {
// 校验完成后的其他代码        
return start(dto);
    }

OK、上記はキーコードです。以下は重要ではありません

肝心な部分に注目

1 @Validated をサービス層クラスに追加します

2 検証するオブジェクトの前に @Valid @RequestBody を追加します (インターフェイスとインターフェイスの実装の両方が存在する必要があることに注意してください)

3 コントローラーで、注入メソッドを使用して次の呼び出しを行います。

4 dtoで判定チェックを定義する

-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------

dto コードの一部

    @Length(min = 1, max = 6, message = "申请类型不合法!提示:xx")
    String approve_type;
    // xx
    Integer port_type;

    @NotNull(message = "创建人id不能为空!")
//    @Range(min = 1,message = "创建人id不能为空!")
    Long create_user_id;
    @Length(max = 32, message = "创建人名称过长!")
    String create_user_name;

グローバル例外処理

// 1:使用PathVariable并且是get请求的参数错误。
    // 2:使用RequestParam并且是from-data方式提交的post请求的参数错误。
    @ExceptionHandler(value = ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleBindGetException(ConstraintViolationException e) {
        log.error("{}", e.getMessage(), e);
        List<String> defaultMsg = e.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        return Params_Common_Res(defaultMsg);
    }


    // 错误情况:
    //1 使用了ResponseBody并且是json数据类型的post请求
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("{}", e.getMessage(), e);
        List<String> defaultMsg = e.getBindingResult().getFieldErrors()
                .stream()
                .map(fieldError -> "【" + fieldError.getField() + "】" + fieldError.getDefaultMessage())
                .collect(Collectors.toList());
        return Params_Common_Res(defaultMsg);
    }

    /**
     * 兼容Validation校验框架:忽略参数异常处理器
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error("{}", e.getMessage(), e);
        log.error("ParameterName: {}", e.getParameterName());
        log.error("ParameterType: {}", e.getParameterType());
        return Params_Common_Res();
    }

    // 前端并没有提交必要的参数信息
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResult error(HttpMessageNotReadableException e){
        log.error("{}", e.getMessage(), e);
        return ErrorResult.build(new ErrorResult( false,ErrorEnum.Params_Lack_Err.getMessage(),ErrorEnum.Params_Lack_Err.getCode()), e.getMessage());
    }

効果:

 

おすすめ

転載: blog.csdn.net/qq_53679247/article/details/131280759