前言
在項目中,前端要對特殊字段做正則驗證,後端也要對特殊的字段做正則驗證和非空判斷,在做正則的時候遇到了很多坑,今天就和大家分享。主要有以下幾種方式:
環境
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());