代码之家  ›  专栏  ›  技术社区  ›  Almas Abdrazak

如果发生异常,则记录http请求正文

  •  2
  • Almas Abdrazak  · 技术社区  · 7 年前

    这是我的休息控制器

    @RequestMapping(value = "owner/login", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
        @ResponseBody
        public ResponseEntity<String> login(@RequestBody Owner owner) throws TimeoutException, SocketTimeoutException, SocketException {
            controller.login(owner);
            return ResponseEntity.ok("\"error\": 0");
        }
    

    这是控制器

     public JsonObject login(Owner loginOwner){
            Map<String,String> params = new HashMap<String,String>();
            params.put("email", loginOwner.getEmail());
            params.put("password", loginOwner.getPassword());
            if(GMoikaStringUtils.isEmpty(loginOwner.getEmail()) || !GMoikaStringUtils.isValidEmail(loginOwner.getEmail())){
                throw new InvalidUserInputException("Wrong email format", CLASS_NAME, "login", params, "owners/owner/login POST");
            }
            else{
                someLogic...
            }
        }
    

    问题是,使用这个结构,我应该在每个方法中创建带有参数的映射。如何避免在每个方法内创建映射,并将所有参数放入该映射?我需要“映射”来显示日志中的参数,以防发生异常。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Dimitri Mestdagh    7 年前

    如果你只想在 InvalidUserInputException 则可以编写异常处理程序:

    @ExceptionHandler(InvalidUserInputException.class)
    @ResponseBody
    public ValidationError getError(InvalidUserInputException ex) {
        // ...
    }
    

    自从 InvalidUserInputException无效用户输入异常 Object 您可以在其中传递请求正文,例如:

    throw new InvalidUserInputException("Wrong email format", loginOwner);
    

    现在您可以使用 toString() Owner Apache commons 以及他们的 ToStringBuilder :

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
            .append("email", email)
            .append("password", password)
            .toString();
    }
    

    toString() HttpServletRequest 作为异常处理程序的参数。

    ContentCachingRequestWrapper .

    总而言之,你应该自己写 Filter 。您可以通过从弹簧 OncePerRequestFilter

    ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
    wrapper.getContentAsByteArray();
    
    @Component
    public class RequestWrapperFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
            filterChain.doFilter(new ContentCachingRequestWrapper(httpServletRequest), httpServletResponse);
        }
    }
    

    getContentAsByteArray() IOUtils 来自Apache Commons:

    ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
    logger.warn("Input validation failed, request body: {}", IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding()));
    

    这将把整个请求主体记录为一个字符串。但要小心记录敏感信息。

        2
  •  1
  •   mohit sharma    7 年前

    并登录 其他的 声明:

    遵循的步骤:

    2.将log4js jar库添加到程序类路径中。



    6.将日志语句放入代码中。

     Logger logger = Logger.getLogger(MyClass.class);
    
    public JsonObject login(Owner loginOwner){
        Map<String,String> params = new HashMap<String,String>();
        params.put("email", loginOwner.getEmail());
        params.put("password", loginOwner.getPassword());
        if(GMoikaStringUtils.isEmpty(loginOwner.getEmail()) || !GMoikaStringUtils.isValidEmail(loginOwner.getEmail())){
            throw new InvalidUserInputException("Wrong email format", CLASS_NAME, "login", params, "owners/owner/login POST");
        }
        else{
            logger.info("Log this event");
        }
    }
    

    请参阅此处: http://www.codejava.net/coding/how-to-configure-log4j-as-logging-mechanism-in-java