在服务/控制器层中集成验证的最佳实践

时间:2015-12-17 11:19:38

标签: spring validation service controller

我使用JPA / Spring jpa / data / mvc / validation,我有这个类结构: POJO / @Entity

@MappedSuperclass @public class Base {//} 
@Entity public class Account extends Base {//} 

JpaRepository接口:

@NoRepositoryBean public interface BaseRepository<T extends Base> extends JpaRepository<T, Integer> {}
public interface AccountRepository extends BaseRepository<Account> {}

我已经为@Service@Controller / @RestController类使用的验证创建了验证类(Spring Validator)。 我不想在pojo课程中添加任何验证(@Max@Min@NotNull)!

public abstract class BaseValidator<T extends Base> implements Validator {}
    @Component public class ConfigValidator extends BaseValidator<Config> {
    public void validate(Object obj, Errors errors) {     // basic (fields or multifields) validations 
        super.validate(obj, errors);
        //other.validations.
    }   
    public void addValidate(Account obj, Errors errors) { // business validations when add 
       validate(obj, errors);
       super.addValidate(obj,errors);
       //own add validations.
    }
    public void editValidate(Account obj, Errors errors) { // business validations when update }

    public void delValidate(Account obj, Errors errors) { // business validations when add 
        validate(obj, errors);
        super.delValidate(obj,errors);
        //own delete validations.
    }   
}

将验证类与@Service@Controlle r / @RestController集成的最佳方法是什么? 那样的东西?

@Service(服务层):(包装器存储库+验证)

    public abstract class BaseService<T extends Base>{ // }

    @Service public class AccountService extends BaseService<Account> {

        @Autowired AccountRepository repository;
        @Autowired AccountValidator validator;

        add(Account obj, Errors errors) {
            // validator.validate(obj, errors)
            // if (!errors.hasErrors())
            // validator.add(obj, errors)
            // if (!errors.hasErrors())
                repository.add(obj)}
        }

        edit(Account ob, Errors errors) { // } 

        del(Integer id, Errors errors) {
            Account obj = repository.findOne(id);
            // validator.validate(obj, errors)
            // if (!errors.hasErrors())
            // validator.delValidate(obj, errors)
            // if (!errors.hasErrors())
                repository.del(id)}
        }

        // Problem: I don't have a class implements Erros internal call add/del methods. BeanPropertyBindingResult?
   }

@Controller(控制层):

@Controller
@RequestMapping("/Account")
public class AccountController {

    @Autowired AccountService service;

    @RequestMapping(value = "/Add", method = RequestMethod.GET)
    public String addForm(Model model) { // }

    @RequestMapping(value = "/Add", method = RequestMethod.POST)
    public String addAction(@Validated @ModelAttribute("entity") Account entity, BindingResult result, Model model) {

        //   if (accountService.add(entity, result) had errors)
        //      return to form with errors.
        }
}   

将验证类与@Service@Controller / @RestController集成的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

我的解决方案:

存储库:

NoRepositoryBean
public interface BaseRepository<T extends Base> extends JpaRepository<T,     Integer> {
    // Common methods
}

public interface AccountRepository extends BaseRepository<Account> {
    // Account methods
}

验证

public interface BaseValidator<T extends Base> extends Validator {
    // Common methods
}

public interface AccountValidator extends BaseValidator<Account>, Validator     {
    // Account methods
}

public abstract class AbsBaseValidator<T extends Base> implements     BaseValidator<T> {
    private BaseRepository<T> repository;
    // Common methods
}

@Component
public class AccountValidatorImpl extends AbsBaseValidator<Account> implements AccountValidator {
    private AccountRepository repository;

    @Autowired
    public AccountValidatorImpl(AccountRepository repository) {
        super(repository);
        this.repository = repository;
    }
    // Account methods
}

服务:

public interface BaseService<T extends Base> {
    // Common methods
}

public interface AccountService extends BaseService<Account> {
    // Account methods
}

public abstract class AbsBaseService<T extends Base> implements BaseService<T> {

    private BaseRepository<T> repository;
    private BaseValidator<T> validator;
    public AbsBaseService(BaseRepository<T> repository, BaseValidator<T> validator) {
        this.repository = repository;
        this.validator = validator;
    }
        // Common methods       
}

@Service
public class AccountServiceImpl extends AbsBaseService<Account> implements AccountService {

    private AccountRepository repository;
    private AccountValidator validator;
    @Autowired
    public AccountServiceImpl(AccountRepository repository, AccountValidator validator) {
        super(repository, validator);
        this.repository = repository;
        this.validator = validator;
    }
        // Account methods
}

控制器:

public interface BaseController<T extends Base> {
        // Common methods
}

public interface AccountController extends BaseController<Account> {
    // Account methods
}

public abstract class AbsBaseController<T extends Base> implements BaseController<T> {

    private BaseService<T> service;
    private BaseValidator<T> validator;

    public AbsBaseController(BaseService<T> service, BaseValidator<T> validator) {
        super(service, validator);
        this.service = service;
        this.validator = validator;
        this.obj = service.getInstance();
    }
        // Common methods
}

@Controller
@RequestMapping("/Account")
public class AccountControllerImpl extends AbsBaseController<Account> implements AccountController {

    private AccountService service;
    private AccountValidator validator;

    @Autowired
    public AccountControllerImpl(AccountService service, AccountValidator validator) {
        super(service, validator);
        this.service = service;
        this.validator = validator;
    }
    // Account methods
}