记录关于Cause为Stream Closed的FileUploadException

今天在写上传头像和图片模块时,再加上自己的权限拦截器时,在无权限时会抛出异常:

WARN 2018-05-08 20:27:14,198 [http-apr-8080-exec-7] org.springframework.web.multipart.commons.CommonsMultipartResolver: - Failed to perform multipart cleanup for servlet request
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadException: Stream closed

看了看异常描述,大致是CommonsMultipartResolver无法完成清理(cleanup)工作,于是寻找CommonsMultipartResolver中的方法,发现有一个cleanupMultipart()方法,该方法描述如下:

public void cleanupMultipart(MultipartHttpServletRequest request) {
    if (request != null) {
        try {
            cleanupFileItems(request.getMultiFileMap());
        }
        catch (Throwable ex) {
            logger.warn("Failed to perform multipart cleanup for servlet request", ex);
        }
    }
}        

继续追查异常原因,发现是在调用getMultiFileMap()抛出的,其中,当multipartfile变量为null时,会开始一个初始化的动作,这里会调用parseRequest()这个方法,在debug模式下发现request的inputstream

是closed的,于是返回我的权限拦截器,在反复发送请求,发现我的工具类WebDataUtils里的writeJson里有这么一段代码:

try {
        writer = response.getWriter();
    writer.write(JSON.toJSONString(resultMap));
} finally {
     if(writer != null) {
         writer.close();
     }
}

这是在发生IOException时,关闭流的正常操作,但没想到调用了writer的close时,因为response里有一个request的引用,requset的inputstream也一同关闭了,所以导致后面CommonsMultipartResolver

清理时发生了Stream closed的异常。于是在权限拦截器中加入了判断请求是否是multipart请求,如果是,则不关闭流,最后交给CommonsMultipartResolver清理,最终解决了该异常。

猜你喜欢

转载自www.cnblogs.com/cedriccheng/p/9010839.html