AOP Aspect 统一日志、异常处理、数据格式

 

package com.gsww.chis.aop;

import java.util.Arrays;

import com.google.common.base.Throwables;
import com.gsww.chis.pojo.pacs.PacswsLog;
import com.gsww.chis.service.pacs.PacswsLogService; import com.gsww.chis.util.TimeHelper; 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.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * 系统日志 * @author fenglanglang * */ @Aspect @Component public class WebServiceLogAspect { private static final Logger logger = LoggerFactory.getLogger(WebServiceLogAspect.class); @Autowired private PacswsLogService pacswsLogService; @Pointcut("execution(public * com.gsww.chis.webservice.*.*(..)) && @annotation(com.gsww.chis.annotation.WebServiceLog)") public void Pointcut() { } @Around("Pointcut()") public Object around(ProceedingJoinPoint point) { PacswsLog log = new PacswsLog(); log.setRst("T"); log.setTime(TimeHelper.getCurrentTime()); MethodSignature signature = (MethodSignature) point.getSignature(); // 请求的方法名 String methodName = signature.getName(); log.setHisMethod(methodName); // 请求的参数 Object[] args = point.getArgs(); log.setParamsIn(Arrays.toString(args)); // 执行方法 Object result =null; long beginTime = System.currentTimeMillis(); try { result = point.proceed(); log.setTimeConsuming(System.currentTimeMillis() - beginTime); log.setParamsOut(result.toString()); } catch (Throwable e) { if("RisCheckInfo".equals(methodName)){ result = "-1"+e.getMessage()+""; }else{ result = "-1"+e.getMessage()+""; } log.setRst("F"); log.setParamsOut(result.toString()); log.setTimeConsuming(0L); logger.error("请求异常:请求方法:{}, 异常信息:{}",methodName,Throwables.getStackTraceAsString(e)); } saveWebServiceLog(log); return result; } /** * 保存接口日志 * @param pacswsLog */ private void saveWebServiceLog(PacswsLog pacswsLog){ try{ pacswsLogService.save(pacswsLog); }catch(Exception e){ logger.error("请求异常:请求方法:{}, 异常信息:{}","saveWebServiceLog",Throwables.getStackTraceAsString(e)); } } } 
package com.gsww.bhis.common.aop;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date; import javax.servlet.http.HttpServletRequest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; 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.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.google.common.base.Throwables; /** * @author fenglanglang * @see * */ @Aspect //声明是个切面 @Component public class LogAspect { private static final Logger logger = LogManager.getLogger("LogConfig"); //切点 @Pointcut("execution(public * com.gsww.bhis..controller.*.*(..))") public void Pointcut(){} /** * * doAround:(环绕方法,统一日志处理). 
* * @author fenglanglang * @param joinPoint * @return * @throws Throwable */ @Around("Pointcut()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { long beginTime = System.currentTimeMillis();//1、开始时间 ServletRequestAttributes requestAttr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes(); String uri = requestAttr.getRequest().getRequestURI(); logger.info("开始计时: {} URI: {}", new Date(),uri); //访问目标方法的参数 可动态改变参数值 Object[] args = joinPoint.getArgs(); //方法名获取 String methodName = joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName(); logger.info("请求方法:{}, 请求参数: {}", methodName, Arrays.toString(args)); //可能在反向代理请求进来时,获取的IP存在不正确行 这里直接摘抄一段来自网上获取ip的代码 logger.info("请求ip:{}", getIpAddr(requestAttr.getRequest())); //调用实际方法 Object object = joinPoint.proceed(); logger.info("请求返回值:{}",object); long endTime = System.currentTimeMillis(); logger.info("结束计时: {}, URI: {},耗时:{}", new Date(),uri,endTime - beginTime); return object; } /** * * afterThrowable:(统一异常处理).
* * @author fenglanglang * @param e */ @AfterThrowing(pointcut="Pointcut()",throwing="e") public void afterThrowable(JoinPoint joinPoint,Throwable e) { //方法名获取 String methodName = joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName(); logger.error("请求异常:请求方法:{}, 异常信息:{}",methodName,Throwables.getStackTraceAsString(e)); } /** * * getIpAddr:(获取ip).
* * @author fenglanglang * @param request * @return */ public static String getIpAddr(HttpServletRequest request) { String ipAddress = null; try { ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if (ipAddress.equals("127.0.0.1")) { // 根据网卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { logger.error("获取ip异常:{}" ,Throwables.getStackTraceAsString(e)); } ipAddress = inet.getHostAddress(); } } // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } } catch (Exception e) { ipAddress = ""; } return ipAddress; } }
package com.gsww.bhis.common.aop;

import java.lang.annotation.Annotation;
import java.util.LinkedHashMap;

import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import com.alibaba.fastjson.JSON; import com.google.common.base.Throwables; import com.gsww.bhis.common.util.GlobalResponse; /** * * 类名: GlobalResponseHandler 
* 功能: 正常请求统一响应数据格式
* 创建时间: 2018年9月6日 上午10:33:32
* * @author fenglanglang * @version */ @ControllerAdvice(annotations={RestController.class,Controller.class}) public class GlobalResponseHandler implements ResponseBodyAdvice<Object>{ /** * * 拦截没有进行统一数据格式的方法 * @see org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice#supports(org.springframework.core.MethodParameter, java.lang.Class) */ @Override public boolean supports(MethodParameter returnType, Class> converterType) { //swagger2 api 数据不进行转换 ,否则api界面会出错 String ngp = returnType.getNestedGenericParameterType().toString(); if(ngp.indexOf("swagger")>=0){ return false; } Annotation[] ano = returnType.getMethodAnnotations(); for(Annotation a:ano){ if(a.annotationType().getName().indexOf("ApiIgnore")>=0){ return false; } } //已经是标准格式的数据不进行转换 String returnTypeName = returnType.getParameterType().getName(); return !"com.gsww.bhis.common.util.GlobalResponse".equals(returnTypeName); } @SuppressWarnings("unchecked") @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body == null) { return JSON.toJSONString(GlobalResponse.success(null)); } //权限校验特殊处理 if(body instanceof LinkedHashMap){ LinkedHashMap hashMapBody = (LinkedHashMap)body; Integer status = (Integer)hashMapBody.get("status"); Object message = hashMapBody.get("message"); if(status != null && message != null){ return GlobalResponse.fail(message.toString(),status); } } //防止classCaseExceptiin https://my.oschina.net/u/1757225/blog/1543715 if(body instanceof String) { return JSON.toJSONString(GlobalResponse.success(body)); } //不是json类型类型的返回值 if(!selectedContentType.includes(MediaType.APPLICATION_JSON)){ return body; } return GlobalResponse.success(body); } /** * * handlerThrowable:(异常时返回统一格式).
* * @author fenglanglang * @param e * @return */ @ResponseBody @ResponseStatus(HttpStatus.OK) @ExceptionHandler({Throwable.class}) public GlobalResponse handlerThrowable(Throwable e){ return GlobalResponse.fail(Throwables.getStackTraceAsString(e), 500); } }
package com.gsww.bhis.common.util;

import java.io.Serializable;

/**
 * 
 * @author fenglanglang
 * 数据格式
 * @param  */ public class GlobalResponse<T> implements Serializable{ private static final long serialVersionUID = 8696541815421373761L; private Boolean rst = false; private T data; private Integer errorCode; private String errorMsg; public GlobalResponse() { super(); } public GlobalResponse(T data,Boolean rst) { super(); this.rst = rst; this.data = data; } public static  GlobalResponse success(T data){ return new GlobalResponse(data,true); } public static  GlobalResponse fail(String errorMsg,Integer errorCode){ GlobalResponse gr = new GlobalResponse(); gr.setErrorCode(errorCode); gr.setErrorMsg(errorMsg); gr.setRst(false); return gr; } public Boolean isRst() { return rst; } public void setRst(Boolean rst) { this.rst = rst; } public T getData() { return data; } public void setData(T data) { this.data = data; } public Integer getErrorCode() { return errorCode; } public void setErrorCode(Integer errorCode) { this.errorCode = errorCode; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } @Override public String toString() { return "GlobalResponse [rst=" + rst + ", data=" + data + ", errorCode=" + errorCode + ", errorMsg=" + errorMsg + "]"; } } 

 

完全参考自

AOP Aspect 统一日志、异常处理、数据格式==》https://my.oschina.net/langgege/blog/3025492

 

你可能感兴趣的:(AOP Aspect 统一日志、异常处理、数据格式 )