Java反射機制如何解決數據傳值為空的問題
反射機制數據傳值為空的問題
兩個小方法,用於解決BeanUtils.copyProperties(x, y);中源對象的值為空問題
1.通過實體註解數據庫字段為Map的Key,需要的非空值為Value封裝數據
@Override public Map<String, Object> setNodeParamItems(DispatchInfoItem dispatchInfoItem) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Map<String, Object> map = new HashMap<>(); DispatchInfo dispatchInfo = new DispatchInfo(); if (null != dispatchInfoItem) { BeanUtils.copyProperties(dispatchInfoItem, dispatchInfo); } Method[] methods = dispatchInfo.getClass().getDeclaredMethods(); if (methods != null) { for (Method method : methods) { String methodName = method.getName(); if (methodName.startsWith("get")) { Column column = dispatchInfo.getClass().getDeclaredMethod(methodName).getAnnotation(Column.class); Object value = method.invoke(dispatchInfo); if (null != column && StringUtils.isNotBlank(StringHelper.getString(value))) { map.put(column.name(), value); } } } } return map; }
2.根據獲取的值註入;
public void getMethods(DispatchInfo dispatchInfo, Map<String, Object> map) throws Exception { //獲取方法上的註解值 Method[] methods = dispatchInfo.getClass().getDeclaredMethods(); if (methods != null) { for (Method method : methods) { String methodName = method.getName(); if (methodName.startsWith("get")) { Column column = dispatchInfo.getClass().getDeclaredMethod(methodName).getAnnotation(Column.class); if (column != null) { String setMethodName = methodName.replaceFirst("(get)", "set"); Method setMethod = dispatchInfo.getClass().getMethod(setMethodName, method.getReturnType()); ; if (null != map.get(column.name())) { setMethod.invoke(dispatchInfo, map.get(column.name())); } } } } } }
3.根據值進行實際的操作
java 反射 處理 空值
package org.zkdg.utils.spring.annotations.impl; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.sql.SQLException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.zkdg.utils.entity.AjaxEntity; import org.zkdg.utils.spring.annotations.NNull; @Aspect @Component /** * * @author 王海明 * @createData 2017年7月13日 上午8:36:23 * @說明 :出瞭一些空值。。。 */ public class AjaxEntityHandler { // @Pointcut("@annotation(org.zkdg.utils.annotations.AfterHandler)") @Pointcut("@annotation(org.zkdg.utils.spring.annotations.NullValidate)") // @Pointcut("execution(* org.dcexam.*.service.*.*(..))") public void beforeCall() { // service方法調用之前,檢測參數,僅限第一個參數, 不能為空值 } /** * service發生異常時調用 */ @Pointcut("execution(* org.dcexam.*.service.*.*(..))") public void afterThrowEx() { System.out.println("************\n\n\n\n\n\n\n\n\n\n\n\n*******"); } @Around(value = "beforeCall()") public AjaxEntity doBefore(ProceedingJoinPoint point) throws Throwable { // TODO Auto-generated method stub // 判斷不能為空 Object[] args = point.getArgs(); if (args == null || args[0] == null) { return new AjaxEntity("warning", "未選擇任何數據。。。"); } // 獲取代理對象類方法參數 MethodSignature target = (MethodSignature) point.getSignature(); Annotation[][] annotations = target.getMethod().getParameterAnnotations(); int argsIndex = 0; StringBuilder sb = new StringBuilder(); for (Annotation[] annotation : annotations) { NNull nn = (NNull) annotation[0]; String[] descs = nn.desc(); String[] fields = nn.field(); if (fields.length > 0 && fields.length > 0 && descs.length == fields.length) { for (int i = 0; i < fields.length; i++) { Field field = args[argsIndex].getClass().getDeclaredField(fields[i]); // 允許訪問 field.setAccessible(true); Object object = field.get(args[argsIndex]); if (object == null) { sb.append(descs[i]).append("不能為空。。。<br>"); } if (object instanceof String) { String string = (String) object; if (string.trim().length() == 0) sb.append(descs[i]).append("不能為空。。。<br>"); else if (string.trim().equals("0")) sb.append("未選擇" + descs[i] + "。。。<br>"); } else if (object instanceof Number) { Integer integer = (Integer) object; if (integer == 0) sb.append("未選擇" + descs[i] + "。。。<br>"); } } if (sb.length() > 0) return AjaxEntity.ERROR(sb.toString()); } argsIndex++; } // 加上@Nullvalidate 註解,不允許出現空 值 for (Object obj : args) { if (obj == null) { return AjaxEntity.WARNING("出現瞭不允許的空值"); } else if (obj instanceof String) { if (((String) obj).length() == 0) { return AjaxEntity.WARNING("出現瞭不允許的空值"); } } } AjaxEntity ajax = (AjaxEntity) point.proceed(args); return ajax == null ? AjaxEntity.ERROR("操作失敗") : ajax; } /** * * @param joinPoint * 連接點 * @param ex * 異常 * @return AjaxEntity 異常信息 */ @AfterThrowing(value = "afterThrowEx()", throwing = "ex") public void doAfterThrowEx(JoinPoint joinPoint, Exception ex) { AjaxEntity ajax = new AjaxEntity(); if (ex.getCause() instanceof SQLException) { // 數據庫操作異常 ajax = AjaxEntity.ERROR("操作數據庫時出現異常"); } } }
另外,java 命名時 。屬性最好不要有下劃線,否則可能會粗錯。。。。。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 使用SpringAOP獲取用戶操作日志入庫
- 手寫redis@Cacheable註解 參數java對象作為key值詳解
- SpringBoot @Cacheable自定義KeyGenerator方式
- 使用spring通過aop獲取方法參數和參數值
- springboot自定義日志註解的實現