1. hibernate validator註解在web項目中經常用到,是一個很好用的字段校驗器,可以對前端傳入的參數進行判斷,如是否爲空,是否滿足正則規定的格式等等。
2. 假設有一個業務場景,需要判斷前端傳入的用戶是否存在,而項目中有很多地方會用到此判斷,此時可以構造一個自定義校驗器進行字段校驗,在需要的時候只需要加上此註解即可。
3. controller接口
package net.mshome.twisted.tmall.common.controller;
import net.mshome.twisted.tmall.common.dto.UserAddDTO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
* <p>
* 前端控制器
* </p>
*
* @author tangjizhou
* @since 2019-05-04
*/
@RestController
@RequestMapping("/user")
@Validated
public class UserController {
@PostMapping("/register")
public void register(@RequestBody @Valid UserAddDTO userAddDTO) {
}
}
4. 前端傳入的參數,注意此處的自定義註解 @UserField
package net.mshome.twisted.tmall.common.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.mshome.twisted.tmall.common.annotation.UserField;
import javax.validation.constraints.NotNull;
/**
* @author tangjizhou
* @date 2019-06-20
* @description 前端post傳入參數
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserAddDTO {
/**
* 假設此處可填寫多個用戶,以逗號隔開
*/
@UserField(message = "填寫的用戶{}不存在")
@NotNull(message = "請填寫用戶")
private String usernames;
}
5. 自定義註解
package net.mshome.twisted.tmall.common.annotation;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
/**
* @author tangjizhou
* @date 2019-06-20
* @description 驗證用戶是否存在註解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Constraint(validatedBy = UserFieldValidator.class)
public @interface UserField {
String message() default "";
String defaultMessage = "用戶{}不存在";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
6. 實現註解功能
package net.mshome.twisted.tmall.common.annotation;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import net.mshome.twisted.tmall.common.entity.User;
import net.mshome.twisted.tmall.common.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* @author tangjizhou
* @date 2019-06-20
* @description 驗證用戶是否存在
*/
@Component
public class UserFieldValidator implements ConstraintValidator<UserField, String> {
private String defaultMessage;
@Autowired
private IUserService userService;
@Override
public void initialize(UserField constraint) {
this.defaultMessage = constraint.defaultMessage;
}
@Override
public boolean isValid(String usernames, ConstraintValidatorContext context) {
// 如果什麼都沒有輸入,則不判斷,直接返回
if (StringUtils.isEmpty(usernames)) {
return true;
}
// 判斷用戶是否存在
String illegalUsernames = Arrays.stream(usernames.split(",")).distinct().map(username -> {
User user = userService.getOne(new QueryWrapper<>(User.builder().username(username).build()));
return user == null ? username : null;
}).filter(StringUtils::isNotEmpty).collect(Collectors.joining(","));
// 所有用戶都存在,返回true
if (StringUtils.isBlank(illegalUsernames)) {
return true;
}
/* ************************ 如果存在非法用戶****************************/
// 禁用直接返回默認的message
context.disableDefaultConstraintViolation();
// 獲取註解配置的message
String messageTemplate = context.getDefaultConstraintMessageTemplate();
messageTemplate = StringUtils.isEmpty(messageTemplate) ? defaultMessage : messageTemplate;
// 構造返回信息,進行佔位符替換
context.buildConstraintViolationWithTemplate(StringUtils.replace(messageTemplate, "{}", illegalUsernames))
.addConstraintViolation();
return false;
}
}