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 "";
}
}
spring 接口校验参数(自定义注解)的更多相关文章
- 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- Spring中如何使用自定义注解搭配@Import引入内外部配置并完成某一功能的启用
文章背景 有一个封装 RocketMq 的 client 的需求,用来提供给各项目收.发消息,但是项目当中常常只使用收或者发消息的单一功能,而且不同的项目 group 等并不相同而且不会变化,可以在项 ...
- Spring启动时获取自定义注解的属性值
1.自定义注解 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documen ...
- Spring Boot 中使用自定义注解,AOP 切面打印出入参日志及Dubbo链路追踪透传traceId
一.使用背景 开发排查系统问题用得最多的手段就是查看系统日志,在分布式环境中一般使用 ELK 来统一收集日志,但是在并发大时使用日志定位问题还是比较麻烦,由于大量的其他用户/其他线程的日志也一起输出穿 ...
- Spring 实现策略模式--自定义注解方式解耦if...else
策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...
- Spring 捕捉校验参数异常并统一处理
使用 @Validated ,@Valid ,@NotBlank 之类的,请自行百度,本文着重与捕捉校验失败信息并封装返回出去 参考: https://mp.weixin.qq.com/s/EaZxY ...
- Spring MVC接受参数的注解
一.Request请求发出后,Headler Method是如何接收处理数据的? Headler Method绑定常用的参数注解,根据处理request的不同部分分为四类: A.处理 Request ...
- spring boot通过自定义注解和AOP拦截指定的请求
一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...
- Spring Boot中自定义注解+AOP实现主备库切换
摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...
随机推荐
- php常用header状态
<?php //200 正常状态 header('HTTP/1.1 200 OK'); // 301 永久重定向,记得在后面要加重定向地址 Location:$url header('HTTP/ ...
- [Vue] vuex-interview
1.你有使用过 vuex 的 module 吗?主要是在什么场景下使用? 把状态全部集中在状态树上,非常难以维护. 按模块分成多个 module,状态树延伸多个分支,模块的状态内聚,主枝干放全局共享状 ...
- sql删除重复行和删除字段首位
删除重复行 user_info: -- 单字段筛选重复行 SELECT *from user_info WHERE NAME in ( SELECT NAME from user_info GROUP ...
- js 判断图片是否存在
有的时候 虽然图片的路径是正确的 但是有可能由于某些原因 导致图裂了 或者网络加载失败 那这样的应该怎么判断呢? 如下: function isHasImg(pathImg){ var Img ...
- mysql数据库之存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该 ...
- iOS蓝牙4.0开发
文/starfox寒流(简书作者)原文链接:http://www.jianshu.com/p/974d165f78b5著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. iOS 蓝牙4.0 ...
- 从分析攻击方式来谈如何防御DDoS攻击
DDoS攻击的定义: DDoS攻击全称——分布式拒绝服务攻击,是网络攻击中非常常见的攻击方式.在进行攻击的时候,这种方式可以对不同地点的大量计算机进行攻击,进行攻击的时候主要是对攻击的目标发送超过其处 ...
- wpf Textbox 回车就换行
将 TextWrapping 属性设置为 Wrap 会导致输入的文本在到达 TextBox 控件的边缘时换至新行,必要时会自动扩展 TextBox 控件以便为新行留出空间. 将 AcceptsRetu ...
- Delphi 标识符
- 微软宣布全新命令行+脚本工具:PowerShell 7
DOS 逐渐退出历史舞台后,Windows 一直内置着 CMD 命令行工具,并在 Windows 7 时代升级为更强悍的 PowerShell,不仅可以执行命令行,更可以执行各种高级脚本,还能跨平台. ...