java实现日记软件_JAVA实现通用日志记录方法

前言:

之前想在filter层直接过滤httpServerletRequest请求进行日志处理,但是之后再getWriter()的 时候报already been call异常。查了下,才发现原来流形式的只能读取一次。。就好像食物,吃了就没了。。 所以在filter和inteceptor里面是没法通过获取request的流来进行日志记录的。

于是还是准备用通用的方法:controller层aop进行切面记录日志。

使用Aop记录操作日志

第一步:添加Aop

/**

* 统一日志处理Handler

* @author Mingchenchen

*

*/

public class LogAopHandler {

@Autowired

private AuditLogDao auditLogDao;

/**

* controller层面记录操作日志

* 注意此处是aop:around的 因为需要得到请求前的参数以及请求后接口返回的结果

* @throws Throwable

*/

public Object doSaveLog(ProceedingJoinPoint joinPoint) throws Throwable {

MethodSignature method = (MethodSignature) joinPoint.getSignature();

String methodName = method.getName();

Object[] objects = joinPoint.getArgs();

String requestBody = null;

if (objects!=null && objects.length>0) {

for (ObjVMnWBTect object : objects) {

if (objecjsONObject.toJSONString(object);

}

}

}

//只记录POST方法的日志

boolean isNeedSaveLog = false;

//此处不能用getAnnotationByType 是java8的特性,因为注解能够重名,所以得到的是数组

RequestMapping annotation = method.getMethod().getAnnotation(RequestMapping.class);

for (RequestMethod requestMethod : annotation.method()) {

if (requestMethod==RequestMethod.POST) {

isNeedSaveLog = true;

}

}

JSONObject requestBodyJson = null;

try {

requestBodyJson = JSONObject.parseObject(requestBody);

} catch (Exception e) {

//do nothing 即POST请求没传body

}

HttpServletRequest request = RequestContextUtil.getRequestByCurrentContext();

String userName = RequestContextUtil.getUserNameByCurrentContext();

if (StringUtil.isEmpty(userName)) {

try {

userName = DmsCache.get(requestBodyJson.getString("userName")).getName();

} catch (Exception e) {

userName = RequestContextUtil.getAsynUserInfoByAutoDeploy().getName();

}

}

//得到request的参数后让方法执行它

//注意around的情况下需要返回result 否则将不会返回值给请求者

Object result = joinPoint.proceed(objects);

try {

JSONObject resultJson = JSONObject.parseObject(result.toString());

if (isNeedSaveLog) {//如果是POST请求 则记录日志

LogTypeEnum logTypeEnum = LogTypeEnum.getDesByMethodName(methodName);

if (logTypeEnum != null) {

AuditLogEntity auditLogEntity = new AuditLogEntity();

auditLogEntity.setUuid(StringUtil.createRandomUuid());

auditLogEntity.setOperator(userName);

auditLogEntity.setRequestIp(request.getRemoteAddr());

auditLogEntity.setRequestUrl(request.getRequestURI().replace("/cloud-master", ""));

auditLogEntity.setEventType(logTypeEnum.getKey());

auditLogEntity.setEventDesc(logTypeEnum.getDescription());

auditLogEntity.setRequest(requestBody);

int isSuccess = "200".equals(resultJson.getString("code")) ? 1 : 0;

auditLogEntity.setSuccessFlag(isSuccess);

auditLogEntity.setResponse(result.toString());

auditLogEntity.setCreateTime(new Date());

auditLogDao.insert(auditLogEntity);

}

}

} catch (Exception e) {

e.printStackTrace();

}

return result;

}

}

第二步:在spring的xml中声明

如此一来,核心步骤就完成了,剩下的就是自己组装需要记录的东西了。

第三步:写Dao、Entity、Mapper

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Id;

import javax.persistence.Table;

/**

* 日志审计

* @author Mingchenchen

*

*/

@Table(name="audit_log")

public class AuditLogEntity {

@Id

private String uuid;

@Column(name="event_type")

private String eventType;//事件类型

@Column(name="event_desc")

private String eventDesc;//事件中文描述

@Column(name="operator")

private String operator;//操作者

@Column(name="request_ip")

private String requestIp;//客户端地址

@Column(name="request_url")

private String requestUrl;//请求地址

@Column(name="request")

private String request;//请求body

@Column(name="response")

private String response;//请求返回值

@Column(name="create_time")

private Date createTime;

public String getUuid() {

return uuid;

}

public void setUuid(String uuid) {

this.uuid = uuid;

}

public String getEventType() {

return eventType;

}

public void setEventType(String eventType) {

this.eventType = eventType;

}

public String getEventDesc() {

return eventDesc;

}

public void setEventDesc(String eventDesc) {

this.eventDesc = eventDesc;

}

public String getOperator() {

return operator;

}

public v编程客栈tor = operator;

}

public String getRequestIp() {

return requestIp;

}

public void setRequestIp(String requestIp) {

this.requestIp = requestIp;

}

public String getRequestUrl() {

return requestUrl;

}

public void setRequestUrl(String requestUrl) {

this.requestUrl = requestUrl;

}

public String getRequest() {

return request;

}

public void setReq编程客栈uest(String request) {

this.request = request;

}

public String getResponse() {

return response;

}

public void setResponse(String response) {

this.response = response;

}

public Date getCreateTime() {

return createTime;

}

public void setCreateTime(Date createTime) {

this.createTime = createTime;

}

}

第四步:根据Controller的方法名称定制响应的事件类型

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

/**

* 操作日志类型

* @author Mingchenchen

*

*/

public enum LogTypeEnum {

//用户

COMMON_LOGIN("login","login","登录");

//其他

private String methodName;//方法名称与controller一致

private String key;//保存到数据库的事件类型

private String description;//保存到数据库的描述

private LogTypeEnum(String methodName,String key,String description){

this.methodName = methodName;

this.key = key;

this.description = description;

}

public String getMethodName() {

return methodName;

}

public void setMethodName(String methodName) {

this.methodName = methodName;

}

public String getKey() {

return key;

}

public void setKey(String key) {

this.key = key;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

/**

* 根据方法名返回

* @param methodName

* @return

*/

public static LogTypeEnum getDesByMethodName(String methodName){

return innerMap.map.get(methodName);

}

/**

* 内部类 用户保存所有的enum 无须通过Enum.values()每次遍历

* @author Mingchenchen

*

*/

private static class innerMap{

private static Map map = new ConcurrentHashMap<>(128);

static{

//初始化整个枚举类到Map

for (LogTypeEnum logTypeEnum : LogTypeEnum.values()) {

map.put(logTypeEnum.getMethodName(), logTypeEnum);

}

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: JAVA实现通用日志记录方法

本文地址: http://www.cppcns.com/ruanjian/java/192925.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值