自定义Spring的Aop切面类拦截业务请求,并获取到请求的参数名和参数值
来源:互联网 发布:ubuntu sublime tar 编辑:程序博客网 时间:2024/06/05 19:20
1.问题引入
本次需求是涉及到审核操作,添加,修改,删除人员,商品时如果需要审核,则先向审核队列表中插入审核信息,不需要审核时直接操作业务表(用户表)。这里许多操作都需要判断是否需要审核,所以我就定义了一个sping的切面类来拦截所有进入业务层的方法(也可以使用springmvc的拦截器)。第二个问题是在切面类中如何获取请求的参数,和参数对应的值。至此有两个问题需要解决:⑴如何定义一个切面类;⑵在这个切面类中如何获取请求参数。
2.定义切面类
下面是切面类的核心代码,需要注意的是,在这里需要引入jar包aspectj,我引入的是1.7.4的,同时还要在spring.xml的配置文件中进行如下配置。
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<context:component-scan base-package="com.ynet.finmall.innermanage.service.impl" />
<context:component-scan base-package="com.ynet.finmall.innermanage.config" />
<context:component-scan base-package="com.ynet.finmall.innermanage.service.impl" />
<context:component-scan base-package="com.ynet.finmall.innermanage.config" />
service.impl是要扫描的业务层实现类所在的包。config是切面类ReviewValidate所在的包。到这里切面类已经定义完毕,可以根据自己的需要配置切入点。代码如下:
@Component
@Aspect
public class ReviewValidate {
@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
//获取到请求参数,判断是否需要审核,代码略
if(需要审核){
//执行通用的审核操作,代码略。。。
return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}
@Aspect
public class ReviewValidate {
@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
//获取到请求参数,判断是否需要审核,代码略
if(需要审核){
//执行通用的审核操作,代码略。。。
return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}
3.在切面类中获取请求参数名和参数值
如果请求参数在在springmvc中是以一个实体类的形式接收的或者jdk是1.8都是可以通过Object[] args = joinPoint.getArgs();这句代码获取到请求参数和参数值的,但是如果以Map形式接的参数,则要费点力气了。下面是所有实现代码(需要引入javassist的jar包)。
/**
* @author 刘俊重
* @Description 审核校验
* 所有的service业务方法都会先走这个方法,
* 先判断本操作需不需要审核,如果需要审核则插入审核队列表,
* 不需要审核则直接插入相关业务表
* @date 2017年7月5日
*/
@Component
@Aspect
public class ReviewValidate {
@Autowired
private ImAuthQueueDao imAuthQueueDao;
private static Logger logger = LoggerFactory.getLogger(ReviewValidate.class);
@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
String classType = joinPoint.getTarget().getClass().getName();
Class<?> clazz = Class.forName(classType);
String clazzName = clazz.getName();
String methodName = joinPoint.getSignature().getName(); //获取方法名称
//获取参数名称和值
Map<String,Object > nameAndArgs = this.getFieldsName(this.getClass(), clazzName, methodName,args);
//nameAndArgs的两种类型,用实体类接收的类似这样: reqParams=com.ynet.finmall.innermanage.event.SaveOrUpdateRoleReqParam@616b9c0e
//用Map<String,Object>接收的是这样:menuNo=56473283,遍历这个map区分两种不同,使用不同的取值方式。
//根据获取到的值所属的不同类型通过两种不同的方法获取参数
boolean flag = false;
if(nameAndArgs!=null && nameAndArgs.size()>0){
for (Map.Entry<String, Object> entry : nameAndArgs.entrySet()) {
logger.info(">>>>>>>>>>>>>>类型"+entry.getValue().getClass().toString());
if(entry.getValue() instanceof String){
flag = true;
break; //跳出循环
}
}
}
StringBuffer sb = new StringBuffer();
if(flag){
//从Map中获取
sb.append(JSONObject.toJSONString(nameAndArgs))
.append(",");
}else{
if (args != null) {
for (Object object : args) {
if (object != null) {
if (object instanceof MultipartFile||object instanceof ServletRequest||object instanceof ServletResponse) {
continue;
}
sb.append(JSONObject.toJSONString(object))
.append(",");
}
}
}
}
String isReview = "";
String arg = sb.toString().substring(0, sb.toString().length()-1);
JSONObject cache_json = new JSONObject();
if(arg!=null){
cache_json = JSONObject.parseObject(arg);
//是否需要审核
isReview = cache_json.getString("isReview");
}
logger.info(">>>>>>>>>>>>>>>>>>>"+cache_json);
if(isReview!=null && isReview!="" && DbEnum.CommonReqParam.IsReview.NEEDREVIEW.equals(isReview)){
//需要审核,执行存入审核队列操作
//如果本操作是需要审核的,则将本操作缓存在操作队列中,审核通过时才真正将新增操作员操作插入数据库
ImAuthQueue imAuth = new ImAuthQueue();
imAuth.setIaqBatchNo(UUID.randomUUID().toString().replace("-", ""));
imAuth.setIaqPk(cache_json.toJSONString());
imAuth.setIaqBsnCode(cache_json.getString("businessCode"));
imAuth.setIaqOpType(cache_json.getString("operatorType"));
imAuth.setIaqSubmitUserId(cache_json.getString("submitUserId"));
imAuth.setIaqDescribe(cache_json.getString("describe"));
//插入审核队列表中
imAuthQueueDao.insert(imAuth);
return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}
/**
* @Description 获取字段名和字段值
* @Author 刘俊重
* @date 2017年7月6日
* @return Map<String,Object>
*/
private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws Exception {
Map<String,Object > map=new HashMap<String,Object>();
ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(cls);
pool.insertClassPath(classPath);
CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (attr == null) {
// exception
}
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++){
map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
}
return map;
}
}
* @author 刘俊重
* @Description 审核校验
* 所有的service业务方法都会先走这个方法,
* 先判断本操作需不需要审核,如果需要审核则插入审核队列表,
* 不需要审核则直接插入相关业务表
* @date 2017年7月5日
*/
@Component
@Aspect
public class ReviewValidate {
@Autowired
private ImAuthQueueDao imAuthQueueDao;
private static Logger logger = LoggerFactory.getLogger(ReviewValidate.class);
@Around(value = "execution(* com.ynet.finmall.innermanage.service.impl.*.*(..))")
public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
String classType = joinPoint.getTarget().getClass().getName();
Class<?> clazz = Class.forName(classType);
String clazzName = clazz.getName();
String methodName = joinPoint.getSignature().getName(); //获取方法名称
//获取参数名称和值
Map<String,Object > nameAndArgs = this.getFieldsName(this.getClass(), clazzName, methodName,args);
//nameAndArgs的两种类型,用实体类接收的类似这样: reqParams=com.ynet.finmall.innermanage.event.SaveOrUpdateRoleReqParam@616b9c0e
//用Map<String,Object>接收的是这样:menuNo=56473283,遍历这个map区分两种不同,使用不同的取值方式。
//根据获取到的值所属的不同类型通过两种不同的方法获取参数
boolean flag = false;
if(nameAndArgs!=null && nameAndArgs.size()>0){
for (Map.Entry<String, Object> entry : nameAndArgs.entrySet()) {
logger.info(">>>>>>>>>>>>>>类型"+entry.getValue().getClass().toString());
if(entry.getValue() instanceof String){
flag = true;
break; //跳出循环
}
}
}
StringBuffer sb = new StringBuffer();
if(flag){
//从Map中获取
sb.append(JSONObject.toJSONString(nameAndArgs))
.append(",");
}else{
if (args != null) {
for (Object object : args) {
if (object != null) {
if (object instanceof MultipartFile||object instanceof ServletRequest||object instanceof ServletResponse) {
continue;
}
sb.append(JSONObject.toJSONString(object))
.append(",");
}
}
}
}
String isReview = "";
String arg = sb.toString().substring(0, sb.toString().length()-1);
JSONObject cache_json = new JSONObject();
if(arg!=null){
cache_json = JSONObject.parseObject(arg);
//是否需要审核
isReview = cache_json.getString("isReview");
}
logger.info(">>>>>>>>>>>>>>>>>>>"+cache_json);
if(isReview!=null && isReview!="" && DbEnum.CommonReqParam.IsReview.NEEDREVIEW.equals(isReview)){
//需要审核,执行存入审核队列操作
//如果本操作是需要审核的,则将本操作缓存在操作队列中,审核通过时才真正将新增操作员操作插入数据库
ImAuthQueue imAuth = new ImAuthQueue();
imAuth.setIaqBatchNo(UUID.randomUUID().toString().replace("-", ""));
imAuth.setIaqPk(cache_json.toJSONString());
imAuth.setIaqBsnCode(cache_json.getString("businessCode"));
imAuth.setIaqOpType(cache_json.getString("operatorType"));
imAuth.setIaqSubmitUserId(cache_json.getString("submitUserId"));
imAuth.setIaqDescribe(cache_json.getString("describe"));
//插入审核队列表中
imAuthQueueDao.insert(imAuth);
return null;
}else{
//不需要审核,直接执行普通的增删改操作
return joinPoint.proceed();
}
}
/**
* @Description 获取字段名和字段值
* @Author 刘俊重
* @date 2017年7月6日
* @return Map<String,Object>
*/
private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws Exception {
Map<String,Object > map=new HashMap<String,Object>();
ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(cls);
pool.insertClassPath(classPath);
CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (attr == null) {
// exception
}
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++){
map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
}
return map;
}
}
本文参考文档:http://blog.csdn.net/thinkingt_t/article/details/68951703
阅读全文
3 0
- 自定义Spring的Aop切面类拦截业务请求,并获取到请求的参数名和参数值
- Spring AOP切面基础 实现请求参数的验证
- 使用 aop拦截 springMVC的controller并获取请求参数及返回结果
- 在spring的aop中获取自定义注解的参数值,即在切面中获取annotation的参数值
- Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理
- struts2拦截器 获得请求方法名和请求参数
- 关于请求参数的类型和获取请求参数方法
- asp.net自定义获取Get和Post请求的参数
- asp.net自定义获取Get和Post请求的参数
- Spring MVC 的请求参数获取
- Spring MVC 的请求参数获取
- Spring MVC 的请求参数获取
- Spring MVC 的请求参数获取
- Spring MVC 的请求参数获取
- Spring MVC请求参数获取的方法
- Spring MVC 集成 AOP,自定义注解,在切面获得方法参数,以及自定义注解的参数。
- 自定义的拦截器,封装公共参数 get请求
- 使用ProceedingJoinPoint获取当前请求的方法等参数——spring mvc拦截器
- bzoj 1565 植物大战僵尸
- SSM框架整合(IntellIj IDEA+Maven+Spring+SpringMVC+MyBatis)之Spring Framework
- 关于GC
- ShaderLab: Pass
- 权限认证
- 自定义Spring的Aop切面类拦截业务请求,并获取到请求的参数名和参数值
- ARKit是什么,现在在哪里呢?十二居是其demo吗?
- library cache lock和library cache pin
- lib和dll文件的区别和联系
- 架构师之路(十四)
- Android端与PC端同步绘画板(二)-适配手机和PC屏幕大小
- Python 包管理工具解惑
- 500 G JAVA视频网盘分享(JEECG开源社区)
- MySQL快速入门12----删除数据 & 备份还原 & 视图 & 事务 & 触发器