轉載: https://my.oschina.net/langgege/blog/3025492
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 = "<Response><list></list><ResultCode>-1</ResultCode><ResultContent>"+e.getMessage()+"</ResultContent></Response>"; }else{ result = "<Response><ResultCode>-1</ResultCode><ResultContent>"+e.getMessage()+"</ResultContent></Response>"; } 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:(環繞方法,統一日志處理). <br/> * * @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:(統一異常處理). <br/> * * @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). <br/> * * @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 <br/> * 功能: 正常請求統一響應數據格式 <br/> * 創建時間: 2018年9月6日 上午10:33:32 <br/> * * @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<? extends HttpMessageConverter<?>> 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<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body == null) { return JSON.toJSONString(GlobalResponse.success(null)); } //權限校驗特殊處理 if(body instanceof LinkedHashMap){ LinkedHashMap<String, Object> hashMapBody = (LinkedHashMap<String, Object>)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:(異常時返回統一格式). <br/> * * @author fenglanglang * @param e * @return */ @ResponseBody @ResponseStatus(HttpStatus.OK) @ExceptionHandler({Throwable.class}) public <T> GlobalResponse<T> handlerThrowable(Throwable e){ return GlobalResponse.fail(Throwables.getStackTraceAsString(e), 500); } }
package com.gsww.bhis.common.util; import java.io.Serializable; /** * * @author fenglanglang * 數據格式 * @param <T> */ 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 <T> GlobalResponse<T> success(T data){ return new GlobalResponse<T>(data,true); } public static <T> GlobalResponse<T> fail(String errorMsg,Integer errorCode){ GlobalResponse<T> gr = new GlobalResponse<T>(); 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 + "]"; } }
