这个异常是由于在拦截MultipartHttpServletRequest中的body内容后,字符流被关闭导致的。通常情况下,在过滤器中拦截请求的body内容后,需要重新创建一个新的ServletRequest对象,并将原始的ServletRequest对象中的内容复制到新的ServletRequest对象中。

以下是一个示例代码,展示了如何在Shiro的AccessControlFilter中正确处理MultipartHttpServletRequest的情况:

public class MyAccessControlFilter extends AccessControlFilter {

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        // 获取原始的HttpServletRequest对象
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        
        // 判断请求是否为Multipart请求
        if (ServletFileUpload.isMultipartContent(httpServletRequest)) {
            // 创建一个新的MultipartHttpServletRequest对象
            MultipartHttpServletRequest multipartRequest = createMultipartHttpServletRequest(httpServletRequest);
            
            // 将原始的ServletRequest对象中的内容复制到新的MultipartHttpServletRequest对象中
            copyRequestParameters(httpServletRequest, multipartRequest);
            
            // 将新的MultipartHttpServletRequest对象设置到Shiro的Subject中
            Subject subject = SecurityUtils.getSubject();
            subject.getSession().setAttribute(DefaultWebSubjectContext.NATIVE_REQUEST, multipartRequest);
        }
        
        // 继续执行Shiro的filter链
        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        // 继续执行Shiro的filter链
        return true;
    }

    // 创建一个新的MultipartHttpServletRequest对象
    private MultipartHttpServletRequest createMultipartHttpServletRequest(HttpServletRequest httpServletRequest) throws IOException {
        MultipartHttpServletRequest multipartRequest = new DefaultMultipartHttpServletRequest(httpServletRequest);
        return multipartRequest;
    }

    // 将原始的ServletRequest对象中的内容复制到新的MultipartHttpServletRequest对象中
    private void copyRequestParameters(HttpServletRequest httpServletRequest, MultipartHttpServletRequest multipartRequest) throws IOException {
        // 获取原始的请求参数Map
        Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
        
        // 将原始的请求参数Map中的内容复制到新的MultipartHttpServletRequest对象中
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            multipartRequest.getParameterMap().put(name, values);
        }
        
        // 复制原始的请求体内容到新的MultipartHttpServletRequest对象中
        ServletInputStream inputStream = httpServletRequest.getInputStream();
        ServletOutputStream outputStream = multipartRequest.getOutputStream();
        IOUtils.copy(inputStream, outputStream);
        inputStream.close();
        outputStream.close();
    }
}

通过以上代码,在Shiro的AccessControlFilter中,可以正确地处理MultipartHttpServletRequest的情况,避免Stream closed的异常

javaioIOException Stream closed ServletRequestshiro AccessControlFilter 拦截MultipartHttpServletRequest中body内容后字符流关闭

原文地址: http://www.cveoy.top/t/topic/iZiF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录