我们通过`@BussinessLog注解`来记录日志,该注解源码如下,
```
/**
* 标记需要做业务日志的方法
*
* @author fengshuonan
* @date 2017-03-31 12:46
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
/**
* 业务的名称,例如:"修改菜单"
*/
String value() default "";
/**
* 被修改的实体的唯一标识,例如:菜单实体的唯一标识为"id"
*/
String key() default "id";
/**
* 字典(用于查找key的中文名称和字段的中文名称)
*/
Class<? extends AbstractDictMap> dict() default SystemDict.class;
}
```
其中,`value`为需要记录日志的业务名称,`key`为修改或删除内容的唯一标识,通过这个唯一标识可以知道具体的修改的哪条记录,删除的哪条记录等等,`dict`为对修改字段的中文翻译字典,因为程序记录的都是英文的字段名称,这里通过字典,把英文字段和中文名称对应起来,那么日志信息记录到数据库中就可以变为中文的记录
以`UserDict`为例,
```
/**
* 用户的字典
*
* @author fengshuonan
* @date 2017-05-06 15:01
*/
public class UserDict extends AbstractDictMap {
@Override
public void init() {
put("userId","账号");
put("avatar","头像");
put("account","账号");
put("name","名字");
put("birthday","生日");
put("sex","性别");
put("email","电子邮件");
put("phone","电话");
put("roleid","角色名称");
put("deptid","部门名称");
put("roleIds","角色名称集合");
}
@Override
protected void initBeWrapped() {
putFieldWrapperMethodName("sex","getSexName");
putFieldWrapperMethodName("deptid","getDeptName");
putFieldWrapperMethodName("roleid","getSingleRoleName");
putFieldWrapperMethodName("userId","getUserAccountById");
putFieldWrapperMethodName("roleIds","getRoleName");
}
}
```
翻译字典类中包含两个方法`init()`和`initBeWrapped()`,其中`init()`为存放英文字段和中文字段的匹配,`initBeWrapped()`操作的是把某些字段的数字值翻译为中文直观名称的过程,例如当修改用户信息时,用户修改了一个人性别信息(数据库中1是男,2是女),由1变为了2,程序记录的是数据库中1变为2,但是这句话给业务人员看到他是不知道1和2是什么东西的,所以这里做了一个`值的包装`,把`1`包装为对应的中文名称`男`,`2`包装为对应的中文名称`女`,这样,记录到数据库中,信息就变为了,xxx用户操作了`修改用户`功能,值由`男`变为了`女`.
在initBeWrapped()方法中`putFieldWrapperMethodName()`这个方法的第一参数是被包装的字段名,第二个参数是`ConstantFactory`中的方法名,因为默认会调用`ConstantFactory`来包装值属性
下面介绍业务日志记录的具体步骤:
> * 1.在需要被记录日志的接口上添加@BussinessLog注解,并根据需要填写三个属性(value,key,dict)
> * 2.若是添加或者修改业务,往往需要去编写Dict字典类
> * 3.若是修改业务,例如修改用户信息,因为点击更新用户的时候不会提交修改之前的数据,所以在更新用户信息之前需要保存一下用户的旧的信息才可以记录用户修改的内容,这个缓存用户临时信息的地方一般添加在跳转到用户详情接口,用`LogObjectHolder.me().set(user);`这行代码来缓存用户的旧的信息,具体用法可以参考`UserMgrController`类中的`userEdit()`和`edit()`
- Guns 技术文档 v5.1
- 1. 序言
- 1.1 文档简介
- 1.2 Guns教程
- 1.3 获取帮助
- 2. 使用手册
- 2.1 下载项目
- 2.2 导入项目
- 2.2.1 eclipse导入
- 2.2.2 IDEA导入
- 2.3 运行项目
- 2.4 打包部署
- 3. 开发手册
- 3.1 了解Guns
- 3.1.1 模块结构
- 3.1.2 包结构说明
- 3.2 实战开发
- 3.2.1 建表
- 3.2.2 代码生成
- 3.3.3 添加菜单与分配权限
- 3.3.4 编写业务代码
- 3.3 权限控制与校验
- 3.3.1 用户,角色和资源
- 3.3.2 如何对资源进行权限控制
- 3.3.3 前端页面对权限资源的显示
- 3.4 多数据源的使用
- 3.5 如何分页
- 3.5.1 简单查询的分页
- 3.5.2 复杂查询的分页
- 3.5.3 获取前端表格插件传值
- 3.6 数据范围
- 3.6.1 介绍
- 3.6.2 如何使用
- 3.6.3 原理
- 3.7 guns-rest模块的使用
- 3.7.1 关于jwt鉴权
- 3.7.2 关于传输数据的签名
- 3.7.3 guns-rest模块的运行流程
- 3.7.4 运行原理
- 3.8 工作流
- 3.9 日志记录
- 3.9.1 业务日志
- 3.9.2 异常日志
- 3.10 如何使用缓存
- 3.10.1 用工具类操作
- 3.10.2 用spring cache操作缓存
- 3.11 使用枚举
- 3.12 spring boot热部署
- 3.12.1 重新加载html
- 3.12.2 重新加载java类
- 4. 扩展与高级配置
- 4.1 修改项目名和包名
- 4.1.1 修改项目名
- 4.1.2 修改包名
- 4.2 放过接口权限验证
- 4.3 静态资源和模板位置的变更
- 4.4 三个或更多数据源如何配置
- 4.5 添加登录验证码
- 4.6 spring profile
- 4.7 多机器部署开启spring session
- 4.8 使用Redis
- 4.9 XSS过滤器
- 4.9.1 介绍
- 4.9.2 原理
- 4.9.3 放过过滤
- 5. 核心思想
- 5.1 分包
- 5.2 统一异常拦截
- 5.2.1 介绍
- 5.2.2 优点
- 5.2.3 关于性能
- 5.3 结果包装器
- 5.3.1 如何使用
- 5.3.2 ConstantFactory
- 5.4 前端思想
- 5.4.1 布局
- 5.4.2 标签
- 5.4.3 手动新增标签页
- 6. 常见问题答疑
- 6.1 默认的系统登录账号和密码是多少
- 6.2 权限异常
- 6.3 为何分页是前端实现
- 6.4 关于${ctxPath}
- 6.5 放过某些url的权限验证
- 6.6 主页的搜索功能
- 6.7 运行sql报错
- 6.8 关于打包
- 6.9 查询结果的驼峰转化问题
- 6.10 为何使用beetl
- 6.11 为何有的业务没有service层
- 6.12 为何既有dao,又有mapper
- 6.13 提示@spring.active@错误