SpringBoot使用自定义注解+拦截器 实现日志记录

来源:互联网 发布:淘宝商城会员 编辑:程序博客网 时间:2024/06/06 00:25

一.自定义注解

package com.xiaojukeji.common.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface SystemLogAnnotation {String value();}

(1)@Target注解是标注这个类它可以标注的位置,常用的元素类型(ElementType):

public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ // TYPE类型可以声明在类上或枚举上或者是注解上 TYPE, /** Field declaration (includes enum constants) */ // FIELD声明在字段上 FIELD, /** Method declaration */ // 声明在方法上 METHOD, /** Formal parameter declaration */ // 声明在形参列表中 PARAMETER, /** Constructor declaration */ // 声明在构造方法上 CONSTRUCTOR, /** Local variable declaration */ // 声明在局部变量上 LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER, /** * Use of a type * * @since 1.8 */ TYPE_USE}
(2)@Retention注解表示的是本注解(标注这个注解的注解保留时期)

public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ // 源代码时期 SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ // 字节码时期, 编译之后 CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ // 运行时期, 也就是一直保留, 通常也都用这个 RUNTIME}
(3)@Documented是否生成文档的标注, 也就是生成接口文档是, 是否生成注解文档


二.拦截器类

package com.xiaojukeji.ecm.interceptor;import java.lang.reflect.Method;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import nl.bitwalker.useragentutils.UserAgent;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.xiaojukeji.common.annotation.SystemLogAnnotation;import com.xiaojukeji.dao.model.SystemLog;import com.xiaojukeji.ep.ip.common.model.AdUser;import com.xiaojukeji.ep.ip.common.utils.ContextHolder;import com.xiaojukeji.service.ERPService;import com.xiaojukeji.service.SystemLogService;/** * <p>Description: [ecm用户操作日志拦截器]</p> * Created on 2017年11月23日 下午12:05:35 * @author  <a href="mailto: 15175223269@163.com">全冉</a> * @version 1.0  * Copyright (c) 2017 全冉公司 */public class EcmSysemLogInterceptor extends HandlerInterceptorAdapter { //此处不继承这个适配器,用implements HandlerInterceptor也行@Autowiredprivate ERPService erpService;@Resourceprivate SystemLogService systemLogService;/** * 在请求处理之前进行调用(Controller方法调用之前),只有返回true才会继续向下执行,返回false取消当前请求 */@Overridepublic boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object handler) throws Exception {// 将handler强转为HandlerMethod        HandlerMethod handlerMethod = (HandlerMethod) handler;        // 从方法处理器中获取出要调用的方法        Method method = handlerMethod.getMethod();        // 获取出方法上的Access注解        SystemLogAnnotation systemLogAnnotation = method.getAnnotation(SystemLogAnnotation.class);        if (systemLogAnnotation == null) {        // 如果注解为null, 说明不需要拦截, 直接放过        return true;        }        if (systemLogAnnotation != null) {        // 如果自定义注解不为空, 则取出配置值        String value = systemLogAnnotation.value();        // 保存操作日志        addSystemLog(value);        return true;        }return false;}/** * <p>Discription:[保存操作日志]</p> * Created on 2017年11月20日 下午3:07:33 * @param operationContent 操作内容 * @author:[全冉] */public void addSystemLog(String operationContent) {// 获取此次请求的request对象HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();// 员工号String employeeNum = adUser.getEmplID();// 员工姓名String employeeName = adUser.getEmplName();// 邮箱String employeeEmail = adUser.getEmailAddr();// 浏览器标标识String webIdentifiy = getBrowserInfo(request);SystemLog systemLog = new SystemLog();systemLog.setEmployeeNum(employeeNum);systemLog.setEmployeeName(employeeName);systemLog.setEmployeeEmail(employeeEmail);systemLog.setOperationContent(operationContent);systemLog.setWebIdentifiy("浏览器" + webIdentifiy);systemLogService.save(systemLog);}/** * <p>Discription:[根据request获取前台浏览器标识]</p> * Created on 2017年11月20日 下午7:30:08 * @param request request对象 * @return String 浏览器标识 * @author:[全冉] */private static String getBrowserInfo(HttpServletRequest request) {UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));String browserInfo = userAgent.getBrowser().toString();return browserInfo;}/** * 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作) */@Overridepublic void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception {}/** * 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后) */@Overridepublic void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3) throws Exception {}}
三.将拦截器注册到拦截器链

package com.xiaojukeji.ecm.interceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/** * web MVC 适配器 * 配置拦截器、处理静态资源、配置消息转换等 * Created by camelot on 2017/10/17. */@Componentpublic class EcmWebMvcConfig extends WebMvcConfigurerAdapter {@Bean    public EcmSysemLogInterceptor ecmSysemLogInterceptor(){        return new EcmSysemLogInterceptor();    }    /**     * 注册拦截器     * @param registry 拦截器注册中心     */    @Override    public void addInterceptors(InterceptorRegistry registry) {    // 注册ecm系统操作日志拦截器(凡加了自定义注解的方法都会添加用户操作日志),拦截所有请求    registry.addInterceptor(ecmSysemLogInterceptor()).addPathPatterns("/**");// 连接器里有@Autowire或者@Resource注入的属性就这么用        // 注册ecm系统请求拦截器(不拦截登录、注销、回调请求,其他都拦截)        registry.addInterceptor(new EcmRequestInterceptor()).addPathPatterns("/**");// 连接器里没有@Autowire或者@Resource注入的属性就这么用        super.addInterceptors(registry);    }    /**     * 静态资源处理     * 将请求的如css、html等静态资源定位到项目指定位置     * @param registry     */    @Override    public void addResourceHandlers(ResourceHandlerRegistry registry) {        super.addResourceHandlers(registry);    }}
四.在想记录用户日志的方法上,加自定义注解

package com.xiaojukeji.ecm.controller;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.annotations.ApiParam;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import com.xiaojukeji.common.annotation.SystemLogAnnotation;import com.xiaojukeji.ep.ip.common.model.AdUser;import com.xiaojukeji.ep.ip.common.utils.ContextHolder;import com.xiaojukeji.service.GiftVisitorService;/** * <p>Description: [gift服务器 相关API接口]</p> * Created on 2017年11月8日 上午10:45:09 * @author  <a href="mailto: 15175223269@163.com">全冉</a> * @version 1.0  * Copyright (c) 2017 全冉公司 */@Api(value = "gift服务器 相关接口", description = "gift服务器 相关接口")@RestController@RequestMapping("/gift")public class GiftVisitorController {    @Autowired    private GiftVisitorService giftVisitorService;    /**     * <p>Discription:[选择文件上传到gift服务器]</p>     * Created on 2017年11月8日 上午10:54:30     * @param request 要上传的文件     * @return String 返回此文件在gift服务器的路径,路径若为空字符串,则需要异常处理     * @author:[全冉]     */    @ApiOperation("选择文件上传到gift服务器[quanran@camelotchina.com]")    @PostMapping(value = "/upload", consumes = "multipart/*", headers = "content-type=multipart/form-data")    @SystemLogAnnotation(value = "上传文件")    public String upload(@ApiParam(value = "上传的文件", required = true) MultipartFile multipartFile, HttpServletRequest request) {// 生成随机fileKey String fileKey = UUID.randomUUID().toString();// 获取后缀String fileName = multipartFile.getOriginalFilename();String suffix = fileName.substring(fileName.indexOf("."));    }}
五.启动项目,请求GiftVisitorController 的upload方法,在进入到此方法前,就会对此请求路径进行拦截,将此用户上传文件的操作插入到了数据库中。


另一篇参考地址,可以和我写得相互验证:http://www.jianshu.com/p/43c97352aa1e




阅读全文
0 0
原创粉丝点击