spring 接口校验参数(自定义注解)
1. 注解类
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Pojo { int minLength() default 0; int maxLength() default 0; Class type() default String.class; boolean empty() default true; }
2.Pojo
引入了lombok包
import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * * @ClassName: EBillRecourseBean * @Description:追索功能 vo * @author: zhouyy * @date: 2019年10月9日 下午3:44:11 * */ @Data @NoArgsConstructor @AllArgsConstructor(access = AccessLevel.PUBLIC) public class EBillRecourseBean { private EBillRequestHeader header; // private String testName; // private String testCode; /** 追索通知(bms4ebank0019) **/ @Pojo(empty=false,minLength=20) private String custCmonId;//客户组织机构代码 private String custNo;//客户号 private String custAcct;//客户账号 private String custAcctSvcr;//客户账号开户行行号 private String drftNo;//电子票据号码 private String rcrsDt;//追索申请日期 private String rcrsTp;//追索类型 RT00拒付追索 private String amt;//追索金额 /** 选填 **/ private String rcrsRsnCd;//追索理由代码 选填 非拒付追索时填写 【RC00承兑人被依法宣告破产/RC01承兑人因违法被责令终止活动】 /** 选填 **/ private String reqRmrk;//追索通知备注 选填 private String rcvNm;//被追索人名称 private String rcvAcct;//被追索人账号 private String rcvAcctSvcr;//被追索人开户行行号 private String rcvCmonId;//被追索人组织机构代码 private String eSgnt;//电子签名 }
3. BaseController
接口需要继承的controller类
import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import com.ebilloperate.util.Pojo; public class BaseController { public Map valid(Object bean){ Field[] fileds = bean.getClass().getDeclaredFields(); Map<String,String> map = new HashMap(); map.put("respCode", "0000"); try { for (Field field : fileds) { if(field.isAnnotationPresent(Pojo.class)){ field.setAccessible(true); Pojo annotation = field.getAnnotation(Pojo.class); int maxLength = annotation.maxLength(); int minLength = annotation.minLength(); boolean empty = annotation.empty(); Object value = field.get(bean); Class fieldType = field.getType(); String msg = ""; if(fieldType == String.class){ if(!empty){ if(value == null || "".equals(value.toString().trim())){ msg = field.getName()+"不能为空!"; }else if(maxLength >0 && value.toString().length() >maxLength){ msg = field.getName()+"超长!"; }else if(minLength >0 && value.toString().length() <minLength){ msg = field.getName()+"过短!"; } } if(!"".equals(msg)){ map.put("respMsg", msg); return map; } } } } } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); map.put("respMsg", "接口错误"); return map; } return null; } }
4.具体的接口controller类
package com.ebilloperate.features.web.controller; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.common.utils.StringUtil; import com.ebilloperate.features.pojo.EBillRecourseBean; import com.ebilloperate.features.service.EBillRecourseService; import com.bytter.framework.log.FeaturesLog; /** * * @ClassName: EBillRecourceController * @Description:电票追索交易类 * 追索通知 * 同意清偿申请 * 同意清偿应答(签收) * @author: zhouyy * @date: 2019年10月9日 下午3:25:47 * */ @RestController @RequestMapping(value="/eBillRecourseTrade") public class EBillRecourseController extends BaseController{ protected FeaturesLog logger = new FeaturesLog(EBillRecourseController.class.getName()); /** * * <p>@Description: 追索通知</p> * @Title NoticeOfRecourse * @author zhouyy * @param bean * @return * @date: 2019年10月9日 下午3:45:33 */ @RequestMapping(value="/test", method=RequestMethod.POST,produces="application/json;charset=UTF-8") public Map test(@RequestBody EBillRecourseBean bean){ Map map = valid(bean); if(map != null){ return map; } //之前要做的 // Map returnMap = eBillRecourseService.doNoticeOfRecourse(bean); Map returnMap = new HashMap(); //之后要做的 returnMap.put("respCode", "0001"); returnMap.put("respMsg", "请求成功!Bytter接口返回随机字符串:"+UUID.randomUUID().toString().replaceAll("-", "")); if(StringUtil.isBlank(bean.getCustCmonId()) || bean.getCustCmonId().length() >10){ returnMap.put("respCode", "0000"); returnMap.put("respMsg", "请求参数有误!参数【custCmonId】"); return returnMap; } if(StringUtil.isBlank(bean.getCustNo()) || bean.getCustNo().length() >32){ returnMap.put("respCode", "0000"); returnMap.put("respMsg", "请求参数有误!参数【custNo】"); return returnMap; } for (Object key : returnMap.keySet()) { System.out.println("key="+key+";value="+returnMap.get(key)); } return returnMap; } }
上面采用的是普通的继承方法。亦可用spring的aop,在进入controller之前进行校验,具体的controller就不用继承、方法中也不需要调用父类方法
5.aop类
package com.ebilloperate.util; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import com.framework.log.FeaturesLog; @Component @Aspect public class ControllerAspect { protected FeaturesLog logger = new FeaturesLog(ControllerAspect.class.getName()); //对包下所有的controller结尾的类的所有方法增强 // private final String executeExpr = "execution(* com.bytter.ebilloperate.features.web..*Controller.*(..))"; private final String executeExpr = "execution(* com.bytter.ebilloperate.features.web..*controller.*(..))"; /** * @param joinPoint: * @throws Exception * @Author: TheBigBlue * @Description: 环绕通知,拦截controller,输出请求参数、响应内容和响应时间 * @Date: 2019/6/17 * @Return: **/ @Around(executeExpr) public Object processLog(ProceedingJoinPoint joinPoint) throws Exception { Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); Class returnc = method.getReturnType(); //获取参数 Object[] args = joinPoint.getArgs(); //接口参数校验。 必填、长度、格式== for (Object bean : args) { String msg = BytterAnnotation.PojoAnnotation(bean); if(!"".equals(msg)){ Map returnMap = new HashMap(); returnMap.put("respMsg", msg); returnMap.put("respCode", "0000"); return returnMap; } } //获取方法名称 String methodName = method.getName(); //获取参数名称 // LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer(); // String[] params = paramNames.getParameterNames(method); Object resObj = null; try { //执行原方法 resObj = joinPoint.proceed(args); } catch (Throwable e) { logger.error(methodName + "方法执行异常!"); throw new Exception(e); } return resObj; } }
6.注解解析类
package com.ebilloperate.util; import java.lang.reflect.Field; public class BytterAnnotation { public static String PojoAnnotation(Object bean) throws IllegalArgumentException, IllegalAccessException{ Field[] fileds = bean.getClass().getDeclaredFields(); for (Field field : fileds) { if(field.isAnnotationPresent(Pojo.class)){ field.setAccessible(true); Pojo annotation = field.getAnnotation(Pojo.class); int maxLength = annotation.maxLength(); int minLength = annotation.minLength(); boolean empty = annotation.empty(); Object value = field.get(bean); Class fieldType = field.getType(); if(fieldType == String.class){ if(!empty){ if(value == null || "".equals(value.toString().trim())){ return field.getName()+"不能为空!"; } if(maxLength >0 && value.toString().length() >maxLength){ return field.getName()+"超长!"; } if(minLength >0 && value.toString().length() <minLength){ return field.getName()+"过短!"; } } } } } return ""; } }