一止长渊

后端数据校验

N 人看过
字数:838字 | 预计阅读时长:3分钟

JSR303(java 规范提案:303 提案),是关于数据校验的规范。在前端发送的数据在前端经过校验后,发送给后台还需要经过校验后才能入库,这是因为如果有人知道你的接口就可以通过 PostMan 工具向你的接口恶意发送坏数据入库,给其他用户浏览页面就会造成不好的影响,为此需要使用后端数据校验。前台防君子后台防小人

JSR 主要使用 javax.validation.constraints 定义的注解此外也可以采用 hibernate 提供的一些注解或者自定义规则注解@Pattern

  • 1)、给 Bean 需要校验字段添加校验注解 可以在 javax.validation.constraints,并定义 message 错误提示
  • 2)、在 Controller 方法体中对相应的 Bean 添加上**@Valid**,否则光在字段标注了注解是没有用的:public R save(@Valid @RequestBody BrandEntity brand)
  • 效果:校验错误以后会有默认的响应,并显示错误信息 message
  • 3)、在方法体校验参数后面紧跟 BindingResult,就可以获取到校验的结果

对应 Bean 上需要校验字段添加注解,这里使用了@URL(hibernate 提供的)、@Pattern(自定义规则注解)以及 javax.validation.constraints 包下定义的注解,
并在 message 中显示了校验错误的原因,不定义 message 则会默认使用 ValidationMessage_zh_CN.properties 中默认的错误信息
此外需要注意:@NotEmpty、@NotBlank、@NotNull 之外的其他注解,如果用户不在 JSON 中添加这些字段则不会经过校验,如果需要不为空且满足某种规则,则还需要添加上@NotEmpty、@NotBlank、@NotNull 之一的注解表示不得为空

package com.lookstarry.doermail.product.entity;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;
import java.util.Date;

import lombok.Data;
import org.hibernate.validator.constraints.URL;

import javax.validation.constraints.*;

/**
 * 品牌
 *
 * @author yizhichangyuan
 * @email 695999620@qq.com
 * @date 2021-03-13 00:04:05
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 品牌id
     */
    @TableId
    private Long brandId;
    /**
     * 品牌名
     */
    @NotBlank(message = "品牌名必须不为空")
    private String name;
    /**
     * 品牌logo地址
     */
    @NotEmpty
    @URL(message="logo必须是一个合法的url地址") // @URL利用了hibernate提供的,只能在用户发送了该字段才校验无法校验不提交的情况,为此添加上了@NotEmpty
    private String logo;
    /**
     * 介绍
     */
    private String descript;
    /**
     * 显示状态[0-不显示;1-显示]
     */
    private Integer showStatus;
    /**
     * 检索首字母
     */
    @NotEmpty
    @Pattern(regexp="/^[a-zA-Z]$/", message = "检索首字符必须是一个字母") //同@URL
    private String firstLetter;
    /**
     * 排序
     */
    @NotNull
    @Min(value=0, message="排序必须大于等于0")
    private Integer sort;
}

Controller 层,在需要校验的 Bean 要添加上@Valid 字段,表示需要校验,在其后添加上 BindResult 可以获取校验结果,如果校验成功则入库,不成功则通过 BindResult 将相应的原因提取返回给用户

    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Valid @RequestBody BrandEntity brand, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            Map<String, String> map = new HashMap<>();
            // 1、获取校验的错误结果
            bindingResult.getFieldErrors().forEach(item ->{
                // 获取到错误提示
                String errorMessage = item.getDefaultMessage();
                // 获取错误的属性名
                String field = item.getField();
                map.put(field, errorMessage);
            });
            return R.error(400, "请求的数据不合法").put("data", map);
        }else{
            brandService.save(brand);
        }
        return R.ok();
    }

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。