struts2框架專案的開發排坑經歷
阿新 • • 發佈:2018-12-12
1. 實現使用者操作的記錄
獲取使用者在系統上的相關操作,並將其儲存到資料庫中。
這裡提供兩種思路:
-
AOP :使用AOP寫切面,設定切點
logPointCut()
,並使用註解方式@annotation
實現注入。然後,在切點處可以通過定義
@Before("logPointCut()")
和@After("logPointCut()")
來具體設定操作。 -
攔截器:攔截器的思路更加簡單,而且更加適配struts2專案,也是我所採用的。
具體實現上,我依然採用了action層、service層和dao層的設計模式,同時在spring配置檔案中進行注入。在spring配置完畢後,需要注意的是在action層和service層都需要定義新的private
主要實現直接放在了action層,程式碼如下:
import *********
@SuppressWarnings("serial")
public class AuditLogInterceptor extends MethodFilterInterceptor {
/** 解釋一下:MethodFilterInterceptor是一個已經實現的過濾器類,可以直接繼承 **/
/** 定義一下需要用的的service,並宣告get和set方法 **/
/** 一個例子,根據自己的設定來寫 **/
private IOperationRecordService operationRecordService;
public IOperationRecordService getOperationRecordService() {
return operationRecordService;
}
public void setOperationRecordService(IOperationRecordService operationRecordService) {
this.operationRecordService = operationRecordService;
}
@Override
protected String doIntercept(ActionInvocation actioninvocation) throws Exception {
AuditLog auditLog = new AuditLog();
Timestamp nowDate = new Timestamp(System.currentTimeMillis());
String result = actioninvocation.invoke();// 遞迴呼叫攔截器
String id = UUID.randomUUID().toString();
auditLog.setId(id);
/*時間相關*/
auditLog.setCreateTime(nowDate);//設定建立時間
/** 獲取網路請求 **/
HttpServletRequest request = ServletActionContext.getRequest();
/** 獲取使用者資訊 **/
User userInfo = (User)request.getSession().getAttribute("userInfo");
String refer = request.getHeader("Referer");
String userAgent = request.getHeader("User-Agent");
String params = getParamString(request.getParameterMap());
/** 只有註冊使用者會有資訊,如果沒有註冊,則將名字設定為unRegedit **/
if(userInfo == null) {
auditLog.setUserName("unRegedit");
} else {
auditLog.setUserName(userInfo.getUid());
}
auditLog.setReference(refer);
auditLog.setUserAgent(userAgent);
auditLog.setParams(params);
String methodName = actioninvocation.getProxy().getMethod();
if (methodName.length() > 0) {
Object action = actioninvocation.getAction();
Class clazz = action.getClass();
/*Action 類名*/
auditLog.setClazz(clazz.getName());
Method method = action.getClass().getMethod(methodName, null);
/*方法名稱*/
auditLog.setMethod(methodName);
String ip = ServletActionContext.getRequest().getRemoteAddr();
auditLog.setIp(ip);// 記錄登入的IP
userService.insertOperationRecord(auditLog);
}
return result; // 跳轉
}
/** param拼接 **/
private String getParamString(Map<String, String[]> map) {
StringBuilder sb = new StringBuilder();
for (Entry<String, String[]> e : map.entrySet()) {
sb.append(e.getKey()).append("=");
String[] value = e.getValue();
if (value != null && value.length == 1) {
sb.append(value[0]).append("&");
} else {
sb.append(Arrays.toString(value)).append("&");
}
}
return sb.toString();
}
/**
* 通過HttpServletRequest返回IP地址
* @param request HttpServletRequest
* @return ip String
* @throws Exception
*/
public String getIpAddr(HttpServletRequest request) throws Exception {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 通過IP地址獲取MAC地址
* @param ip String,127.0.0.1格式
* @return mac String
* @throws Exception
*/
public String getMACAddress(String ip) throws Exception {
String line = "";
String macAddress = "";
final String MAC_ADDRESS_PREFIX = "MAC Address = ";
final String LOOPBACK_ADDRESS = "127.0.0.1";
//如果為127.0.0.1,則獲取本地MAC地址。
if (LOOPBACK_ADDRESS.equals(ip)) {
InetAddress inetAddress = InetAddress.getLocalHost();
//貌似此方法需要JDK1.6。
byte[] mac = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
//下面程式碼是把mac地址拼裝成String
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
if (i != 0) {
sb.append("-");
}
//mac[i] & 0xFF 是為了把byte轉化為正整數
String s = Integer.toHexString(mac[i] & 0xFF);
sb.append(s.length() == 1 ? 0 + s : s);
}
//把字串所有小寫字母改為大寫成為正規的mac地址並返回
macAddress = sb.toString().trim().toUpperCase();
return macAddress;
}
//獲取非本地IP的MAC地址
try {
Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
if (line != null) {
int index = line.indexOf(MAC_ADDRESS_PREFIX);
if (index != -1) {
macAddress = line.substring(index + MAC_ADDRESS_PREFIX.length()).trim().toUpperCase();
}
}
}
br.close();
} catch (IOException e) {
e.printStackTrace(System.out);
}
return macAddress;
}
}
2. 使用spring配置檔案實現注入
在spring.xml配置檔案中要將相關的action、service、dao全部注入
其中,action層注入service,service層注入dao,dao層注入sql。要將所有用到的全部注入,否則報錯!
3. 前端傳參
一開始使用的是implements ModelDriven<>
的方法傳參,發現引數傳不過來,因此放棄了這種方式,採用了笨辦法,即在action中寫明需要的變數名稱(注意名稱要唯一)!
4. 資料庫表
資料庫表字段長度一定要長,否則在insert時會報錯,catch住錯誤後一定要列印這個錯誤,否則很難排查。
5. list中remove的問題
這個坑排了很久!
string[]
轉list<string>
時,一定不要用Arrays.asList
!!!
否則,list
的remove
功能無法使用。
直接使用迴圈+add傳值即可。