java aspect 切面怎么获取 POST 数据,以及 获取FormData 文件跟form一起上传时候的参数
java aspect 切面怎么获取 POST 数据,以及 获取FormData 文件跟form一起上传时候的参数
package com.test.aop; import com.alibaba.druid.sql.ast.statement.SQLIfStatement; import com.alibaba.fastjson.JSONObject; import com.cms.aop.BaseFormData; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.*; import java.util.stream.Collectors; import static org.jeecg.modules.jmreport.common.constant.c.o; /** * 切面 ,记录日志 */ @Slf4j @Aspect @Component public class PostRequestBodyAspect { @Pointcut("execution(* com.cms.controller.*.*(..))") public void controllerMethods() { } /** * ** 支持get POST 的提交,但不支持formData提交 */ @Around("controllerMethods() && args(.., @RequestBody requestBody)") public Object aroundControllerMethods(ProceedingJoinPoint joinPoint, Object requestBody) throws Throwable { // 在这里获取到 POST 请求体中的参数 // requestBody 就是 POST 请求体中的参数 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String data = getFormData(joinPoint, request, requestBody); log.info("url:{},body:{}",request.getServletPath(),data); Date startDate = new Date(); try { // 执行原始方法 Object result = joinPoint.proceed(); // 可以对原始方法的返回值进行拦截和修改 return result; } catch (Exception e) { // 处理异常情况 throw e; } finally { HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getResponse(); Date endDate = new Date(); Long costTime = endDate.getTime() - startDate.getTime(); //耗时 log.info("url:{},Response Status Code:{},Response Body:{},cost :{} ",request.getServletPath(),response.getStatus(),response.getWriter().toString(),costTime); // // 获取并处理Response对象 // System.out.println("Response Status Code: " + response.getStatus()); // System.out.println("Response Content Type: " + response.getContentType()); // System.out.println("Response Body: " + response.getWriter().toString()); // //写入日志到数据库 // int responseStatue = response.getStatus(); // } } /** * 解决前端用formData提交没有记录日志问题 ,注意MultipartFile 在方法中的参数一定要放在最后面,不然参数位置不对,会没反应 */ @Around("controllerMethods() && args(.., mulList)") public Object aroundControllerMethods2(ProceedingJoinPoint joinPoint, @RequestPart List<MultipartFile> mulList) throws Throwable { // 在这里获取到 POST 请求体中的参数 // requestBody 就是 POST 请求体中的参数 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String data = getFormData(joinPoint, request, null); log.info("url:{},body:{}",request.getServletPath(),data); Date startDate = new Date(); try { // 执行原始方法 Object result = joinPoint.proceed(); // 可以对原始方法的返回值进行拦截和修改 return result; } catch (Exception e) { // 处理异常情况 throw e; } finally { HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getResponse(); Date endDate = new Date(); Long costTime = endDate.getTime() - startDate.getTime(); //耗时 log.info("url:{},Response Status Code:{},Response Body:{},cost :{} ",request.getServletPath(),response.getStatus(),response.getWriter().toString(),costTime); // // 获取并处理Response对象 // System.out.println("Response Status Code: " + response.getStatus()); // System.out.println("Response Content Type: " + response.getContentType()); // System.out.println("Response Body: " + response.getWriter().toString()); // //写入日志到数据库 // int responseStatue = response.getStatus(); } } /** * 解决前端后端特殊类处理 */ // @Around("controllerMethods() && args(.., reqVo)") // public Object aroundControllerMethods3(ProceedingJoinPoint joinPoint, BaseFormData reqVo) throws Throwable { // // 在这里获取到 POST 请求体中的参数 // // requestBody 就是 POST 请求体中的参数 // HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); // String data=getFormData(joinPoint,request,requestBody); // Date startDate=new Date(); // try { // // 执行原始方法 // Object result = joinPoint.proceed(); // // // 可以对原始方法的返回值进行拦截和修改 // // return result; // } catch (Exception e) { // // 处理异常情况 // throw e; // } finally { // HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse() // // Date endDate=new Date(); // // 获取并处理Response对象 // System.out.println("Response Status Code: " + response.getStatus()); // System.out.println("Response Content Type: " + response.getContentType()); // System.out.println("Response Body: " + response.getWriter().toString()); // //写入日志到数据库 // int responseStatue=response.getStatus(); // Long costTime=endDate.getTime()-startDate.getTime(); //耗时 // } // } /** * * 获取POST GET的data数据 * @param request * @return大 */ private static String getFormData(ProceedingJoinPoint joinPoint, HttpServletRequest request, Object requestBody) { if ("POST".equalsIgnoreCase(request.getMethod())) { if (existFileUpload(request)) { Map<String, Object> mapData = new HashMap<>(); request.getParameterMap().entrySet().stream().forEach(entry -> { mapData.put(entry.getKey(), entry.getValue()); }); return JSONObject.toJSONString(mapData); } else { if (requestBody == null) { Object[] args = joinPoint.getArgs(); if (args != null && args.length > 0) { List<Object> newArgs = new ArrayList<>(); for (Object arg : args) { if (arg instanceof HttpServletRequest) { } else if (arg instanceof BindingResult) { } else { newArgs.add(arg); } } return JSONObject.toJSONString(newArgs); } } else if (requestBody instanceof BeanPropertyBindingResult) { return JSONObject.toJSONString(((BeanPropertyBindingResult) requestBody).getTarget()); } else if (requestBody instanceof MultipartHttpServletRequest) { Enumeration<String> parameterNames = request.getParameterNames(); Map<String, String> map = new HashMap<>(); while (parameterNames.hasMoreElements()) { String paramName = (String) parameterNames.nextElement(); String paramValue = request.getParameter(paramName); map.put(paramName, paramValue); } return JSONObject.toJSONString(map); } else { return JSONObject.toJSONString(requestBody); } } } String data = request.getParameterMap().entrySet().stream().map(entry -> { String result; String[] value = entry.getValue(); if (value != null && value.length > 1) { result = Arrays.stream(value).map(s -> entry.getKey() + "=" + s).collect(Collectors.joining("&")); } else { result = entry.getKey() + "=" + value[o]; } return result; }).collect(Collectors.joining("&")); return data; } /***是否是上传文件* @param request* @return*/ static boolean existFileUpload(HttpServletRequest request) { String contentType = request.getContentType(); if (contentType != null && (contentType.startsWith("multipart/") || contentType.contains("boundary="))) { return true; // 是上传文件的诗求 } else { return false; // 不是上传文件的请求 } } }
/** formdata提交方式的基础类 */ public class BaseFormData{ } /** formdata提交方式的基础类 */ public class TestFormData extend BaseFormData{ }
测试例子
@RequestMapping(value="/testUpload",method= RequestMethod.POST)
public Strin adduploadFile(HttpServleteRequest reawest,@Valid TestFormData req,BindingResult bindingResult,@ReuestPart("uplodFilelist") List<MultipartFile> uplodFilelist) {