首页 > 解决方案 > 如何使用自定义验证器验证列表中的每个条目

问题描述

我有一个 Springboot Rest 应用程序,其中一个模型有一个服务器自定义验证器。有 2 个 api 端点,一个接收单个对象,另一个接收相同对象的列表。我的自定义验证器在第一个端点上运行良好。我如何为其他端点使用相同的验证器。

模型类

@Entity
@Table(name=TABLE_MESSAGE, schema = SCHEMA)
public class Message implements java.io.Serializable {

    @Id @GeneratedValue(strategy=IDENTITY)
    @Column(name=COLUMN_ID, unique=true)
    private Long id;

    @Basic(optional = false)
    @Column(name = COLUMN_CREATETIMESTAMP, insertable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;

    @Column(name=COLUMN_MESSAGE_SENDERNAME)
    private String senderName;

    @Column(name=COLUMN_MESSAGE_SENDEREMAIL)
    private String senderEmail;

    @Column(name=COLUMN_MESSAGE_SUBJECT)
    private String subject;

    @Column(name=COLUMN_MESSAGE_BODY)
    private String body;
}

DTO 类

public class MessageForm {

    private List<Message> messageList;

    public List<Message> getMessageList() {
        return messageList;
    }

    public void setMessageList(List<Message> messageList) {
        this.messageList = messageList;
    }
}

自定义验证器

@Component
public class MessageValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return Message.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmpty(errors, "senderName", ERRORCODE_MESSAGE_SENDERNAME_EMPTY);
        ValidationUtils.rejectIfEmpty(errors, "senderEmail", ERRORCODE_MESSAGE_SENDEREMAIL_EMPTY);
        ValidationUtils.rejectIfEmpty(errors, "subject", ERRORCODE_MESSAGE_SUBJECT_EMPTY);
        ValidationUtils.rejectIfEmpty(errors, "body", ERRORCODE_MESSAGE_BODY_EMPTY);
        Message m = (Message) target;

        if (!m.getSenderName().trim().equalsIgnoreCase(EMPTY_STRING) && m.getSenderName().matches(REGEX_CONTAINS_NUMBER)) {
            errors.rejectValue("senderName", ERRORCODE_MESSAGE_SENDERNAME_INVALID);
        }
        if (!m.getSenderEmail().trim().equalsIgnoreCase(EMPTY_STRING) && !m.getSenderEmail().matches( REGEX_EMAIL)) {
            errors.rejectValue("senderEmail", ERRORCODE_MESSAGE_SENDEREMAIL_INVALID);
        }
    }
}

控制器

@RestController
public class MainSiteRestController
{
    @Autowired
    private MessageValidator messageValidator;

     @InitBinder("message")
     protected void initMessageBinder(WebDataBinder binder) {
       binder.addValidators(messageValidator);
     }

    // this works fine
    public ResponseForm saveMessage(@Valid @RequestBody Message message, BindingResult bindingResult) throws APIException {
        if (bindingResult.hasErrors()){
            throw new APIException(getErrorMesage(bindingResult.getAllErrors()));
        }
        return apiService.saveMessage(message);
    }

    // this is not working
    public ResponseForm saveAllMessage(@RequestBody MessageForm messageForm, Errors errors) throws APIException {
        // need to validate the complete list or particular indexed object here, tried below code but not working
        // messageValidator.validate(messageForm.getMessageList().get(0), errors);
        if(errors.hasErrors()) {
            throw new APIException(createErrorString(errors));
        }
        return apiService.saveAllMessage(messageForm);
    }
}

标签: spring-bootvalidationspring-rest

解决方案


Spring 验证器在单个表单上工作,因此您必须为 list dto 创建一个验证器。


推荐阅读