httpServletRequest.getParameterMap() is null_ Fan yicui's blog - CSDN blog
Because there is no access to the log system in the project, it is very inconvenient to view abnormal information at ordinary times. Moreover, the product is required every time. Only when it is found in the test can we know that there is an error, which has a bad impact.
Therefore, the real-time alarm combined with enterprise and micro is realized by combining the technologies of section + global exception interception.
I use the group robots provided by enterprises and micro enterprises to release abnormal information. A new robot will provide a Webhook address
Developers can initiate HTTP POST requests according to the provided Webhook to send messages to the group. For details, please refer to the article: Group robot configuration description - interface document - enterprise wechat Developer Center (qq.com)
Message content type used: markdown type
{ "msgtype": "markdown", "markdown": { "content": "Real time new user feedback<font color=\"warning\">132 example</font>,Please pay attention to relevant colleagues.\n >type:<font color=\"comment\">User feedback</font> >General user feedback:<font color=\"comment\">117 example</font> >VIP User feedback:<font color=\"comment\">15 example</font>" } }
parameter | Required | explain |
---|---|---|
msgtype | yes | The message type is fixed as markdown at this time |
content | yes | The maximum length of the markdown content is 4096 bytes, which must be utf8 encoded |
Reason for use: there are few parameters and the content length is long.
Abnormal alarm robot code:
@Component @Slf4j public class ExceptionMsgBot { private static final String METHOD_GET = "GET"; private static final String METHOD_POST = "POST"; /** * Enterprise micro robot webhook address */ @Value("${ExceptionMsgBot.url}") private String url; /** * Enable */ @Value("${ExceptionMsgBot.isEnable:true}") private Boolean isEnable; /** * Maximum length */ @Value("${ExceptionMsgBot.maxSize:2500}") private int maxSize; public void send(Exception e, HttpServletRequest request) { if (!isEnable) { return; } String title = "title"; //time String now = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMAT); //Request url String api = request.getRequestURL().toString(); //Request parameters String params = JSONUtil.toJsonStr(request.getAttribute("params")); if (!StringUtils.isEmpty(params)) { //Convert json to normal string params = params.replace("\"","\\\""); } //Server IP String serverIP = NetUtil.getLocalhostStr(); //Client IP String clientIP = request.getRemoteAddr(); String textMsg = "{\n" + " \"msgtype\": \"markdown\",\n" + " \"markdown\": {\n" + " \"content\": \"" + title + "\\n\n" + " [url]: " + api + " \n" + " [[parameter]: " + params + " \n" + " [[time]: " + now + " \n" + " [serverIp]: " + serverIP + " \n" + " [clientIp]: " + clientIP + " \n" + " [message]: " + e.getMessage() + " \n" + " [cause]: " + e.getCause() + " \n" + " [StackTrace]: " + e + " \"\n" + " }\n" + "}\n"; //send message HttpResponse response = HttpRequest .post(url) .header(Header.CONTENT_TYPE, "application/json; charset=UTF-8") .body(textMsg) .execute(); log.info("[Exception message sending result] {}", response.body()); } }
The abnormal information of this design mainly shows 8 points
- Request interface path
- Request parameters
- current time
- Server ip
- Client ip
- e.message
- e.cause
- e.stack
Except that the request parameters need special processing, other parameters can be easily obtained.
Because every time the interface is requested, there will be a global log section class in the project to print out the information of each request.
This global log aspect class will intercept before entering the controller, so that the parameters of each request can be obtained. Then the parameters are encapsulated in the request and passed to the internal web container for use, that is, the abnormal alarm robot in this article.
@Aspect @Configuration @Slf4j public class GlobalControllerLogAspect { @Pointcut("execution (* com.*..controller..*.*(..))") public void controllers() { } @Around("controllers()") public Object aroundProcess(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); long startTime = System.currentTimeMillis(); Object proceed = null; try { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String uid = request.getHeader(HeaderConstant.UID); List<Object> params = new ArrayList<>(); if (args != null && args.length > 0) { for (Object arg : args) { if (arg instanceof HttpServletRequest || arg instanceof HttpServletResponse) { continue; } else if (arg instanceof MultipartFile) { continue; } else { params.add(arg); } } } //Save request parameters request.setAttribute("params", JSONUtil.toJsonStr(params)); log.info("Interface method:{},uid:{},Request parameters:{}", request.getRequestURL().toString(), uid, JSONUtil.toJsonStr(params)); proceed = joinPoint.proceed(args); log.info("Response result:{},Time consuming:{}ms", JSONUtil.toJsonStr(proceed), System.currentTimeMillis() - startTime); } finally { } return proceed; } }
The request parameters can be obtained at the joinPoint.
The abnormal alarm robot is buried in the global abnormal interceptor
@ControllerAdvice @Slf4j public class GlobalExceptionHandler { @Autowired private ExceptionMsgBot bot; @ExceptionHandler(value = Exception.class) public void handle(Exception e, HttpServletRequest request, HttpServletResponse response) { log.error("Interface[{}]abnormal, ", request.getRequestURI(), e); CommonResult<Object> result = CommonResult.failed("There is a small problem with the system"); //Buried point bot.send(e, request); String json = JSONUtil.toJsonStr(result); response.setHeader("Content-Type", "application/json; charset=UTF-8"); try { response.getWriter().write(json); } catch (IOException ex) { log.error("Interface[{}]IO abnormal, ", request.getRequestURI(), ex); } } }
When abnormal information is captured by the global exception interceptor, save the exception log and send alarm information to notify relevant personnel such as developers for handling.
effect:
Abnormal alarm, please pay attention to relevant colleagues! [url]: http://172.18.139.x:9001/xxx [[parameter]: ["uid",{"f1":9,"f2":2,"f3":2377,"f4":false,"f5":"","f6":1}] [[time]: 2022-04-14 16:35:28 [serverIp]: 172.18.139.x [clientIp]: 172.18.139.x [message]: xxx Cannot be empty [cause]: null [StackTrace]: com.xxx.common.component.exception.ApiException: xxx Cannot be empty
Perfect~