日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java自定义注解annotation记录操作日志

發布時間:2025/3/12 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java自定义注解annotation记录操作日志 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

說到注解我們平常用的可以說非常多啦,說幾個常用的的注解 @RestController @Service @Autowired
這些都是我們平常使用spring框架最常見的注解了,我們只知道它們非常好用,使用@RestController 就能構建一個restful的控制器,@Service 這個是我們常用的mvc架構中的業務層使用的注解,將類交給spring容器管理,我們要用的話直接使用@Autowired就能將類自動注入。我們都知道用了這些注解非常的方便,今天我們自己也來寫一個自己的注解。

需求

一個項目,有些方法是需要被保護起來的,有寫方法是開放出來不需要保護的,比如登錄 注冊等 都不需要保護,解決方案有很多,今天我們就使用springboot的aop 和自定義注解來解決這個需求。
在創建自己的注解之前,了解一些注解的知識。
1.首先java jdk給我們提供了meta-annotation用于自定義注解的時候使用,這四個注解為:@Target,@Retention,@Documented 和@Inherited。

  • 第一個注解@Target
    @Target:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方),其源碼如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target {ElementType[] value(); }

我們可以看到它只有一個屬性值,是個枚舉類型的數組,我們進該枚舉類型看看

public enum ElementType {TYPE,//用于描述類、接口(包括注解類型) 或enum聲明FIELD, //用于描述成員變量;METHOD,//用于描述方法PARAMETER,//用于描述參數CONSTRUCTOR,//用于描述構造器LOCAL_VARIABLE,//用于描述局部變量;ANNOTATION_TYPE,//注解類型聲明 該注解可用于描述注解PACKAGE,//用于描述包TYPE_PARAMETER,//這個是jdk1.8后加入的類型 表示這個 Annotation 可以用在 Type 的聲明式前TYPE_USE//表示這個 Annotation 可以用在所有使用 Type 的地方(如:泛型,類型轉換等) }
  • 第二個注解@Retention
    @Retention:指定被描述的注解在什么范圍內有效。源碼如下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention {RetentionPolicy value(); }

可以看到,該注解也只有一個枚舉的屬性,我們進該枚舉類型看看

public enum RetentionPolicy {SOURCE,//表示描述程序編譯時CLASS,//在class文件中有效(即class保留RUNTIME//在運行時有效(即運行時保留) }
  • 第三個注解:@Documented

@Documented 是一個標記注解,木有成員,用于描述其它類型的annotation應該被作為被標注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }
  • 第四個注解 @Inherited

@Inherited 元注解是一個標記注解,@Inherited闡述了某個被標注的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用于一個class,則這個annotation將被用于該class的子類。

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention {RetentionPolicy value(); }

下面我們開始編寫我們自己的注解

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface IgnoreToken { } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface Log {String name() default ""; }

編寫aop攔截所有的controller請求

@Component @Aspect @Order(1) public class TokenAspect {@Autowiredprivate HttpServletRequest request;@Autowiredprivate HttpServletResponse response;@Autowiredprivate LoginController loginController;@Pointcut("within(com.niehziliang.annotation.demo.controller..*)")public void checkToken () {}@Before("checkToken()")public void checkToken (JoinPoint joinPoint) throws IOException {MethodSignature signature = (MethodSignature)joinPoint.getSignature();//獲取當前訪問的類方法Method targetMethod = signature.getMethod();//判斷是否是注解修飾的類,如果是則不需要校驗tokenif(!targetMethod.isAnnotationPresent(IgnoreToken.class)){String token = request.getParameter("token");if (null == token || "".equals(token)) {response.setCharacterEncoding("utf-8");response.setContentType("application/json; charset=utf-8");PrintWriter out = response.getWriter();out.print("token不能為空");out.flush();out.close();} else {if (!loginController.chkToken(token)) {response.setCharacterEncoding("utf-8");response.setContentType("application/json; charset=utf-8");PrintWriter out = response.getWriter();out.print("token不合法");out.flush();out.close();}}}}}

aop日志攔截

@Component @Aspect @Order(2) public class LogAspect {@Autowiredprivate HttpServletRequest request;@Autowiredprivate LoginController loginController;@Pointcut("@annotation(com.niehziliang.annotation.demo.annos.Log)")public void saveLog() {}@Around("saveLog()")public Object saveLog(ProceedingJoinPoint point) throws Throwable {long start = System.currentTimeMillis();MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();Log logAnnotation = method.getAnnotation(Log.class);String name = null;if (logAnnotation != null) {// 注解上的描述name = logAnnotation.name();}// 請求的方法名String className = point.getTarget().getClass().getName();String methodName = signature.getName();// 請求的方法參數值Object[] args = point.getArgs();LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();String[] paramNames = u.getParameterNames(method);String params = "";if (args != null && paramNames != null) {for (int i = 0; i < args.length; i++) {params += " " + paramNames[i] + ": " + args[i];}}String ip = IpUtils.getIpAddress(request);long time = System.currentTimeMillis() - start;StringBuffer log = new StringBuffer();log.append("注解上的name:").append(name).append("=======").append("請求的方法:").append(className).append(".").append(methodName).append("=====").append("請求參數:").append(params).append("=======").append("請求的ip:").append(ip).append("耗時:").append(time).append("ms");System.out.println(log.toString());loginController.saveLog(log.toString());return point.proceed();} }

編寫controller代碼, 登錄方法加了我自己定義的注解@IgnoreToken aop在攔截的時候判斷有我們自己定義注解就不會去校驗token啦,獲取密碼的方法則會進行token的校驗

@RestController public class LoginController {public static Map<String,String> map = new HashMap<>();public static List<String> logList = new ArrayList<>();public static Set<String> tokenSet = new HashSet<>();@RequestMapping(value = "login")@IgnoreToken@Logpublic String login(String userName,String password) {map.put(userName,password);//保存tokentokenSet.add(userName+password);//返回tokenreturn userName+password;}@RequestMapping(value = "query")@Log(name = "獲取密碼")public String getPassword(String userName) {//獲取用戶密碼return map.get(userName);}@RequestMapping(value = "logs")@Log(name = "獲取日志信息")public String getLogMap() {return JSON.toJSONString(logList);}}

下面我在瀏覽器輸入請求登錄地址進行登錄

// 登錄獲取token http://127.0.0.1:8080/login?userName=admin&password=adminadmin

不帶token訪問受保護的方法

// 獲取用戶密碼 http://127.0.0.1:8080/query?userName=admin

帶正確的token訪問受保護的犯法

// 獲取用戶密碼 http://127.0.0.1:8080/query?userName=admin&token=adminadminadmin 12

獲取用戶訪問日志信息

總結

以上是生活随笔為你收集整理的java自定义注解annotation记录操作日志的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 1000部啪啪未满十八勿入 | 手机在线看片你懂的 | 刘亦菲毛片 | 色黄啪啪网 | 亚洲精品高潮久久久久久久 | 91麻豆精品国产91久久久更新时间 | 美女福利视频导航 | 亚洲国产成人精品女人 | 红桃一区二区三区 | 日本aⅴ在线| 亚洲精品中文字幕乱码三区91 | 精品视频区 | a毛片 | av免费在线播放 | 精品一区二区亚洲 | 韩日av在线播放 | 秋霞av一区二区三区 | 小视频在线免费观看 | 吊侵犯の奶水授乳羞羞漫画 | 精品人妻无码一区二区三区蜜桃一 | 小香蕉av | 伊人网视频| 日韩精品1区 | 又爽av| 91重口味| 尤物精品在线观看 | 色综合久久久久综合体桃花网 | 一级国产片 | 三级黄在线观看 | 91香蕉国产在线观看软件 | 毛片福利视频 | 91一区在线观看 | 精品一区二区三区免费毛片 | 99国产精品自拍 | 亚洲不卡视频 | 少妇人妻偷人精品一区二区 | 天天干在线播放 | 好爽…又高潮了毛片免费看 | 精品国产免费观看 | 国产精品66| 成人亚洲一区 | 国产乱人乱精一区二视频国产精品 | 国产人妖ts重口系列网站观看 | 青青草原在线免费观看视频 | 狠狠艹| 亚洲第一免费播放区 | 图书馆的女友动漫在线观看 | 字幕网在线 | 精品视频久久久久久久 | 国产亚洲精 | 久久久精品91 | 人体毛片 | 中文字幕在线视频播放 | 国产这里只有精品 | 久久久久久一区二区三区 | 一区二视频| av手机 | 18一20岁毛毛片 | av三级网站 | 中国美女囗交视频 | 中文不卡在线 | 成年人网站黄 | 四虎三级 | 美女张开腿露出尿口 | 国产亚洲一区二区三区在线观看 | 国产露脸国语对白在线 | 最近的中文字幕 | 草av | 无遮挡aaaaa大片免费看 | 亚洲一区二区三区欧美 | 日韩一级中文字幕 | 精品爆乳一区二区三区 | 国产成人亚洲一区二区 | 黄色三级生活片 | chinesepron hd videos国产91 | 美女网站在线免费观看 | 午夜影院免费观看 | 国产在线观看中文字幕 | 成人激情小说网站 | 欧美日韩第一区 | 狠狠狠| 国内性爱视频 | 精品久久久噜噜噜久久久 | 91黄免费| 欧美视频在线观看一区二区三区 | 99视频国产精品免费观看a | 女人被狂躁60分钟视频 | 亚洲欧美日本另类 | 蜜桃av一区 | 在线国产一区 | 色噜噜影院 | 天天干天天插天天操 | 伊人久久五月 | 国产丝袜一区二区三区 | 亚洲伦理一区二区 | 亚洲色偷精品一区二区三区 | 婷婷国产精品 | 亚洲免费在线看 | 欧美精品一级二级三级 |