好久没有写博客了,最近找一些之前写过的代码,结果不知道在那个项目里面写的,已经找不到了,又得从头开始,所以记录一下本次编写过程,之后自己查看,也可给需要的朋友一个参考!
项目为 springboot2.0+mybatisplus + mysql搭建
需求:编写一个注解,记录 登录账户的操作记录,主要记录增删改操作
效果如下图所示
1.首先添加一个自定义注解,@interface ,里面的注解类型元素(参数)是需要在具体注解里面添加的,可以有很多类型如string,int,array等,注意,对参数有一下要求:
*访问修饰符必须为public,不写默认为public;
*名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作)
*default
代表默认值 如这样: int age() default 18;
*如果没有默认值,代表后续使用注解时必须给该类型元素赋值
*所有定义的注解都会自动继承java.lang.annotation.Annotation接口
@Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。它使用一个枚举类型定义如下:
public enum ElementType {
/** 类,接口(包括注解类型)或枚举的声明 */
TYPE,
/** 属性的声明 */
FIELD,
/** 方法的声明 */
METHOD,
/** 方法形式参数声明 */
PARAMETER,
/** 构造方法的声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 注解类型声明 */
ANNOTATION_TYPE,
/** 包的声明 */
PACKAGE
}
@Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。
注解的生命周期有三个阶段:1、Java源文件阶段SOURCE;2、编译到class文件阶段CLASS;3、运行期阶段RUNTIME。
具体代码如下:
package com.zdxf.server.component.security.oplog.annotation;
import com.zdxf.server.component.security.oplog.service.impl.OperationLogAnnotation;
import javax.validation.Constraint;
import java.lang.annotation.*;
/**
* 操作日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
// 可以出现在java文档中
@Documented
// 可以被子注解继承
@Inherited
public @interface AddOperationLog {
/**
* 功能
* @return
*/
String resource() default "";
/**
* 操作
* @return
*/
String operation() default "";
/**
* 模块
* @return
*/
String module() default "";
}
2. 然后添加一个spring拦截器,拦截所有请求,也可以指定到方法,将dao注入进去,否则报空指针
package com.zdxf.server.component.security.oplog.config;
import com.zdxf.server.component.security.oplog.dao.IOperationLogDao;
import com.zdxf.server.component.security.oplog.service.impl.OperationLogAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AnnotationConfig implements WebMvcConfigurer {
@Autowired
private IOperationLogDao dao;
@Override
public void addInterceptors(InterceptorRegistry registry) {
OperationLogAnnotation oper=new OperationLogAnnotation(dao);
registry.addInterceptor(oper)
.addPathPatterns("/**");
}
}
3.保存登录账户信息
package com.zdxf.server.component.security.oplog.service.impl;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdxf.server.common.base.context.RequestContext;
import com.zdxf.server.common.base.model.UserPriciple;
import com.zdxf.server.component.common.util.SecurityUserUtil;
import com.zdxf.server.component.govern.model.TplUserT;
import com.zdxf.server.component.security.oplog.annotation.AddOperationLog;
import com.zdxf.server.component.security.oplog.dao.IOperationLogDao;
import com.zdxf.server.component.security.oplog.model.OperationLogVO;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Date;
@Aspect
@Component
public class OperationLogAnnotation implements HandlerInterceptor {
private IOperationLogDao dao;
public OperationLogAnnotation(IOperationLogDao dao){
this.dao=dao;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
boolean isAnn=handler.getClass().isAssignableFrom(HandlerMethod.class);
if(isAnn) {
//根据当前方法获取类的注解
AddOperationLog olog=((HandlerMethod)handler).getMethodAnnotation(AddOperationLog.class);
if(null!=olog){
OperationLogVO op=createOperationLog(olog);
int result=dao.insert(op);
System.out.println("保存操作记录:"+result);
}
}
}
private OperationLogVO createOperationLog(AddOperationLog operationLog) {
String moduleStr = operationLog.module();
String resourceStr = operationLog.resource();
String operationStr = operationLog.operation();
OperationLogVO opLog = new OperationLogVO();
UserPriciple user = RequestContext.getCurrent().getUser();
if(null != user){
opLog.setUserId(RequestContext.getCurrent().getUser().getId());
opLog.setUsername(RequestContext.getCurrent().getUser().getUsername());
opLog.setPhone(RequestContext.getCurrent().getUser().getPhone());
}
TplUserT tuser= SecurityUserUtil.obtainUser();
if(null != tuser){
opLog.setUserId(SecurityUserUtil.obtainUser().getAgencyUserId());
opLog.setUsername(SecurityUserUtil.obtainUser().getUsername());
opLog.setPhone(SecurityUserUtil.obtainUser().getPhone());
}
opLog.setOpDate(new Date());
opLog.setIp(RequestContext.getCurrent().getRequest().getRemoteAddr());
// opLog.setLocalIp(RequestContext.getCurrent().getRequest().getLocalAddr());
opLog.setModule(moduleStr);
opLog.setResource(resourceStr);
opLog.setOperation(operationStr);
// opLog.setCreationDate(new Date());
opLog.setOpCode("操作成功");
return opLog;
}
}
4. 对应的dao层,使用mybatis默认方法
package com.zdxf.server.component.security.oplog.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zdxf.server.component.security.oplog.model.OperationLogVO;
public interface IOperationLogDao extends BaseMapper<OperationLogVO> {
}
5.对应的实体,添加@Data注解,可以代替getset方法,具体可自行查询
package com.zdxf.server.component.security.oplog.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tpl_operation_log_t")
@ApiModel(value="操作日志对象", description="")
public class OperationLogVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID(操作日志)")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "用户ID")
private Long userId;
@ApiModelProperty(value = "操作结果")
private String opCode;
@ApiModelProperty(value = "手机")
private String phone;
@ApiModelProperty(value = "姓名")
private String username;
@ApiModelProperty(value = "角色")
private String role;
@ApiModelProperty(value = "IP")
private String ip;
@ApiModelProperty(value = "操作日期")
private Date opDate;
@ApiModelProperty(value = "模块")
private String module;
@ApiModelProperty(value = "资源")
private String resource;
@ApiModelProperty(value = "操作")
private String operation;
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date creationDate;
}
6 具体应用,名称为自定义注解的名称,里面的参数就是自定义注解里面的三个参数
以上!!!