@ControllerPointcut 注解:
/**
系统级别的controller层自定义注解
* <br>拦截Controller
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})//作用于参数或方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ControllerPointcut {
String description() default "";
}
调用自定义注解:
/**
* 创建应用
*/
@ResponseBody
@ControllerPointcut(description = "创建应用")
@RequestMapping(value = "/createApplication", method = RequestMethod.POST)
public JSONObject createApplication(@RequestBody ApplicationVo applicationVo) throws HttpRequestException, PaasException {
return ApplicationServiceUtils.createApplication(applicationVo);
}
/**
* 修改应用
*/
@ResponseBody
@ControllerPointcut(description = "修改应用")
@RequestMapping(value = "/modifyApplication", method = RequestMethod.POST)
public JSONObject modifyApplication(@RequestBody ApplicationVo applicationVo) throws HttpRequestException, PaasException {
return ApplicationServiceUtils.modifyApplication(applicationVo);
}
package com.ivr.callcenter.aop;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSONObject;
import com.ivr.callcenter.exception.BaseException;
import com.ivr.common.Constant;
import com.ivr.utils.GeneralDto;
import com.ivr.utils.JsonResponseUtil;
/**
* AspectJ 接管 web异常,返回值, 权限校验等
* 配置<aop:aspectj-autoproxy proxy-target-class="true"/>
*/
@Aspect
@Component
public class ControllerAspect {
private static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
/**
* controller层切入点
* 对应方法上使用 @ResponseBody, 防止出现 url mapping 找不到的警告
* response 由本类接管,spring mvc 的ResponseBodyxxxx不会处理@ResponseBody
*/
@Pointcut("@annotation(com.sobot.call.callCenter.aop.ControllerPointcut)")
public void controllerAspect() {
logger.info(" 进入AOP 控制");
}
@Around("controllerAspect()")
public void aroundAdvise(ProceedingJoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getResponse();
GeneralDto<Object> gendto = new GeneralDto<Object>();
gendto.setRetCode(Constant.SUCCESS_CODE);
gendto.setRetMsg(Constant.SUCCESS_MSG);
Object retObject = gendto;
try {
String method = joinPoint.getTarget().getClass().getName() + "."
+ joinPoint.getSignature().getName() + "()";
String desc = getControllerMethodDescription(joinPoint);
logger.info("------------------------------------------------------------------");
logger.info("请求方法:{}", method);
logger.info("请求参数:{}", getControllerArgs(joinPoint));
logger.info("方法描述:{}" , desc);
logger.info("请求 IP:{}", getIpAddr(request));
Object obj = joinPoint.proceed();
//System.out.println("obj : "+obj);
if (obj != null){
if(obj instanceof JSONObject){
retObject = obj;
}
//SONObject data = (JSONObject) obj;
// if (!data.isEmpty()){
// gendto.setItem(data);
//}
}
logger.info("{}:报文成功返回", desc);
} catch (Exception e) {
gendto.setRetCode(Constant.SYSERROR_CODE);
gendto.setRetMsg(Constant.SYSERROR_MSG + " " + e.getMessage());
if (e instanceof BaseException) {
BaseException base = (BaseException) e;
gendto.setRetCode(base.getCode());
gendto.setRetMsg(base.getMessage());
}
logger.error(e.getMessage(), e);
} catch (Throwable throwable) {
gendto.setRetCode(Constant.SYSERROR_CODE);
gendto.setRetMsg(Constant.SYSERROR_MSG + " " + throwable.getMessage());
logger.error(throwable.getMessage(), throwable);
} finally {
JsonResponseUtil.write(response, retObject);
}
}
public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.indexOf(",") != -1) {
ip = ip.split(",")[0];
}
return ip;
}
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param joinPoint 切点
* @return 方法描述
* @throws Exception
*/
private String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
//获取目标类名
String targetName = joinPoint.getTarget().getClass().getName();
//获取方法名
String methodName = joinPoint.getSignature().getName();
//获取相关参数
Object[] arguments = joinPoint.getArgs();
Class[] paramTypes = new Class[arguments.length];
for (int i = 0; i < arguments.length; i++) {
paramTypes[i]=arguments[i].getClass();
}
//生成类对象
Class targetClass = Class.forName(targetName);
Method method = targetClass.getMethod(methodName, paramTypes);
String description = method.getAnnotation(ControllerPointcut.class).description();
return description;
}
/**
* 获取Controller 方法参数
*
* @param joinPoint 切点
* @return 方法描述
* @throws Exception
*/
private String getControllerArgs(JoinPoint joinPoint) throws Exception {
//获取相关参数
Object[] arguments = joinPoint.getArgs();
StringBuilder parames = new StringBuilder();
for (int i = 0; i < arguments.length; i++) {
parames.append(arguments[i].toString());
parames.append(" ");
}
if (parames.length()>0){
parames.deleteCharAt(parames.length()-1);
}
return parames.toString();
}
}
注意:
1、如果是springboot项目一定要添加:import 扫描注解类
或者启动类上加
@ImportResource("classpath:applicationContext.xml") 加扫描文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 启用解析注解的处理器 -->
<context:annotation-config/>
<context:component-scan base-package="com.springboot.annotation"/>
</beans>
2、pom中需要添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
3、applicatio.yuml 中添加