基於註解的校驗器,本文使用的是攔截器,並將攔截器交給nutz的ioc容器進行管理。思路是在前臺發過來的請求,在被指定的函數接收參數前,會先被攔截,在攔截器中獲取方法的參數,及須要校驗的字段,校驗類型,並將校驗結果放到一個對象中,並將對象賦值給函數參數。本例子中前段只會傳遞一個參數json,全部須要的參數都封裝在了json中,json格式如{id:1,name:"cai10"}java
主要用到的類有如下幾個:json
一、首先是自定義註解:ValidationAnnotation數組
@Target(value={ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidationAnnotation { /** * * @Title key須要校驗的字段類型,如required等 * @Description * @author Administrator * @param * @date 2015-5-14 * @return String */ ValidationType validationType() default ValidationType.REQUIRED; /** * * @Title value * @Description 校驗的字段 * @author Administrator * @param * @date 2015-5-14 * @return String[] */ String[] fieldValues() default {}; }
二、自定義校驗類型:ValidationTypeide
public enum ValidationType { /*必填*/ REQUIRED //能夠根據業務須要添加一些其餘類型的校驗 }
三、錯誤信息彙總類,存儲校驗失敗的信息:Errors函數
/** * 驗證錯誤信息彙總類 * * @author QinerG(QinerG@gmail.com) */ public class Errors { /* * 存放錯誤信息的 map */ private Map<String, String> errorMap = new TreeMap<String, String>(); /** * @return 是否存在驗證錯誤 */ public boolean hasError() { return errorMap.size() > 0; } /** * @return 返回存在錯誤的總數 */ public int errorCount() { return errorMap.size(); } /** * 增長一個錯誤信息 * * @param fieldName * 存在錯誤的字段名 * @param errorMessage * 錯誤的詳細信息 */ public void add(String fieldName, String errorMessage) { errorMap.put(fieldName, errorMessage); } /** * 返回錯誤信息列表 * @return */ public Collection<String> getErrorsList() { return errorMap.values(); } /** * 返回詳細的錯誤信息列表,含驗證錯誤的字段名和提示語 * @return */ public Map<String, String> getErrorsMap() { return errorMap; } }
四、自定義的攔截器,並繼承nutz的AbstractMethodInterceptor:ValidationInterceptor學習
/** * 基於註解的驗證 * @author Administrator * * 2015-5-14 */ @IocBean//注意必須將此攔截器交給ioc管理 public class ValidationInterceptor extends AbstractMethodInterceptor{ @Override public boolean beforeInvoke(Object obj, Method method, Object... args) { //定義 第一個參數爲json, 第二個參數爲Errors對象 if(args.length ==2){ String json = (String) args[0]; NutMap map = Json.fromJson(NutMap.class, json); ValidationAnnotation anno = method.getAnnotation(ValidationAnnotation.class); ValidationType validator_type = anno.validationType(); String[] values = anno.fieldValues(); //若是是校驗必填項 if(ValidationType.REQUIRED.equals(validator_type)){ //判斷每一個字段是否都存在於數組values中 Errors es = null; for(String val:values){ if(!map.containsKey(val)){ args[2] = es= new Errors(); es.add("required_string", "param ["+val+"] is requred, please check!......"); break; } } } } return super.beforeInvoke(obj, method, args); } }
五、使用校驗器的函數以下:ui
@Aop("validationInterceptor") public void saveSupplierInfo(@Param("json")String json, Errors error) throws IOException{ try { if(error.hasError()){ result.setSuccessData(error.getErrorsList().toString()); }else{ boolean flag = supplierService.saveSupplierInfo(json); result.setSuccessData(flag); } } catch (Exception e) { e.printStackTrace(); result.setExceptionData(e.getMessage()); log.error(e.getMessage()); } HttpKit.responseJson(result, getResponse()); }
可能有些設計不合理,望相互學習指教設計