SpringAOP實現攔截Controller請求引數並輸出到日誌
一、實現的效果
請求:
http://localhost:8080/regist?username=king&age=12&password=123456
Controller:
@RestController
public class UserController {
@RequestMapping("/regist")
public Apiresult userRegister(@ModelAttribute User user) {
//....
return Apiresult.success("ok");
}
//user類包含username,age,password屬性,並重寫了tostring方法
}
控制檯
---------Path: /regist
---------ClassName: UserController
---------MethodName: userRegister
---------ParamList: {username:king,age:12,password:123456}
二、這樣做的原因
1.方便除錯,和前臺聯調可以直接看到引數
2.記錄資訊,方便回查。
三、實現程式碼
package com.kingboy.common.tools.log;
import lombok.extern.log4j.Log4j;
import org.aspectj .lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework .stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Objects;
import java.util.stream.Stream;
/**
* @author [email protected]
* @date 2017/11/19 下午10:10
* @desc 方法接收的引數日誌.
*/
@Log4j
@Aspect
@Component
@ConditionalOnProperty(name = "king.log.enabled", havingValue = "true")
public class ParamInfoLog {
@Pointcut("execution(* com.kingboy.controller..*(..))")
public void controller() { }
@Pointcut("execution(* com.kingboy.service..*(..))")
public void service() { }
@Pointcut("execution(* com.kingboy.repository..*(..))")
public void repository() { }
@Before("controller()")
public void controller(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Long count = Stream.of(signature.getMethod().getDeclaredAnnotations())
.filter(annotation -> annotation.annotationType() == RequestMapping.class)
.count();
String requestPath = count >= 1 ? signature.getMethod().getAnnotation(RequestMapping.class).value()[0] : "";
String info = String.format("path:%s | %s", requestPath, getMethodInfo(point));
log.info(info);
}
@Before("service()")
public void service(JoinPoint point) {
log.info(String.format("%s", getMethodInfo(point)));
}
@Before("repository()")
public void repository(JoinPoint point) {
log.info(String.format("%s", getMethodInfo(point)));
}
private String getMethodInfo(JoinPoint point) {
String className = point.getSignature().getDeclaringType().getSimpleName();
String methodName = point.getSignature().getName();
String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
StringBuilder sb = null;
if (Objects.nonNull(parameterNames)) {
sb = new StringBuilder();
for (int i = 0; i < parameterNames.length; i++) {
String value = point.getArgs()[i] != null ? point.getArgs()[i].toString() : "null";
sb.append(parameterNames[i] + ":" + value + "; ");
}
}
sb = sb == null ? new StringBuilder() : sb;
String info = String.format("class:%s | method:%s | args:%s", className, methodName, sb.toString());
return info;
}
}
更新時間 2018-09-06 00:50:25
根據專案實際情況進行了一定的優化,可以參考以下程式碼,日誌使用的是lombok提供的註解,更換為自己的log即可
@Slf4j
@Aspect
@Component
public class ParamLogger {
@Pointcut("execution(* com.kimzing.provider.web..*(..))")
public void controller() {
}
@Pointcut("execution(* com.kimzing.provider.service..*(..))")
public void service() {
}
@Pointcut("execution(* com.kimzing.provider.mapper..*(..))")
public void repository() {
}
@Before("controller()")
public void controller(JoinPoint point) {
}
@Around("controller()")
public Object around(ProceedingJoinPoint point) throws Throwable {
String uuid = RandomUtil.uuid();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
log.info("\n\t請求標識: {}\n\t請求IP: {}\n\t請求路徑: {}\n\t請求方式: {}\n\t方法描述: {}\n\t請求引數: {}",
uuid, request.getRemoteAddr(), request.getRequestURL(), request.getMethod(),
getMethodInfo(point), JSONObject.toJSONString(request.getParameterMap()));
long startTime = System.currentTimeMillis();
Object[] args = point.getArgs();
Object retVal = point.proceed(args);
long endTime = System.currentTimeMillis();
log.info("\n\t請求標識: {} \n\t執行時間: {} ms \n\t返回值: {}", uuid, endTime - startTime, JSONObject.toJSONString(retVal));
return retVal;
}
@Before("service()")
public void service(JoinPoint point) {
log.info("\n\tservice method: {}", getMethodInfo(point));
}
@Before("repository()")
public void repository(JoinPoint point) {
log.info("\n\trepository method: {}", getMethodInfo(point));
}
private String getMethodInfo(JoinPoint point) {
ConcurrentHashMap<String, Object> info = new ConcurrentHashMap<>(3);
info.put("class", point.getTarget().getClass().getSimpleName());
info.put("method", point.getSignature().getName());
String[] parameterNames = ((MethodSignature) point.getSignature()).getParameterNames();
ConcurrentHashMap<String, String> args = null;
if (Objects.nonNull(parameterNames)) {
args = new ConcurrentHashMap<>(parameterNames.length);
for (int i = 0; i < parameterNames.length; i++) {
String value = point.getArgs()[i] != null ? point.getArgs()[i].toString() : "null";
args.put(parameterNames[i], value);
}
info.put("args", args);
}
return JSONObject.toJSONString(info);
}
}
相關推薦
SpringAOP實現攔截Controller請求引數並輸出到日誌
一、實現的效果 請求: http://localhost:8080/regist?username=king&age=12&password=123456 Controller: @RestController public cl
Android 攔截WebView請求,並加入或修改引數(GET)
今天遇到一個需求,H5內部呼叫登入請求,然後手機端給他拼接使用者的ID及其他訊息 這個WebView提供了方法shouldInterceptRequest 下面程式碼,只是簡單demo,請求方式是get mWebView.setWebViewClient(new WebViewClien
自定義Spring的Aop切面類攔截業務請求,並獲取到請求的引數名和引數值
/** * @author 劉俊重 * @Description 稽核校驗 * 所有的service業務方法都會先走這個方法, * 先判斷本操作需不需要稽核,如果需要稽核則插入稽核隊列表, * 不需要稽核則直接插入相關業務表 * @date 2017年7月5日 */ @Component @As
spring boot 攔截器實現攔截前端請求並返回json至前端頁面
攔截器主體 import com.alibaba.fastjson.JSONObject; import com.ufclub.vis.constant.StatusConstant; import com.ufclub.vis.entity.BaseResult; imp
FileReader實現讀取文件內容並輸出到屏幕上
null tac otf style ace 讀取 編碼 use unicode編碼 FileReader與FileInputStream都是從文件讀數據,而前者一次讀一個字符,後者一次讀一個字節(在Unicode編碼環境下1個字符=2個字節) package com.j
關於Retrofit2+Okhttp3實現統一新增請求引數和重定向
Android開發中難免會遇到一些比較“不友好”的服務端介面。比如以前遇到的json資料中,某個欄位偶爾為Object,偶爾為List… 最近遇到的一個問題就是:所有請求介面都要增加一個token引數… 並且token引數有可能過期,比如請求某一條介面,如果token失效則在該請求
springMvc實現攔截特定請求判斷用戶是否登錄
攔截 定義 就會 操作 結束 詳細 htm object 哪裏 dUI與一 對於一個新聞站點來說除了評論功能其他請求都不用攔截 所以試著給springmvc框架增加一個用戶登錄的攔截功能 0基礎需要明白 登錄攔截是怎麽實現的 由誰實現攔截 在哪裏配置 用戶的登錄狀態保存在哪
自實現後臺動態請求引數:getParam
/** * 得到request物件 */ public HttpServletRequest getRequest() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHo
Java實現攔截HTTP請求的幾種方式
在Java的服務端開發當中,攔截器是很常見的業務場景,這裡對Java開發當中幾種常見的攔截器的實現方式進行記錄和分析。案例說明基於Spring Boot環境。一:實現javax.servlet.Filter介面(使用過濾器方式攔截請求)import org.springfra
spring aop攔截Controller做引數校驗
在專案中,我們會對入參做校驗,這些引數的校驗邏輯我們會寫很多次.能不能將這些引數的校驗邏輯提出來呢?答案是可以.Spring 有自己的validate工具方法,我個人感覺不是太好遠,想自己定製更加契合自己專案的校驗機制.經過哆哆嗦嗦的研究,有點結果,現在貼出來
Spring Boot 攔截器 請求引數MD5簽名校驗
攔截器定義 /** * 攔截器 請求引數簽名校驗 * Created by jiyang on 14:47 2017/12/14 */ @Component @Slf4j public class ParameterInterceptor implements Han
如何啟用設定org.slf4j.Logger列印並輸出日誌
org.slf4j.Logger列印並輸出日誌 在resouces目錄下面新建logback.xml(此為Logback推薦目錄) 內容配置如下 logback 分為兩種設定: 1. 輸出到控制
mybatis攔截器的使用(輸出日誌或sql語句)
2016-08-28 14:48:02 [ http-apr-8888-exec-8:70630 ] - [ INFO ] ---------------------------------------------- 2016-08-28 14:48:02 [ http-apr-8888-exec-8
linux java程序後臺啟動,並輸出日誌到指定檔案中
linux 中讓java程序以後臺形式執行,並輸出日誌到指定檔案中。 舉例: 現在linux /home/pro/application/monitor下有一個jar包叫zop-monitor-web
使用 aop攔截 springMVC的controller並獲取請求引數及返回結果
有人說使用aop攔截不到springMVC的controller,一般出現此種情況大多是由於配置錯誤造成,不廢話直接進入主題: 1、applicationContext.xml 配置掃描 除@controller外的bean <context:component
AOP之獲取Controller請求(Request)、返回(Response)引數、報錯資訊實現日誌記錄
需求:為系統中所有的提交,修改,刪除等等操作(除查詢以外的所有操作)做日誌記錄,記錄的內容包括:請求引數,返回引數,如果報錯就儲存報錯資訊。日誌要新增一個日誌型別。 方案:最好的選擇就是用註解標記切點,用AOP實現此需求。 一、準備 版本: J
實現從命令列引數輸入兩個字串型別的數值,並計算輸出兩個數值的和。 [必做題]
import java.io.UnsupportedEncodingException; import java.util.Scanner; public class ZiFuChuanHe { public static void main(String[] args) throws
使用攔截器獲取請求引數資訊並寫入日誌
前言 使用攔截器獲取請求的引數,ip地址等等資訊,然後寫入日誌更加方便後期異常的維護。 2.程式碼例項 public class RequestParamInfoIntorceptor extends HandlerInterceptorAdapter
SpringAOP攔截Controller,Service實現日誌管理(自定義註解的方式)
首先我們為什麼需要做日誌管理,在現實的上線中我們經常會遇到系統出現異常或者問題。這個時候就馬上開啟CRT或者SSH連上伺服器拿日子來分析。受網路的各種限制。於是我們就想為什麼不能直接在管理後臺檢視報錯的資訊呢。於是日誌管理就出現了。 其次
SpringAOP攔截Controller,Service實現日誌管理(自定義註解的方式)(轉載)
http://langgufu.iteye.com/blog/2235556 首先我們為什麼需要做日誌管理,在現實的上線中我們經常會遇到系統出現異常或者問題。這個時候就馬上開啟CRT或者SSH連上伺服器拿日子來分析。受網路的各種限制。於是我們就想為什麼不能直接在