【问题标题】:Best practices for integrating validations in service/controller layer在服务/控制器层中集成验证的最佳实践
【发布时间】:2015-12-17 11:19:38
【问题描述】:

我使用 JPA/Spring jpa/data/mvc/validation 并且我有这样的类结构: 波乔/@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> {}

我为验证创建了验证类(Spring Validator),@Service@Controller/@RestController 类将使用这些验证类。 我不喜欢在 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@Controller/@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 集成的最佳方式是什么?

【问题讨论】:

    标签: spring validation service controller


    【解决方案1】:

    我的解决方案:

    存储库:

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多