java后端做正则验证

本文分享了在SpringBoot项目中,后端如何进行正则验证和非空判断的经验,涉及结合注解进行正则校验的方法,以及正则验证手机号的技巧,主要应用于数据新增和修改场景。

前言

在项目中,前端要对特殊字段做正则验证,后端也要对特殊的字段做正则验证和非空判断,在做正则的时候遇到了很多坑,今天就和大家分享。主要有以下几种方式:

环境

springboot1.5.x
jpa
java8

1.结合注解来正则来校验

正则表达式

package com.test.util;

/**
 * 描述:正则表达式格式
 */
public class RegexpProperties {
    public static final String MOBILE_PATTERN = "^$|0?(13|14|15|18|17)[0-9]{9}$";//手机号
    public static final String EMAIL_PATTERN = "^$|(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$";//邮箱
    public static final String FAX_PATTERN = "^$|(\\d{3,4}-)?\\d{7,8}$";//传值
    public static final String CREDIT_CODE_PATTERN = "^$|[a-zA-Z0-9]{18}$";//社会信用代码
}

实体类

package com.test.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;

@Table(name = "company")
@Entity
@Getter
@Setter
@DynamicInsert//新增时空字段不去插入values
@DynamicUpdate//只跟新变化的字段,结合merge方法使用
@JsonInclude(JsonInclude.Include.NON_NULL)
@EntityListeners({AuditingEntityListener.class})
@JsonIgnoreProperties({"createDate", "modifyDate"})
public class Company implements BaseEntity{
    //BaseEntity 是实现序列化的,这个类我就不放进来了

    @Id
    @GeneratedValue
    private Integer id;
    @NotBlank(message = "企业名称不能为空")
    private String name;
    @NotBlank(message = "社会信用代码不能为空")
    @Pattern(regexp = RegexpProperties.CREDIT_CODE_PATTERN, message = "社会信用代码格式有误")
    private String creditCode;
    private String contactName;
    @Pattern(regexp = RegexpProperties.MOBILE_PATTERN, message = "电话格式有误")
    private String contactPhone;
    @Length(min = 0, max = 50, message = "企业法人长度不得超过50个字符")
    private String corporation;
    @Pattern(regexp = RegexpProperties.EMAIL_PATTERN, message = "邮箱格式有误")
    private String email;
    @Pattern(regexp = RegexpProperties.FAX_PATTERN, message = "传真格式有误")
    private String fax;
    private String address;
    @Min(value = 0, message = "占地面积不能小于0")
    private Double floorArea;
    private Integer attentionLevel;
    private Integer industryId;
    private String industryName;
    private Timestamp establishedDate;
    @Min(value = 0, message = "请输入正确的员工人数")
    private Integer staffNum;
    private Boolean isDeleted = false;
    
    @CreatedDate
    private Date createDate;
    @LastModifiedBy
    private Integer modifier;
    @LastModifiedDate
    private Date modifyDate;
}

该方法在新增或者修改的时使用, 在controller层中,
在@RequestBody 前面加上@Validated 这种方能起作用.

1.2正则验证手机号的另外一种方式

package com.test.util;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;

/**
 * 请求参数验证器
 */
@Getter
public class Validator {
    public static final int SUCCESS = 0;
    public static final int ARGUMENT_NULL = 101;
    public static final int ARGUMENT_ERROR = 102;
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$");
    private static final Pattern MOBILE_PATTERN = Pattern.compile("1\\d{10}");
    public static final Pattern FAX_PATTERN = Pattern.compile("^(\\d{3,4}-)?\\d{7,8}$");
    private static final Pattern TEL_PATTERN = Pattern.compile("^((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?$");
    private static final Pattern SPACE_PATTERN = Pattern.compile("\\s*|\t|\r|\n", Pattern.CASE_INSENSITIVE);
    private static final Pattern DATE_PATTERN =
            Pattern.compile("^\\d{4}[./-]\\d{1,2}[./-]\\d{1,2}[\\d\\.\\:\\+ZT ]+$", Pattern.CASE_INSENSITIVE);
    private static final Pattern EMOJI_PATTERN =
            Pattern.compile("[\\uD800-\\uDBFF\\uDC00-\\uDFFF\\u2600-\\u27ff]",
                    Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
    private static final Pattern IP_PATTERN =
            Pattern.compile("\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                    + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                    + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                    + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b");
    private static final Pattern ID_CARD_NO_PATTERN =
            Pattern.compile("^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$");
    private final List<Valid> expressions = new ArrayList<>();
    private int code;
    private String message;

    public static Validator create() {
        return new Validator();
    }

    public static Validator create(String appId) {
        return Validator.create().appId(appId);
    }

    public static boolean isNullOrEmpty(String string) {
        return string == null || string.length() == 0;
    }

    public static boolean isPhone(String phone) {
        return !isNullOrEmpty(phone) && (TEL_PATTERN.matcher(phone).matches() || isMobile(phone));
    }

    public static boolean isMobile(String mobile) {
        return hasMobile(mobile) && mobile.length() == 11;
    }

    public static boolean hasMobile(String content) {
        return !isNullOrEmpty(content) && MOBILE_PATTERN.matcher(content).find();
    }

    public static boolean hasFax(String content) {
        return !isNullOrEmpty(content) && FAX_PATTERN.matcher(content).find();
    }

    public static boolean isFax(String fax) {
        return hasFax(fax) && fax.length() >= 7;
    }

    public static boolean isEmail(String email) {
        return hasEmail(email) && email.length() > 4;
    }

    public static boolean hasEmail(String content) {
        return !isNullOrEmpty(content) && EMAIL_PATTERN.matcher(content).find();
    }

    public static boolean isIp(String ip) {
        return !isNullOrEmpty(ip) && IP_PATTERN.matcher(ip).matches();
    }

    public static boolean hasEmoji(String text) {
        return !isNullOrEmpty(text) && EMOJI_PATTERN.matcher(text).matches();
    }

    /**
     * 是否身份证号
     */
    public static boolean isIdCardNO(String text) {
        return !isNullOrEmpty(text)
                && text.length() >= 15
                && ID_CARD_NO_PATTERN.matcher(text).matches();
    }
    
    public boolean valid() {
        for (Valid valid : expressions) {
            if (!valid.getExpression().get()) {
                this.code = valid.getCode();
                this.message = valid.getAlter();
                return false;
            }
        }
        return true;
    }

    public <T> T convert(Function<Validator, T> function) {
        return function.apply(this);
    }

    public Validator valid(int code, String alter, Supplier<Boolean> expression) {
        Valid valid = new Valid(code, alter, expression);
        this.expressions.add(valid);
        return this;
    }

    public Validator validNull(String name, Supplier<Boolean> valid) {
        String alert = "缺少必要的请求参数:" + name;
        return valid(ARGUMENT_NULL, alert, valid);
    }

    public Validator validError(String name, Supplier<Boolean> valid) {
        String alert = "请求参数格式错误:" + name;
        return valid(ARGUMENT_ERROR, alert, valid);
    }

    public Validator appId(String appId) {
        return valid(ARGUMENT_NULL, "缺少参数 _appId", () -> !isNullOrEmpty(appId));
    }

    public Validator notNull(String name, Object value) {
        return validNull(name, () -> value != null);
    }

    public Validator notEmpty(String name, String value) {
        return validNull(name, () -> !isNullOrEmpty(value));
    }

    public Validator notEmpty(String name, Collection value) {
        return validNull(name, () -> value != null && value.size() > 0);
    }

    public Validator greaterThanZero(String name, Number value) {
        return greaterThan(name, value, 0);
    }

    public Validator greaterThan(String name, Number value, Number min) {
        String alert = String.format("%s 值必须大于 %s", name, min);
        return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() > min.doubleValue());
    }

    public Validator greaterThanOrEqual(String name, Number value, Number min) {
        String alert = String.format("%s 值必须大于等于 %s", name, min);
        return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() >= min.doubleValue());
    }

    public Validator lessThan(String name, Number value, Number max) {
        String alert = String.format("%s值必须小于 %s", name, max);
        return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() < max.doubleValue());
    }

    public Validator lessThanOrEqual(String name, Number value, Number max) {
        String alert = String.format("%s 值必须小于等于 %s", name, max);
        return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() <= max.doubleValue());
    }

    public Validator range(String name, Number value, Number min, Number max) {
        String alert = String.format("%s值必须在 [%s~%s] 之间", name, min, max);
        return valid(ARGUMENT_ERROR, alert, () -> value.doubleValue() >= min.doubleValue()
                && value.doubleValue() <= max.doubleValue());
    }

    public Validator regexMatches(String name, String value, String pattern) {
        String alert = String.format("%s必须满足格式:%s", name, pattern);
        return valid(ARGUMENT_ERROR, alert, () -> Pattern.matches(pattern, value));
    }

    public Validator phone(String phone) {
        String alert = String.format("电话号码格式不正确,tel:[%s]", phone);
        return valid(ARGUMENT_ERROR, alert, () -> isPhone(phone));
    }

    public Validator mobile(String mobile) {
        String alert = String.format("手机号码格式不正确,mobile:[%s]", mobile);
        return valid(ARGUMENT_ERROR, alert, () -> isMobile(mobile));
    }

    public Validator email(String email) {
        String alert = String.format("邮箱格式不正确,email:[%s]", email);
        return valid(ARGUMENT_ERROR, alert, () -> isEmail(email));
    }

    public Validator idCardNo(String idCardNo) {
        String alert = String.format("身份证号格式不正确,number:[%s]", idCardNo);
        return valid(ARGUMENT_ERROR, alert, () -> isIdCardNO(idCardNo));
    }

    public Validator ip(String ip) {
        String alert = "ip地址格式不正确";
        return valid(ARGUMENT_ERROR, alert, () -> isIp(ip));
    }

    @Getter
    @Setter
    @NoArgsConstructor
    @AllArgsConstructor
    private class Valid {
        private int code;
        private String alter;
        private Supplier<Boolean> expression;
    }
}
 /**
     * 验证手机号
     *
     * @param str 手机号
     * @return
     */
    public static boolean isMobile(String str) {
        boolean b = false;
        String s2 = "^$|0?(13|14|15|18|17)[0-9]{9}$";// 验证手机号
        if (Helpers.isNotNullAndEmpty(str)) {
            Pattern p = Pattern.compile(s2);
            Matcher m = p.matcher(str);
            b = m.matches();
        }
        return b;
    }

/**
     * 验证不为空
     *
     *
     */
  Validator validator = Validator.create()
                    .notEmpty("用户名", user.getUserName())
                    .notEmpty("密码", user.getPassword())
                    .notEmpty("验证码", user.getCode())
                    .mobile(user.getMobile());


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值