1. 程式人生 > >分享spring boot controller統一日誌程式碼

分享spring boot controller統一日誌程式碼

最近專案需要做一個controller層的aop,主要解決下面問題:

1.controller日誌統一列印輸出json格式,相容json和velocity 。

2.專案異常處理

3.異常郵件傳送

4.頁面訪問統計

主要思路使用aop實現,controller引數統一使用@RequestParam接收。

controller

    @RequestMapping(name = "添加個人資訊", value ="/addInfo", method = RequestMethod.POST)
    public String addInfo(@RequestParam("idFront") MultipartFile idFront,
                           @RequestParam(
"idReverse") MultipartFile idReverse, @RequestParam("idNo") String idNo, @RequestParam("realName") String realName, @RequestParam("token") String token, HttpServletRequest request)
throws Exception {

aop

@Aspect
@Component
public class CotrollerLogAop {

    private final static Logger logger = LoggerFactory.getLogger(CotrollerLogAop.class);
   //請求資訊快取
    private final static Map<String, Object[]> MethodInfo=new ConcurrentHashMap<String, Object []>();
    //專案名
@Value("${base.project.name}") private String projectName; //spring boot 錯誤頁面uri @Value("${server.error.path:/error}") private String errorPath; //郵件傳送 @Autowired private EmailClient emailClient; //頁面統計 @Autowired private PageStatService pageStatService; //切面 @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)") public void requestMapping() { } //增強 @Around("requestMapping()") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { long startTime=System.currentTimeMillis(); long endTime=0; Object[] objects = pjp.getArgs(); String userName = ""; String reqArray = ""; String respView = null; String respData = null; String operation = null; Object object = null; String ip = null; Boolean returnJson=false; String[] paramNames=null; String referer=null; String userAgent=null; boolean errorReq=false; try { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); operation=request.getRequestURI(); referer=request.getHeader("Referer"); if(referer==null) referer=""; userAgent=request.getHeader("User-Agent"); if(userAgent==null) userAgent=""; Method method = ((MethodSignature) pjp.getSignature()).getMethod(); if (operation.equals(errorPath)) { errorReq=true; returnJson=method.getAnnotation(ResponseBody.class)!=null; }else{ Object [] info=getMethodInfo(operation, method); returnJson=(Boolean) info[0]; paramNames=(String [])info[1]; } //請求相關引數 ip = RequestParamUtil.getClientIpAddr(request); SessionUser securityUser = (SessionUser) request.getSession().getAttribute(Constants.SESSIONKEY); if (securityUser != null) { userName = securityUser.getShowName(); } reqArray = ArrayToJsonString(objects, paramNames); //執行該方法 object = pjp.proceed(); //響應相關引數 if (returnJson) { if(object instanceof String){ respData=(String)object; }else{ respData = JSON.toJSONString(object); } } else { if (object instanceof ModelAndView) { respView = ((ModelAndView) object).getViewName(); } else { respView = (String) object; } respData = RequestParamUtil.getResponseStr(request); } //spring boot 系統錯誤 if(errorReq){ pageStatService.addStat("/error"); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); if(returnJson){ Map<String, Object> map = new HashMap<String, Object>(); ResponseEntity entity = null; if (response.getStatus() == 404) { map.put("code", MsgCode.ERROR); map.put("msg", "資源不存在!"); entity = new ResponseEntity<Map<String, Object>>(map, HttpStatus.OK); } else { map.put("code", MsgCode.ERROR); map.put("msg", "系統異常!"); entity = new ResponseEntity<Map<String, Object>>(map, HttpStatus.OK); } emailClient.sendSysErrorEmail(operation, response.getStatus() + "-->"+respData); logger.info("<|>error_redirect<|>{}<|>{}<|>{}<|>{}<|>異常資訊<|>{}<|>改寫<|>{}<|>", projectName, userName, ip, operation, respData, JSON.toJSONString(map)); return entity; }else{ ModelAndView view = null; if (response.getStatus() == 404) { view = new ModelAndView("error/404"); } else { view = new ModelAndView("error/500"); } String msg=JSON.toJSONString(((ModelAndView) object).getModel()); emailClient.sendSysErrorEmail(operation, response.getStatus() + "-->"+msg); logger.info("<|>error_redirect<|>{}<|>{}<|>{}<|>{}<|>異常資訊<|>{}<|>改寫<|>{}<|>", projectName, userName, ip, operation, msg, view.getViewName()); return view; } } endTime=System.currentTimeMillis(); logger.info("<|>common<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>", projectName, userName, ip, operation, referer, reqArray, userAgent, respView, respData, endTime-startTime); pageStatService.addStat(operation); return object; } catch (Exception e) { endTime=System.currentTimeMillis(); if (returnJson) { BaseResp baseResp = new BaseResp(); if (e instanceof OpenException) { OpenException openException = (OpenException) e; baseResp.setFailedMsg(openException.getMessage()); logger.info("<|>common<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>", projectName, userName, ip, operation, referer, reqArray, userAgent, "", JSON.toJSONString(baseResp), endTime-startTime); } else { e.printStackTrace(); logger.info("<|>error<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>", projectName, userName, ip, operation,referer, reqArray,userAgent, e.getMessage(), startTime-endTime); baseResp.setFailedMsg("系統異常!"); emailClient.sendSysErrorEmail(operation, e.getMessage()); } return baseResp; } else { e.printStackTrace(); emailClient.sendSysErrorEmail(operation, e.getMessage()); logger.info("<|>error<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>{}<|>", projectName, userName, ip, operation, referer, reqArray, userAgent, e.getMessage(), startTime-endTime); return "error/500"; } } } //拼接請求json private String ArrayToJsonString(Object[] objects, String [] paramNames) throws Exception { StringBuilder reqArray = new StringBuilder("{"); if (paramNames!=null && paramNames.length>0 && objects != null && objects.length > 0) { for (int i = 0; i < objects.length; i++) { if (objects[i] == null) { continue; } if(paramNames.length>i) { String className = objects[i].getClass().getName(); if (className.contains("MultipartFile")) { MultipartFile multipartFile = (MultipartFile) objects[i]; reqArray.append("\"").append(paramNames[i]).append("\":\""). append(multipartFile.getOriginalFilename()).append("\","); } else { reqArray.append("\"").append(paramNames[i]).append("\":"). append(JSON.toJSONString(objects[i])).append(","); } }else{ break; } } } if (reqArray.length() > 1) { reqArray.replace(reqArray.length() - 1, reqArray.length(), "}"); } else { reqArray.append("}"); } return reqArray.toString(); } private Object[] getMethodInfo(String operation, Method method) throws Exception{ Object [] info=MethodInfo.get(operation); if(info==null){ info=new Object[2]; }else{ return info; } Boolean returnJson=false; if(method.getAnnotation(ResponseBody.class)!=null){ returnJson=true; } info[0]=returnJson; Annotation[][] parameterAnnotations = method.getParameterAnnotations(); List<String> list=new ArrayList<String>(); if (parameterAnnotations != null) { int i = 0; //陣列增強for和普通遍歷等價 for (Annotation[] parameterAnnotation : parameterAnnotations) { for (Annotation annotation : parameterAnnotation) { if (annotation instanceof RequestParam) { RequestParam param = (RequestParam) annotation; list.add(param.value()); break; } } } } info[1]=list.toArray(new String[0]); MethodInfo.put(operation, info); return info; } }