java 注解校验 import javax.validation.constraints 实体类属性注解校验 并自定义异常对前端返回的参数格式错误消息封装

Java在做接收参数使用javax.validation注解时,有时候不能返回给前端理想的提示信息(要在项目中添加jar包 这里我就不做说明)


    javax.validation
    validation-api
    2.0.1.Final
    true

示例:

请求一个新增接口

1.接口

/**
     * 运营管理-产品管理-产品列表-添加产品
     */
    @PostMapping("/product/save")
    public ResponseDTO saveProduct(@Valid @RequestBody RequestDTO request, HttpServletRequest httpServletRequest) {
        ProductBO param = request.getParam();
        if (param == null) {
            return RestResponseUtil.response(HttpStatus.BAD_REQUEST, this.messageService
                    .getMessage("request.parameter.invalid"), false);
        }
        AdminDO adminDO = adminService.getAdminByPartnerIdAndToken(request.getPartnerId(), TokenUtil.getAuthorizationHeader(httpServletRequest));
        param.setAdminId(adminDO.getId());
        param.setPartnerId(request.getPartnerId());
        return RestResponseUtil.ok(messageService.getMessage("request.success"), productService.saveProduct(param));
    }

需要注意一个问题,如图:

java 注解校验 import javax.validation.constraints 实体类属性注解校验 并自定义异常对前端返回的参数格式错误消息封装_第1张图片

2.所接收参数并使用了的类,如下代码:

package com.rocky.fintech.boss.entity.product;

import com.rocky.fintech.boss.entity.BaseEntity;
import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author 9043
 * @date 2019/11/7
 */
@Getter
@Setter
public class ProductBO extends BaseEntity {
    private Long id;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("1")
    private BigDecimal feeRate;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("1")
    private BigDecimal dayInterest;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("1")
    private BigDecimal overdueInterest;
    @NotNull
    @Min(0)
    private Integer overdueMaxDays;
    @NotBlank
    private String appPackage;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("99999999")
    private BigDecimal productAmountMin;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("99999999")
    private BigDecimal productAmountMax;
    @NotNull
    @DecimalMin("0")
    private BigDecimal productAmountPer;
    @NotNull
    @Min(0)
    private Integer productPeriodMin;
    @NotNull
    @Min(0)
    private Integer productPeriodMax;
    @NotNull
    @Min(0)
    private Integer productPeriodPer;
    @NotNull
    @DecimalMin("0")
    @DecimalMax("1")
    private BigDecimal overdueMaxRate;
    private Long adminId;
    private Long partnerId;
    @NotBlank
    private String currency;
    @Size(max = 100)
    @NotBlank
    private String slogan;
    @NotNull
    private List productUserLevels;
}

 

如下数据很乱(往后看,有处理方式):

java 注解校验 import javax.validation.constraints 实体类属性注解校验 并自定义异常对前端返回的参数格式错误消息封装_第2张图片

java 注解校验 import javax.validation.constraints 实体类属性注解校验 并自定义异常对前端返回的参数格式错误消息封装_第3张图片

 

解决及处理方式如下(也就是做了个全局异常):

1.新增:

2.继承

3.所继承具体实现代码:

package com.rocky.fintech.skeleton.exception;

import com.rocky.fintech.entity.ResponseDTO;
import com.rocky.fintech.exception.BusinessException;
import com.rocky.fintech.skeleton.service.MessageSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.rocky.fintech.skeleton.util.RestResponseUtil.error;
import static com.rocky.fintech.skeleton.util.RestResponseUtil.response;
import static org.springframework.http.HttpStatus.BAD_REQUEST;

@Slf4j
@RestControllerAdvice
public class SkeletonExceptionHandler {
    @Autowired
    protected MessageSourceService messageService;

    @ExceptionHandler(RuntimeException.class)
    public ResponseDTO handleRuntimeException(RuntimeException e) {
        log.error("handle runtime exception: {}", e.getMessage());
        return error(this.messageService.getMessage("service.unavailable"), "");
    }

    @ExceptionHandler(HttpMessageConversionException.class)
    public ResponseDTO handleHttpMessageConversionException(HttpMessageConversionException e) {
        log.error("handle http message conversion exception: {}", e.getMessage());
        return response(BAD_REQUEST, this.messageService.getMessage("request.parameter.invalid"), "");
    }

    @ExceptionHandler(BusinessException.class)
    public ResponseDTO handleBusinessException(BusinessException e) {
        HttpStatus status = HttpStatus.resolve(e.getStatus());
        String localeMessage = this.messageService.getMessage(e.getCode(), e.getArgs());
        log.warn("handle business exception: {}", e.getMessage());
        return response(status, localeMessage, e.getMessage());
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseDTO> handleConstraintViolationException(ConstraintViolationException e)  {
        Set> violations = e.getConstraintViolations();
        Map map = new HashMap<>(violations.size());
        violations.forEach(violation->violation.getPropertyPath()
                .forEach(node -> map.put(node.getName(), violation.getMessage())));
        log.error("handle constraint violation exception: {}", map);
        return response(BAD_REQUEST, this.messageService.getMessage("request.parameter.invalid"), map);
    }

    @ExceptionHandler(BindException.class)
    public ResponseDTO> handleBindException(BindException e)  {
        return this.wrapErrors(e.getBindingResult().getAllErrors());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseDTO> handleMethodArgumentNotValid(MethodArgumentNotValidException e)  {
        return this.wrapErrors(e.getBindingResult().getAllErrors());
    }

    private ResponseDTO> wrapErrors(List errors) {
        SecureRandom random = new SecureRandom();
        Map map = new HashMap<>(errors.size());
        errors.forEach(error->{
            if(error instanceof FieldError) {
                FieldError fieldError = (FieldError)error;
                map.put(fieldError.getField(), error.getDefaultMessage());
            } else {
                map.put(error.getObjectName()+random.nextInt(), error.getDefaultMessage());
            }
        });
        log.error("handle argument valid exception: {}", map);
        return response(BAD_REQUEST, this.messageService.getMessage("request.parameter.invalid"), map);
    }
}

 

此时:请求查看code:400 结果 就会是一个适合前端展示给用户能理解的信息

java 注解校验 import javax.validation.constraints 实体类属性注解校验 并自定义异常对前端返回的参数格式错误消息封装_第4张图片

仅供参考,自学。

你可能感兴趣的:(Java后端代码)