在前面 一步一步做项目(17)日志处理的基础上进行,由于前面已经建立了日志信息,这里就可以使用了。
拦截器
利用拦截器原理,创建用户访问拦截器,生成用户日志,代码如下:
package cn.lut.curiezhang.interceptor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import cn.lut.curiezhang.model.UserLog;
import cn.lut.curiezhang.model.Users;
import cn.lut.curiezhang.service.UserLogService;
/**
* 用户日志拦截器
* @author curiezhang
*/
@SuppressWarnings("serial")
public class UserLogInterceptor implements Interceptor {
public static final String USER_SESSION = ResourceBundle.getBundle("Messages").getString("Application.sessionName");
private static final Logger log = LogManager.getLogger(UserLogInterceptor.class);
private UserLogService userLogService;
public UserLogService getUserLogService() {
return userLogService;
}
public void setUserLogService(UserLogService userLogService) {
this.userLogService = userLogService;
}
@Override
public void destroy() {
log.debug("cmis:UserLogInterceptor层 > destroy");
}
@Override
public void init() {
log.debug("cmis:UserLogInterceptor层 > init");
}
@SuppressWarnings("deprecation")
@Override
public String intercept(ActionInvocation invocation) throws Exception {
log.debug("cmis:UserLogInterceptor层 > 开始拦截");
HttpServletRequest request = ServletActionContext.getRequest();
// 取得请求相关的ActionContext实例
ActionContext actionContext = invocation.getInvocationContext();
Map<String, Object> session = actionContext.getSession();
// 用户ip
String userIp = request.getRemoteAddr();
// 日志时间
String logDate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
// 访问url
String visitUrl = request.getRequestURI();
if (null != request.getQueryString()) {
visitUrl += "?";
visitUrl += request.getQueryString();
}
// 操作Action
String operateAction = invocation.getAction().getClass().toString().substring(6);
// 操作方法 0浏览 1添加 2修改 3删除 4上传 5下载 6缴费 7打印准考证 8验证个人信息
String operateMethod = invocation.getProxy().getMethod();
boolean result = invocation.getProxy().getExecuteResult();
// 日志名
String userLogName = operateAction.substring(operateAction.lastIndexOf(".") + 1) + "_" + operateMethod;
// 操作结果(0成功 1失败)
String operateResult = result ? "0" : "1";
// 返回值
//invocation.invoke()是放行的意思,等action中的方法执行完成后,会再次返回过来,actionResultString为action中返回的值,如success
String returnValue = invocation.invoke();
// 重复提交则不记录日志
if ("invalid.token".equalsIgnoreCase(returnValue)) {
return returnValue;
}
// 备注(暂时没用)
//String memo;
// 取出名为user的session属性
Users user = (Users)session.get(USER_SESSION);
UserLog userLog = new UserLog();
if (user != null) {
userLog.setUserLogName(userLogName);
userLog.setUserId(user.getUserId());
userLog.setUserName(user.getUserName());
userLog.setUserIp(userIp);
userLog.setLogDate(logDate);
if(visitUrl.length() > 250)
userLog.setVisitUrl(visitUrl.substring(0, 249));
else
userLog.setVisitUrl(visitUrl);
if(operateAction.length() > 250)
userLog.setOperateAction(operateAction.substring(0, 249));
else
userLog.setOperateAction(operateAction);
userLog.setOperateMethod(operateMethod);
userLog.setOperateResult(operateResult);
userLog.setReturnValue(returnValue);
// 获取Action参数
Map<String, String[]> map = invocation.getInvocationContext().getParameters().toMap();
Set<String> keys = map.keySet();
// 操作参数(浏览、添加、修改、删除、上传、下载、缴费、打印准考证、验证个人信息等)
String operateParameter = "{";
for (String key : keys) {
if(key.toLowerCase().contains("password")) {
operateParameter += "\"" + key + "\":\"******\",";
} else {
operateParameter += "\"" + key + "\":\"" + ((Object[]) map.get(key))[0] + "\",";
}
}
if(keys.size() > 0) {
operateParameter = operateParameter.substring(0, operateParameter.length() - 1);
}
operateParameter += "}";
if(operateParameter.length() > 10000)
userLog.setOperateParameter(operateParameter.substring(0, 9999));
else
userLog.setOperateParameter(operateParameter);
log.debug("cmis:UserLogInterceptor层 > userLogName={}", userLogName);
log.debug("cmis:UserLogInterceptor层 > userId={}", userLog.getUserId());
log.debug("cmis:UserLogInterceptor层 > userName={}", userLog.getUserName());
log.debug("cmis:UserLogInterceptor层 > userIp={}", userIp);
log.debug("cmis:UserLogInterceptor层 > logDate={}", logDate);
log.debug("cmis:UserLogInterceptor层 > visitUrl={}", visitUrl);
log.debug("cmis:UserLogInterceptor层 > operateAction={}", operateAction);
log.debug("cmis:UserLogInterceptor层 > operateMethod={}", operateMethod);
log.debug("cmis:UserLogInterceptor层 > operateParameter={}", operateParameter);
log.debug("cmis:UserLogInterceptor层 > operateResult={}", operateResult);
log.debug("cmis:UserLogInterceptor层 > returnValue={}", returnValue);
} else {
userLog.setUserLogName(userLogName);
userLog.setUserIp(userIp);
userLog.setLogDate(logDate);
if(visitUrl.length() > 250)
userLog.setVisitUrl(visitUrl.substring(0, 249));
else
userLog.setVisitUrl(visitUrl);
if(operateAction.length() > 250)
userLog.setOperateAction(operateAction.substring(0, 249));
else
userLog.setOperateAction(operateAction);
userLog.setOperateMethod(operateMethod);
userLog.setOperateResult(operateResult);
userLog.setReturnValue(returnValue);
// 获取Action参数
Map<String, String[]> map = invocation.getInvocationContext().getParameters().toMap();
Set<String> keys = map.keySet();
// 操作参数(浏览、添加、修改、删除、上传、下载、缴费、打印准考证、验证个人信息等)
String operateParameter = "{";
for (String key : keys) {
if(key.toLowerCase().contains("password")) {
operateParameter += "\"" + key + "\":\"******\",";
} else {
operateParameter += "\"" + key + "\":\"" + ((Object[]) map.get(key))[0] + "\",";
}
}
if(keys.size() > 0) {
operateParameter = operateParameter.substring(0, operateParameter.length() - 1);
}
operateParameter += "}";
if(operateParameter.length() > 10000)
userLog.setOperateParameter(operateParameter.substring(0, 9999));
else
userLog.setOperateParameter(operateParameter);
log.debug("cmis:UserLogInterceptor层 > userLogName={}", userLogName);
log.debug("cmis:UserLogInterceptor层 > userIp={}", userIp);
log.debug("cmis:UserLogInterceptor层 > logDate={}", logDate);
log.debug("cmis:UserLogInterceptor层 > visitUrl={}", visitUrl);
log.debug("cmis:UserLogInterceptor层 > operateAction={}", operateAction);
log.debug("cmis:UserLogInterceptor层 > operateMethod={}", operateMethod);
log.debug("cmis:UserLogInterceptor层 > operateParameter={}", operateParameter);
log.debug("cmis:UserLogInterceptor层 > operateResult={}", operateResult);
log.debug("cmis:UserLogInterceptor层 > returnValue={}", returnValue);
}
try {
// 日志记录到数据库中
userLogService.save(userLog);
} catch (Exception e) {
log.debug("cmis:UserLogInterceptor层 > 保存数据库错误");
}
return returnValue;
}
}
配置
创建了UserLogInterceptor拦截器类,就要进行配置,在中间添加配置,之后,在action中引用配置,让自定义拦截器起作用,配置如下:
<interceptors>
<interceptor name="log" class="cn.lut.curiezhang.interceptor.UserLogInterceptor" />
<interceptor-stack name="logStack">
<interceptor-ref name="log">
</interceptor-ref>
</interceptor-stack>
</interceptors>
引用配置方法如下:
<action name="index" class="cn.lut.curiezhang.action.AdminAction" method="index">
<result name="success">index.jsp</result>
<interceptor-ref name="logStack"/>
<interceptor-ref name="basicStack"/>
</action>
注意,这里interceptor-ref指定的logStack,就是前面配置的拦截器栈信息,这样,只要访问该链接,就会记录访问日志了,因此,对应的配置文件,都需要进行相应的处理,以便让日志记录起作用。
从这里可以看出,要想产生一个易于修改的应用,还是比较困难的,而且,越到后面越不容易。
运行
所有的配置修改好了以后,只要使用action访问的地址,就都会被拦截,运行截图如下:
点击浏览按钮,就可以查看详细信息了。