背景:因公司所有项目都需要按照某个标准进行升级,因此所有项目都需要添加操作日志,又因手上struts项目较多没时间全部升级为springboot,因此直接在struts添加拦截器(添加操作日志),struts1.2升级至2.5.30可查看升级
struts2添加拦截器步骤:
先定义拦截器 :
/**
*操作日志记录 实体类
* */
public class OperationLog {
String userId;
String operationTime;
String actionName;
String method;
String param;
String result;
String requestIp;
String uri;
@Override
public String toString() {
return "OperationLog [userId=" + userId + ", operationTime=" + operationTime + ", actionName=" + actionName
+ ", method=" + method + ", param=" + param + ", result=" + result + ", requestIp=" + requestIp
+ ", uri=" + uri + "]";
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getOperationTime() {
return operationTime;
}
public void setOperationTime(String operationTime) {
this.operationTime = operationTime;
}
public String getActionName() {
return actionName;
}
public void setActionName(String actionName) {
this.actionName = actionName;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getRequestIp() {
return requestIp;
}
public void setRequestIp(String requestIp) {
this.requestIp = requestIp;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.Parameter;
import com.esl.wifs.domain.User;
import com.esl.wifs.util.DateUtils;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.PreResultListener;
/**
* struts系统日志拦截器
*/
public class Dolog implements Interceptor {
// private IAdminOperationLogService adminOperationLogService;
private static final long serialVersionUID = 1L;
public String intercept(ActionInvocation ai) throws Exception {
ai.addPreResultListener(new PreResultListener() {
public void beforeResult(ActionInvocation ai, String arg1) { //写入DB
OperationLog log = new OperationLog();
HttpServletRequest request = ServletActionContext.getRequest();
try {
log.setOperationTime(DateUtils.getNow());//操作时间
Map<String, Object> session = ai.getInvocationContext().getSession();
User user = (User) session.get("sessionUser");
if (user != null) {
log.setUserId(user.getLoginname() + "(" + user.getPname() + ")");
} else {
log.setUserId("未登录");
}
Map<String, Parameter> map = ai.getInvocationContext().getParameters();
Set<String> keys = map.keySet();
StringBuffer sb = new StringBuffer(); //因未引入JSON,因此参数暂时拼接处理
for (String key : keys) {
sb.append(key + "=" + map.get(key).getValue()+ "#");
}
log.setRequestIp(request.getRemoteAddr()); //请求的IP地址
log.setActionName(ai.getAction().getClass().toString());//类名
log.setMethod(ai.getInvocationContext().getName());//方法名
log.setUri(request.getRequestURI()); // 请求URI
log.setParam(sb.toString());//参数
log.setResult(ai.getResultCode());//返回结果
//...//插入数据库 -----待实现
saveLog(log.toString());//写入本地文件
} catch (Exception e) {
e.printStackTrace();
}
}
});
return ai.invoke();
}
public static void saveLog(String content) {
//String appPath = ServletActionContext.getServletContext().getRealPath("/"); //当前项目所在路径 ;
String appPath = "d://OperLog";//为了方便找到日志,直接写入D盘下的某个文件夹
try {
File path = new File(appPath);
if (!path.exists()) {
path.mkdir();
}
File LogDir = new File(path + "/" + (Calendar.getInstance().get(Calendar.MONTH) + 1));
if (!LogDir.exists()) {
LogDir.mkdir();
}
File file = new File(LogDir + "/" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + ".log");
if (!file.exists()) {
file.createNewFile();
}
BufferedWriter br = new BufferedWriter(new FileWriter(file, true));
br.write(content);
br.newLine();
br.flush();
br.close();
File LogDirOld = new File(
path + "/" + (Calendar.getInstance().get(Calendar.MONTH) - 2 > 0 ? (Calendar
.getInstance().get(Calendar.MONTH) - 2)
: Calendar.getInstance().get(Calendar.MONTH) + 10));
if (LogDirOld.exists()) {
File[] fileOlds = LogDirOld.listFiles();
for (File f : fileOlds) {
f.delete();
}
LogDirOld.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
}
public void init() {
}
}
struts.xml中定义声明拦截器:
注意:拦截器的标签必须是在package标签内,package必须在struts标签内,package标签内其他标签必须在拦截器之下定义,否则保存xml文件就会报错,启动也会报错,因struts.xml严格定义了书写顺序),以下是拦截器的定义与指定引用:
<interceptors>
<!-- 1、定义拦截器 -->
<interceptor name="dolog" class="com.esl.wifs.web.master.Dolog"></interceptor>
<!-- 2.定义拦截器栈 -->
<interceptor-stack name="MyStack">
<!-- 我们定义了全局拦截器之后,会把父包中的默认拦截器栈覆盖掉了,这里记得引用回来 -->
<interceptor-ref name="dolog"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- *****************定义操作日志拦截器 END ****************-->
<default-interceptor-ref name="MyStack"/><!--*指定当前package下的所有action默认的拦截器 -->
示例:
因我的项目引入的xml较多,action分的较细,因此package很多,多个package就需要多次定义拦截器,下面只取了其中一个package(一个struts标签下可以有很多package,package标签下可以有很多action标签,定义声明拦截器必须在所有action标签之前声明):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 如果接口访问不了,需要在每个action的package上加上 strict-method-invocation="false"-->
<package name="login" extends="tiles-default" namespace="/login" strict-method-invocation="false">
<!-- ***************** 定义操作日志拦截器 START **************** -->
<interceptors>
<!-- 1、定义拦截器 -->
<interceptor name="dolog" class="com.esl.wifs.web.master.Dolog"></interceptor>
<!-- 2.定义拦截器栈 -->
<interceptor-stack name="MyStack">
<!-- 我们定义了全局拦截器之后,会把父包中的默认拦截器栈覆盖掉了,这里记得引用回来 -->
<interceptor-ref name="dolog"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- *****************定义操作日志拦截器 END ****************-->
<default-interceptor-ref name="MyStack"/><!--*指定当前package下的所有action默认拦截器 -->
<action name="login" class="login" method="login">
<result name="SUCCESS" type="redirectAction"><!--登录成功之后跳转的页面-->
<param name="actionName">goInquire</param>
<param name="namespace">/inquire</param>
</result>
<result name="updatePwd">/master/personPsw.jsp</result><!-- 登录成功后判断超过90天未修改密码,跳转密码修改页面 -->
<result name="input">/login.jsp</result>
<result type="redirect" name="gotowi">${page}?wiid=${id}</result> <!--跳转到登录之前请求的页面-->
</action>
</package>
<!-- 如果以下还有更多的package标签,且这些标签都有action,且都需要拦截器拦截,那么就需要把前面声明的拦截器再当前package再次声明并引用,否则拦截器只会拦截上面哪个package下的所有action -->
</struts>
以上完成之后启动项目,执行任何操作,就可以在d盘下的OperLog文件夹下查看操作日志了,需要写入数据库只需要把生成文件的方法改成保存数据库的方法即可