1. 程式人生 > >struts2框架專案的開發排坑經歷

struts2框架專案的開發排坑經歷

1. 實現使用者操作的記錄

獲取使用者在系統上的相關操作,並將其儲存到資料庫中。

這裡提供兩種思路:

  1. AOP :使用AOP寫切面,設定切點logPointCut(),並使用註解方式@annotation實現注入。

    然後,在切點處可以通過定義@Before("logPointCut()")@After("logPointCut()")來具體設定操作。

  2. 攔截器:攔截器的思路更加簡單,而且更加適配struts2專案,也是我所採用的。

具體實現上,我依然採用了action層、service層和dao層的設計模式,同時在spring配置檔案中進行注入。在spring配置完畢後,需要注意的是在action層和service層都需要定義新的private

變數來宣告所設定的介面為一個javabean,同時完成set和get方法,否則會報錯。

主要實現直接放在了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!!!

否則,listremove功能無法使用。

直接使用迴圈+add傳值即可。