通過反射獲取上傳文件方法參數中的文件名

  • 2022 年 1 月 11 日
  • 筆記

  最近系統在做安全測評,要求所有數據操作都要保留操作痕迹,於是PM要求所有介面按照增加、修改、查詢、刪除、導出、導入、審批、文件上傳下載刪除這幾大操作類型統一增加日誌。這一需求的典型實現方法是給Controller層的介面加上自定義註解,通過AOP攔截所有方法來實現。我實現的這個自定義註解傳入的參數有menu菜單名、title操作數據說明及操作類型,記錄格式一般是:用戶名+操作類型+菜單+操作數據說明+獲取的參數資訊。下面簡單說一下其中的邏輯。

1.增加:單條新增數據的方法統一返回新增記錄id,根據攔截到的方法返回值獲取id記錄

2.刪除:循環request中的參數獲取到id並記錄

Enumeration enu=request.getParameterNames();
while(enu.hasMoreElements()){
  String paraName=(String)enu.nextElement();
  Object paramVal1 = request.getParameter(paraName);
  if(paramVal1 != null && !"".equals(paramVal1.toString())){
  sb.append(paraName+"為"+paramVal1+";");
  }
}

3.查詢:一般是GET請求也是循環request中的參數獲取查詢條件,這裡注意參數有的放在request里,有的是如queryXXX/id 這種直接放在請求路徑上的,

String paraName=(String)enu.nextElement();
// 解析查詢路徑傳參的情況,如 url/{id}
if ("_".equals(paraName)){
Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
String idInPath = (String) pathVariables.get("id");
if (idInPath != null) {
sb.append("id為"+idInPath+";");
}
}
4.修改/導出操作:默認也是根據request獲取資訊,但是我的POST請求類型是通過joinPoint.getArgs()獲取的
StringBuffer exportStr = new StringBuffer();
String title = operLog.getTitle();
// 統計報表專用(因為所有統計報表公用一個導出介面)
Object[] args = joinPoint.getArgs();
if ("統計報表".equals(controllerLog.menu()) && args.length>0){
Map arguMap = (Map) args[0];
title = arguMap.get("reportName")+"穿透";
exportStr.append("tn為").append(arguMap.get("tn"))
.append("exportMode為").append(arguMap.get("exportMode"));
}
5.文件上傳、下載、刪除
我的文件上傳是通過WebUploader組件實現的,上傳文件記錄了文件名,而下載和刪除文件都只記錄了文件id。注意這裡有個小坑,Controller中獲取文件名是直接將HttpServletRequest請求映射為MultipartHttpRequest實現的:
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
通過反射獲取到request之後再這樣寫就報錯:cannot be cast to org.springframeworkweb.multipart.MultipartHttpServletRequest
於是查了一下發現需要通過MultipartResolver轉一下:
MultipartResolver resolver = new StandardServletMultipartResolver();
MultipartHttpServletRequest multiRequest = resolver.resolveMultipart(request);
這個具體原理大家可以查詢,其他方式實現的文件上傳不一定適用此方法。
感興趣的朋友可以留言跟我要相關程式碼及數據表