AOP日志切面拦截出现异常:java.lang.IllegalStateException: It is illegal to call this method if the current requ

问题描述

一个下载功能,后端代码出现异常,被AOP的日志切面拦截,出现异常。

具体异常如下:

java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)

	at org.apache.catalina.connector.Request.getAsyncContext(Request.java:1781)

	at org.apache.catalina.connector.RequestFacade.getAsyncContext(RequestFacade.java:1056)

	at javax.servlet.ServletRequestWrapper.getAsyncContext(ServletRequestWrapper.java:431)

	at com.alibaba.fastjson.serializer.ASMSerializer_7_ShiroHttpServletRequest.write(Unknown Source)

	at com.alibaba.fastjson.serializer.ASMSerializer_1_ShiroHttpServletResponse.write(Unknown Source)

	at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333)

	at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:311)

	at com.alibaba.fastjson.serializer.ObjectArrayCodec.write(ObjectArrayCodec.java:118)

	at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:270)

	at com.alibaba.fastjson.serializer.MapSerializer.write(MapSerializer.java:44)

	at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:285)

	at com.alibaba.fastjson.JSON.toJSONString(JSON.java:955)

	at com.XXXX.common.aspect.LogAspect.methodBefore(LogAspect.java:78)

这个异常java.lang.IllegalStateException是Java中的一个表示状态错误的异常。它指示在非异步模式下调用了一个只允许在异步模式下调用的方法。该异常是由Tomcat抛出的。

原因分析

获取请求参数,对参数进行处理,封装到jsonObject对象,执行jsonObject.toJSONString()时,抛出上述异常

Object[] args = joinPoint.getArgs();
this.argsToString(jsonObject, args);

jsonObject.put("方法参数", args);

String logMsg = jsonObject.toJSONString();
log.info(logMsg);

具体的原因是:当参数是servletRequest,ServletResponse,MultipartFile等类型参数,不能进行序列化,否则将出现上述异常

解决方案

对不能进行序列化的入参过滤,这里对servletRequest,ServletResponse,MultipartFile等参数过滤

    /**
     * 参数处理
     */
    private void argsToString(JSONObject jsonObject, Object[] args) {
    
    
        // 检查参数是否包含servletRequest,ServletResponse,MultipartFile等参数,其不能被序列化
        boolean parameterExclude = Arrays.stream(args).anyMatch(arg -> arg instanceof MultipartFile || arg instanceof ServletResponse || arg instanceof ServletRequest);
        if (parameterExclude) {
    
    
            StringBuilder fileInfo = new StringBuilder();
            Arrays.stream(args).filter(arg -> arg instanceof MultipartFile).forEach(file -> {
    
    
                MultipartFile multipartFile = (MultipartFile) file;
                String fileName = multipartFile.getOriginalFilename();
                long fileSize = multipartFile.getSize();
                fileInfo.append("【文件名:").append(fileName).append(" ,文件大小: ").append(fileSize).append("】");
            });
            jsonObject.put("方法参数", fileInfo);
        } else {
    
    
            jsonObject.put("方法参数", args);
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_38628046/article/details/131599600
今日推荐