生活随笔
收集整理的這篇文章主要介紹了
自定义的注解校验器的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先先學習一下注解,注解為我們在代碼中添加信息提供了一種形式化的方法,使得我們在稍后的某個時刻可以方便地使用這些數據。
????在日常的編碼中我們一直都在使用注解,只是沒有特別關注過,Java中內置了三種注解:@Override,@SuppressWarnings @Deprecated。相信只要學習過Java的同學一定是見過這些主角的 。
????如果我們要寫一個自定義的注解應該怎么呢?
????首先需要定義一個注解標注出是自定義的注解
?
Java代碼??
? ? ? ? ?? @Documented?? @Target(ElementType.ANNOTATION_TYPE)?? @Retention(RetentionPolicy.RUNTIME)?? public?@interface?CustomerValidator?{?? ?? }?? ??????這個注解中沒有任何內容,屬于標記注解
?
?
??? 自定義?日期類型校驗器的注解
?
Java代碼??
? ? ? ? ?? @Documented?? @Target(ElementType.FIELD)?? @Retention(RetentionPolicy.RUNTIME)?? @CustomerValidator?? public?@interface?DateString?{?? ????String?pattern()?default?"yyyy-MM-dd?HH:mm:ss";?? ?? ????String?errorCode()?default?"must?date";?? ?? ????String?message()?default?"must?be?date?pattern";?? }?? ?
?
?
, @Target是用來定義該注解將可以應用在什么地方,FIELD表示該注解應用在一個屬性上,@Rectetion?用來定義該注解在哪一個級別可以使用 RUNTIME表示運行時。
?????String pattern() default "yyyy-MM-dd HH:mm:ss"?表示如果不指定pattern這個值的時候將返回默認值“yyyy-MM-dd HH:mm:ss” 。
?
???有了自己的注解,那么就需要一個注解的處理器,定義一個處理器接
?
Java代碼??
? ? ? ? ? ?? public?interface?CustomerValidatorRule?{?? ?? ????? ? ? ? ? ? ?? ????public?boolean?support(Annotation?annotation);?? ?? ????? ? ? ? ? ? ? ?? ????public?void?valid(Annotation?annotation,?Object?object,?Field?field,?Errors?errors)?? ????????????throws?Exception;?? }?? ?
?
?
Java代碼??
? ? ? ? ?? public?abstract?class?AbastractCustomerValidatorRule?implements?CustomerValidatorRule?{?? ?? ????? ? ?? ????public?abstract?boolean?support(Annotation?annotation);?? ?? ????? ? ? ?? ????public?void?valid(Annotation?annotation,?Object?target,?final?Field?field,?final?Errors?errors)?? ???????????????????????????????????????????????????????????????????????????????????????????????????throws?Exception?{?? ????????preHandle(annotation,?target,?field,?errors);?? ????????PropertyDescriptor?propertyDescriptor?=?BeanUtils.getPropertyDescriptor(target.getClass(),?? ????????????field.getName());?? ????????Method?reader?=?propertyDescriptor.getReadMethod();?? ????????Object?property?=?reader.invoke(target);?? ????????validProperty(annotation,?property,?new?PostHandler()?{?? ?? ????????????public?void?postHanle(String?errorCode,?String?message)?{?? ????????????????errors.rejectValue(field.getName(),?errorCode,?message);?? ????????????}?? ????????});?? ????}?? ?? ????public?static?interface?PostHandler?{?? ????????public?void?postHanle(String?errorCode,?String?message);?? ????}?? ?? ????? ? ?? ????private?void?preHandle(Annotation?annotation,?Object?target,?Field?field,?Errors?errors)?{?? ????????Assert.notNull(target);?? ????????Assert.notNull(annotation);?? ????????Assert.notNull(errors);?? ????????Assert.notNull(field);?? ????}?? ?? ????public?abstract?void?validProperty(Annotation?annotation,?Object?property,?? ???????????????????????????????????????PostHandler?postHandler);?? ?? }?? ?
?
?
?
Java代碼??
? ? ? ? ?? @CustomerRule?? public?class?DateValidatorRule?extends?AbastractCustomerValidatorRule?{?? ?? ????? ? ?? ????@Override?? ????public?boolean?support(Annotation?annotation)?{?? ????????return?annotation?instanceof?DateString;?? ?? ????}?? ?? ????? ? ?? ????@Override?? ????public?void?validProperty(Annotation?annotation,?Object?property,?PostHandler?postHandler)?{?? ????????DateString?ds?=?(DateString)?annotation;?? ????????if?(parse(ds.pattern(),?(String)?property)?==?null)?{?? ????????????postHandler.postHanle(ds.errorCode(),?ds.message());?? ????????}?? ????}?? ?? ????private?Date?parse(String?pattern,?String?property)?{?? ????????try?{?? ????????????SimpleDateFormat?sdf?=?new?SimpleDateFormat(pattern);?? ????????????return?sdf.parse(property);?? ????????}?catch?(ParseException?e)?{?? ?????????????? ????????}?? ????????return?null;?? ????}?? }?? ?
?
???這樣我們就有了一個注解處理器,為了方便擴展,該處使用注解的方式加載定義的注解處理器,這就需要定義一個標注是自定義的注解處理器的注解。
?
?
Java代碼??
? ? ? ? ?? @Documented?? @Target(ElementType.TYPE)?? @Retention(RetentionPolicy.RUNTIME)?? @Component?? public?@interface?CustomerRule?{?? ?? }?? ?
?
?
Java代碼??
? ? ? ? ?? public?class?CustomerValidatorConfig?implements?ApplicationContextAware?{?? ?? ????private?Map<Annotation,?CustomerValidatorRule>?rules???????????????????=?new?ConcurrentHashMap<Annotation,?CustomerValidatorRule>();?? ?? ????Map<String,?Object>????????????????????????????customerValidationRules?=?null;?? ?? ????? ? ?? ????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{?? ????????customerValidationRules?=?applicationContext?? ????????????????.getBeansWithAnnotation(CustomerRule.class);?? ????????System.out.println(customerValidationRules);?? ????}?? ?? ????private?CustomerValidatorRule?findFormMap(Annotation?annotation)?{?? ????????for?(Entry<String,?Object>?entry?:?customerValidationRules.entrySet())?{?? ????????????if?(entry.getValue()?!=?null?? ????????????????????&&?((CustomerValidatorRule)?entry.getValue()).support(annotation))?{?? ????????????????return?(CustomerValidatorRule)?entry.getValue();?? ????????????}?? ????????}?? ????????return?null;?? ????}?? ?? ????public?CustomerValidatorRule?findRule(Annotation?annotation)?{?? ????????CustomerValidatorRule?customerValidatorRule?=?null;?? ????????if?(!rules.containsKey(annotation))?{?? ????????????CustomerValidatorRule?cvr?=?findFormMap(annotation);?? ????????????if?(cvr?!=?null)?{?? ????????????????rules.put(annotation,?cvr);?? ????????????}?? ????????????customerValidatorRule?=?cvr;?? ????????}?? ????????customerValidatorRule?=?rules.get(annotation);?? ????????return?customerValidatorRule;?? ????}?? }?? ?通過實現ApplicationContextAware接口,從上下文中自動加載處理器。 Java代碼??
? ? ? ? ?? @Component?? public?class?CustomerValidatorFactory?implements?Validator?{?? ?? ????@Autowired?? ????private?CustomerValidatorConfig?customerValidatorConfig;?? ?? ????? ? ?? ????public?boolean?supports(Class<?>?clazz)?{?? ????????return?true;?? ????}?? ?? ????? ? ?? ????public?void?validate(Object?target,?Errors?errors)?{?? ????????Assert.notNull(target);?? ????????Assert.notNull(errors);?? ????????List<Field>?fileds?=?getFields(target.getClass());?? ????????for?(Field?field?:?fileds)?{?? ????????????Annotation[]?annotations?=?field.getAnnotations();?? ????????????for?(Annotation?annotation?:?annotations)?{?? ????????????????if?(annotation.annotationType().getAnnotation(CustomerValidator.class)?!=?null)?{?? ????????????????????try?{?? ????????????????????????CustomerValidatorRule?customerValidatorRule?=?customerValidatorConfig?? ????????????????????????????.findRule(annotation);?? ????????????????????????if?(customerValidatorRule?!=?null)?{?? ????????????????????????????customerValidatorRule.valid(annotation,?target,?field,?errors);?? ????????????????????????}?? ????????????????????}?catch?(Exception?e)?{?? ????????????????????????e.printStackTrace();?? ????????????????????}?? ????????????????}?? ????????????}?? ????????}?? ?? ????}?? ?? ????? ? ? ? ? ?? ????private?List<Field>?getFields(Class<??extends?Object>?clazz)?{?? ?????????? ????????List<Field>?fields?=?new?ArrayList<Field>();?? ?? ?????????? ????????while?(clazz?!=?null)?{?? ?????????????? ????????????Collections.addAll(fields,?clazz.getDeclaredFields());?? ????????????clazz?=?clazz.getSuperclass();?? ????????}?? ????????return?fields;?? ????}?? ?? }?? ?
?
使用自定義校驗處理器:
Java代碼??
? ? ? ? ?? @RunWith(SpringJUnit4ClassRunner.class)?? @ContextConfiguration(locations?=?"classpath:spring.xml")?? public?class?DemoTest?{?? ?? ????@Autowired?? ????private?Validator?customerValidatorFactory;?? ?? ????@Test?? ????public?void?helloTest()?{?? ????????Form?form?=?new?Form();?? ????????form.setCurrent("2015?11?11");?? ????????BindException?errors?=?new?BindException(form,?"target");?? ????????customerValidatorFactory.validate(form,?errors);?? ????????System.out.println(errors.getFieldErrors());?? ????}?? ?? }?? ?
Java代碼??
? ? ? ? ?? public?class?Form?{?? ????@DateString?? ????private?String?current;?? ?? ????? ? ? ? ?? ????public?String?getCurrent()?{?? ????????return?current;?? ????}?? ?? ????? ? ? ? ?? ????public?void?setCurrent(String?current)?{?? ????????this.current?=?current;?? ????}?? ?? }?? ?運行的結果是:
Java代碼??
五月?30,?2015?8:21:35?下午?org.springframework.test.context.TestContextManager?retrieveTestExecutionListeners?? 信息:?@TestExecutionListeners?is?not?present?for?class?[class?com.cathy.core.service.annotation.HelloServiceTest]:?using?defaults.?? 五月?30,?2015?8:21:36?下午?org.springframework.beans.factory.xml.XmlBeanDefinitionReader?loadBeanDefinitions?? 信息:?Loading?XML?bean?definitions?from?class?path?resource?[spring.xml]?? 五月?30,?2015?8:21:36?下午?org.springframework.context.support.GenericApplicationContext?prepareRefresh?? 信息:?Refreshing?org.springframework.context.support.GenericApplicationContext@f7aae2:?startup?date?[Sat?May?30?20:21:36?CST?2015];?root?of?context?hierarchy?? 五月?30,?2015?8:21:36?下午?org.springframework.beans.factory.support.DefaultListableBeanFactory?preInstantiateSingletons?? 信息:?Pre-instantiating?singletons?in?org.springframework.beans.factory.support.DefaultListableBeanFactory@19627bc:?defining?beans?[customerValidatorFactory,dateValidatorRule,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,customerValidatorConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor];?root?of?factory?hierarchy?? {dateValidatorRule=com.cathy.core.service.annotation.rule.DateValidatorRule@1758f2a}?? [Field?error?in?object?'target'?on?field?'current':?rejected?value?[2015?11?11];?codes?[must?date.target.current,must?date.current,must?date.java.lang.String,must?date];?arguments?[];?default?message?[must?be?date?pattern]]?? ?PS: spring的配置文件
Java代碼??
<?xml?version="1.0"?encoding="UTF-8"?>?? <beans?xmlns="http://www.springframework.org/schema/beans"?? ????xmlns:p="http://www.springframework.org/schema/p"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?? ????xmlns:context="http://www.springframework.org/schema/context"?xmlns:tx="http://www.springframework.org/schema/tx"?? ????xmlns:aop="http://www.springframework.org/schema/aop"?xmlns:jee="http://www.springframework.org/schema/jee"?? ????xmlns:task="http://www.springframework.org/schema/task"?? ????xsi:schemaLocation="?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????http:?? ????????">?? ????<context:component-scan?base-package="com.cathy.core.service"/>?? ??? ??? ????<bean?id="customerValidatorConfig"?class="com.cathy.core.service.annotation.handle.CustomerValidatorConfig"/>?? ?????? ?????? ????? </beans>??
總結
以上是生活随笔為你收集整理的自定义的注解校验器的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。