JAVA共通ログ記録方法の実現
前言:
以前はfilter層で直接にhttp ServerletRequestをフィルタしてログ処理を要求しましたが、その後は再びget Writer()の時にalready been call異常を報告します。調べてみたら、元の流れの形式は一回しか読み取れませんでした。食べ物のようです。食べたらなくなります。だからfilterとinteceptorではrequestの流れを取ることでログを記録することはできません。
そこでやはり共通の方法を使うつもりです。controller層aopでログを記録します。
Aopを使って操作ログを記録します。
ステップ1:Aopを追加
ステップ3:Dao、Entity、Mapperを書く
以前はfilter層で直接にhttp ServerletRequestをフィルタしてログ処理を要求しましたが、その後は再びget Writer()の時にalready been call異常を報告します。調べてみたら、元の流れの形式は一回しか読み取れませんでした。食べ物のようです。食べたらなくなります。だからfilterとinteceptorではrequestの流れを取ることでログを記録することはできません。
そこでやはり共通の方法を使うつもりです。controller層aopでログを記録します。
Aopを使って操作ログを記録します。
ステップ1: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 (Object object : objects) {
if (object == null) {
requestBody = null;//POST XXX
}else if (object instanceof String) {
requestBody = (String) object;//
}else {
requestBody = JSONObject.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;
}
}
ステップ2:springのxmlに声明を出す
<!-- -->
<bean id="operationLogAop" class="com.ming.learn.core.aop.LogAopHandler"/>
<aop:config>
<aop:aspect id="logAOP" ref="operationLogAop">
<aop:pointcut id="target" expression="execution(* com.ming.learn..*Controller.*(..))"/>
<aop:around method="doSaveLog" pointcut-ref="target"/>
</aop:aspect>
</aop:config>
これでコアステップが完成し、残りは自分で組み立てて記録するものです。ステップ3: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 void setOperator(String operator) {
this.operator = 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 setRequest(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<String, LogTypeEnum> map = new ConcurrentHashMap<>(128);
static{
// Map
for (LogTypeEnum logTypeEnum : LogTypeEnum.values()) {
map.put(logTypeEnum.getMethodName(), logTypeEnum);
}
}
}
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。