當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
Springboot使用AOP记录请求日志和返回数据
生活随笔
收集整理的這篇文章主要介紹了
Springboot使用AOP记录请求日志和返回数据
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
首先是日志表結構
DROP TABLE IF EXISTS `protal_logvo`; CREATE TABLE `protal_logvo` (`id` varchar(255) NOT NULL,`ip` varchar(255) DEFAULT NULL,`url` varchar(255) DEFAULT NULL,`httpMethod` varchar(255) DEFAULT NULL,`classMethod` varchar(255) DEFAULT NULL,`requestParams` varchar(255) CHARACTER SET utf8 DEFAULT NULL,`result` text CHARACTER SET utf8,`timeCost` int(10) DEFAULT NULL,`crsj` timestamp NULL DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;依賴??fastjson和lombok只是用來優(yōu)化格式的,核心是aop
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.4</version><scope>provided</scope></dependency>?1.核心代碼??
獲取請求參數(shù)寫了兩個方法,建議用第二個,第一個經(jīng)過嘗試有失敗的風險。
import com.alibaba.fastjson.JSONObject; import com.sws.link.apps.zs.service.LogIntoService; import com.sws.link.apps.zs.util.IdReidsIncr; import com.sws.link.apps.zs.util.TimeUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.CodeSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Array; import java.util.*;/*** @author qushen* @date 2021/5/4 15:09*/@Slf4j @Aspect @Component public class LogAspect {@Autowiredprivate LogIntoService logIntoService;@Autowiredprivate IdReidsIncr idreidsincr; //redis注入,可忽略/*** 切入點*/// @Pointcut("execution(public * com.sws.link.apps.zs.controller..*.*(..))")//切入點描述,這個是controller包的切入點 指定的controller@Pointcut("@within(org.springframework.stereotype.Controller) || @within(org.springframework.web.bind.annotation.RestController)") //全局的controller//切入點描述 這個是controller包的切入點public void aspect() {}/*** 環(huán)繞操作* 記錄請求日志*/@Around("aspect()")public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {// 獲取請求參數(shù)ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 記錄執(zhí)行時間long startTime = System.currentTimeMillis();//處理請求Object result = joinPoint.proceed();//記錄日志try {HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();int logid = (int) idreidsincr.incr("log_vo", 1); //redis自增,可忽略LogVO logVo = LogVO.builder()//id.id(logid)//請求ip.ip(HttpUtils.getIpAddress(request))//請求路徑.url(request.getRequestURL().toString())//處理的類.classMethod(String.format("%s.%s", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName()))//處理的方法類型.httpMethod(request.getMethod())//請求參數(shù).requestParams(getRequestParam2())//返回結果.result(result)//耗時.timeCost(System.currentTimeMillis() - startTime)//插入時間.crsj(TimeUtil.getNowTimeDate())//build.build();//執(zhí)行插入數(shù)據(jù)庫操作logIntoService.saveLogVo(logVo);} catch (Exception e) {}return result;}/*** 獲取請求參數(shù)---根據(jù)getArgs()---第一個方法*/private Object[] getRequestParam(ProceedingJoinPoint joinPoint) {Object[] args = joinPoint.getArgs();Object[] arguments = new Object[args.length];for (int i = 0; i < args.length; i++) {if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {//ServletRequest,ServletResponse,MultipartFile不能序列化continue;}arguments[i] = args[i];}return arguments;}/*** 獲取請求參數(shù)---根據(jù)request--第二個方法*/private String getRequestParam2() {ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = servletRequestAttribute.getRequest();Map<String, String[]> map = request.getParameterMap();Set<Map.Entry<String, String[]>> keys = map.entrySet();Iterator<Map.Entry<String, String[]>> i = keys.iterator();StringBuffer sb = new StringBuffer();while (i.hasNext()){Map.Entry<String, String[]> it = i.next();sb.append(it.getKey()+"="+Arrays.toString(it.getValue()));}return sb.toString();}}2.工具類
import javax.servlet.http.HttpServletRequest;/*** @author qushen* @date 2021/5/3 0:16*/ public class HttpUtils {private static final String SIGN = ",";private static final String STR_UNKNOWN = "unknown";/*** 獲取請求ip*/public static String getIpAddress(HttpServletRequest request) {String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || STR_UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || STR_UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || STR_UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}if (ip == null || ip.length() == 0 || STR_UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (ip == null || ip.length() == 0 || STR_UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("X-Real-IP");}if (ip.contains(SIGN)) {return ip.split(SIGN)[0];} else {return ip;}}}3.日志實體類
import lombok.Builder; import lombok.Data;import java.util.Date;/*** @author qushen* @date 2021/5/4 15:05*/ @Data @Builder public class LogVO {// idprivate int id;// ipprivate String ip;// urlprivate String url;// 請求方式 GET POSTprivate String httpMethod;// 類方法private String classMethod;// 請求參數(shù)private String requestParams;// 返回參數(shù)private Object result;// 接口耗時private Long timeCost;// 插入時間private String crsj;}日志記錄的信息如下:
總結
以上是生活随笔為你收集整理的Springboot使用AOP记录请求日志和返回数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 迷你世界怎样删除账号
- 下一篇: Spring Boot配置多数据源