栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java HttpServletRequest拷贝解决HttpServletRequest 中流只能读取一次的问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java HttpServletRequest拷贝解决HttpServletRequest 中流只能读取一次的问题

目录
      • 一、遇到的问题:
      • 二、原因:
      • 三、解决办法:
      • 四、测试:

一、遇到的问题:

接口上传了一个文件,从HttpServletRequest 中获取了文件名、文件内容等信息,后面再从HttpServletRequest 中读取文件名信息、文件内容就读取不到了

二、原因:

因为流是单向的,就像水一样被舀了一瓢就会少一瓢。所以 HttpServletRequest 对象中的 InputStream 或者 Reader 只能使用一次。

三、解决办法:

那该怎么办,复制一份HttpServletRequest 对象,把流转为字节数组存储,使用时再从字节数组中获取,可以解决。

1.用到以下依赖将输入流转化为字节数组:


    commons-io
    commons-io
    2.11.0

2.MyHttpServletRequest类继承HttpServletRequestWrapper:

import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;

public class MyHttpServletRequest extends HttpServletRequestWrapper {

    private byte[] body;

    public MyHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        try {
            body = IOUtils.toByteArray(request.getInputStream());
        } catch (IOException ex) {
            body = new byte[0];
        }
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            ByteArrayInputStream bais = new ByteArrayInputStream(body);

            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }

}
四、测试:

测试里用到以下依赖来获取文件信息:


    commons-fileupload
    commons-fileupload
    1.3.2

public void addNewAttachment(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //将request转化为newRequest,便可以使用newRequest多次读取流了
        HttpServletRequest newRequest = new MyHttpServletRequestWrapper(request);
    
    	//第一次读取
      	FileItemFactory firlfact1 = new DiskFileItemFactory();
        ServletFileUpload sfu1 = new ServletFileUpload(firlfact1);
        List list1 = sfu1.parseRequest(newRequest);
        for (FileItem fileItem : list1) {
               DiskFileItem diskFileItem = (DiskFileItem) fileItem;
               String fileName = diskFileItem.getName();
               System.out.println(fileName);
        }
    
    	//第二次读取
      	FileItemFactory firlfact2 = new DiskFileItemFactory();
        ServletFileUpload sfu2 = new ServletFileUpload(firlfact2);
        List list2 = sfu1.parseRequest(newRequest);
        for (FileItem fileItem : list2) {
               DiskFileItem diskFileItem = (DiskFileItem) fileItem;
               String fileName = diskFileItem.getName();
               tem.out.println(fileName);
        }
    
}

参考:
How to read request.getInputStream() multiple times
HttpServletRequestWrapper example – read httpservletrequest twice

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/922035.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号