Java自定義註解 和 springMVC攔截器 配合使用記錄系統操作日誌的案例
阿新 • • 發佈:2019-02-20
自定義註解的用法, 好多人不知道, 在這裡, 程式碼的註釋中, 我已經詳細的介紹了,
另外就是很多人不知道自定義註解如何使用, 這裡配合springMVC攔截器, 做一個非常實用的案例.
案例: 記錄系統操作的日誌
首先是定義註解:
package cn.wxy.ssm.myAnnotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author wxy E-mail:[email protected] * @date 建立時間:2017年5月25日 下午5:05:22 * @version 1.0版本 * @company xxx科技公司 * @description 描述: 自定義註解: 這個註解是用在某一個成員方法上, 標識這個方法具體是增刪改查具體什麼內容 * */ @Target(ElementType.METHOD) //表明該註解對成員方法起作用 @Retention(RetentionPolicy.RUNTIME) //在編譯以後仍然起作用 @Documented //支援JavaDoc文件註釋 public @interface record { String actionType() default "預設動作型別"; //一般有增加, 刪除, 修改, 查詢 String businessLogic() default "預設業務邏輯"; }
然後, 在一個普通的ssm框架中來只用它, 新建一個web層的controller類:
package cn.wxy.ssm.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import cn.wxy.ssm.myAnnotation.record; /** * @author wxy E-mail:[email protected] * @date 建立時間:2017年5月25日 下午8:19:17 * @version 1.0版本 * @company xxx科技公司 * @description 描述: 測試自定義註解的controller層類 * */ @Controller public class TestAnnotationController extends BaseController { @RequestMapping(value = "wxy/testAnnotation.action") @record(actionType = "測試, 沒有做任何後臺增刪改",businessLogic="測試好不好使") public String test(){ System.out.println("執行完這行程式碼, 執行攔截器"); return "success"; } }
此時, 我們需要在springmvc的xml配置檔案中, 來構建攔截器, 攔截上面的controller
<!-- 配置攔截器, --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- 具體匹配原則可以百度 /**的意思是所有資料夾及裡面的子資料夾 /*是所有資料夾,不含子資料夾 /是web專案的根目錄 --> <bean class="cn.wxy.ssm.interceptor.OperationLogInteceptor"></bean> </mvc:interceptor> </mvc:interceptors>
建立上面配置的攔截器, 來繼承HandlerInteceptorAdaptor 或者實現 HandlerInteceptor 介面. 個人比較推薦前者.
package cn.wxy.ssm.interceptor;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import cn.wxy.ssm.myAnnotation.record;
/**
* @author wxy E-mail:[email protected]
* @date 建立時間:2017年5月25日 下午3:49:55
* @version 1.0版本
* @company xxx科技公司
* @description 描述: 繼承HandlerInterceptorAdapter, 重寫裡面的方法
* */
public class OperationLogInteceptor extends HandlerInterceptorAdapter {
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
* 預處理, 進行程式碼編寫, 安全控制等.
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("進入方法之前進行攔截");
return super.preHandle(request, response, handler);
}
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
* 返回處理, 這裡有機會修改ModelAndView
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//wxy筆記: 現在我要在這裡做的事情是: 新增日誌, 記錄進行的操作. 日誌的內容來源於我在
// 操作的方法中新增的 自定義註解, 因為自定義註解中有引數, 這些引數記錄的是操作的主要內容
// 我只要在這裡用反射將方法上自定義註解的內容拿出來, 新增到日誌裡面就行了/
System.out.println("攔截器執行.......");
HandlerMethod hm = (HandlerMethod) handler;//將其強轉過來
record record = hm.getMethodAnnotation(record.class);//拿到裡面的自定義註解物件//通過反射
if (record != null) {
//Map<String, String[]> params = request.getParameterMap();
//對params這個map集合的鍵進行遍歷
//Set<String> paramsKey = params.keySet();
//Iterator<String> it = paramsKey.iterator();
/*while (it.hasNext()) {
String key = (String) it.next();
}*/
String actionType = record.actionType();//拿到自定義註解中的欄位值 動作型別
String businessLogic = record.businessLogic();//拿到自定義註解中的欄位值 業務邏輯
String str = "動作型別是:" + actionType + " 業務邏輯是:" + businessLogic;
//執行日誌記錄
saveLog(str);
}
super.postHandle(request, response, handler, modelAndView);
}
/**
* 進行日誌記錄, 日誌一般分兩種:一種是資料庫(系統操作日誌),一種是寫入磁碟(系統執行日誌 log4j這類)
* 這裡我們這是屬於系統操作日誌, 需要存入資料庫, 但是為了演示, 這裡只打印到控制檯.
* @param str
*/
private void saveLog(String str) {
try {
System.out.println(str);
//真正開發中, 這裡傳遞日誌到資料庫, 操作失敗在catch中新增系統執行日誌
} catch (Exception e) {
e.printStackTrace();
}
}
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
* 後處理, 可以根據ex是否為null判斷是否發生了異常,進行日誌記錄。
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
}
/* (non-Javadoc)
*
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterConcurrentHandlingStarted(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
* 這個這裡不做研究暫時.
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
super.afterConcurrentHandlingStarted(request, response, handler);
}
}
最後我們來執行測試: 直接訪問即可:
http://localhost:8080/wxySSM/wxy/testAnnotation.action 檢視你們的Tomcat是否是8080, 另外, wxySSM 是專案名.
最後我把我建立的這個專案目錄結構截圖給大家參考, 以便更清晰學習.