当前位置: 代码网 > it编程>编程语言>Java > 如何解决getReader() has already been called for this request问题

如何解决getReader() has already been called for this request问题

2024年06月01日 Java 我要评论
解决getreader() has already been called for this request在 filter 中对 request 中的 body 进行参数签名校验会报如下错误:get

解决getreader() has already been called for this request

在 filter 中对 request 中的 body 进行参数签名校验

会报如下错误:

getreader() has already been called for this request

原因是

request.getreader() 和 request.getinputstream() 都是只能调用一次

并且 getreader() 方法底层也是调用 getinputstream() 来实现的.

所以我们要使用 httpservletrequestwrapper 来实现自定义的 customhttpservletrequestwrapper, 把 body 保存在 customhttpservletrequestwrapper 中, 并且重写 getinputstream() 方法

重写  httpservletrequestwrapper

package com.fosung.pb.village.config;
 
import org.apache.commons.fileupload.servlet.servletfileupload;
 
import javax.servlet.readlistener;
import javax.servlet.servletinputstream;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletrequestwrapper;
import java.io.bufferedreader;
import java.io.bytearrayinputstream;
import java.io.ioexception;
import java.io.inputstreamreader;
import java.nio.charset.standardcharsets;
 
public class myrequestwrapper extends httpservletrequestwrapper {
 
    private byte[] body;
    public myrequestwrapper(httpservletrequest request) throws ioexception {
        super(request);
        if(servletfileupload.ismultipartcontent(request)){
            return;
        }
        stringbuilder sb = new stringbuilder();
        string line;
        bufferedreader reader = request.getreader();
        while ((line = reader.readline()) != null) {
            sb.append(line);
        }
        string body = sb.tostring();
        this.body = body.getbytes(standardcharsets.utf_8);
    }
    public string getbody() {
        return new string(this.body , standardcharsets.utf_8) ;
    }
    @override
    public servletinputstream getinputstream() {
        final bytearrayinputstream bais = new bytearrayinputstream(body);
        return new servletinputstream() {
            @override
            public boolean isfinished() {
                return false;
            }
            @override
            public boolean isready() {
                return false;
            }
            @override
            public void setreadlistener(readlistener readlistener) {
            }
            @override
            public int read(){
                return bais.read();
            }
        };
    }
    @override
    public bufferedreader getreader(){
        return new bufferedreader(new inputstreamreader(this.getinputstream()));
    }
}

filter 使用

package com.fosung.pb.village.config;
 
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.component;
 
import javax.servlet.*;
import javax.servlet.annotation.webfilter;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
 
/**
 * @author lanx
 * @date 2022/4/11
 */
@slf4j
@component
@webfilter(filtername = "antisqlinjectionfilter", urlpatterns = "/*")
public class antisqlinjectionfilter implements filter {
 
    public void destroy() {
        // todo auto-generated method stub
    }
 
    public void init(filterconfig arg0) throws servletexception {
        // todo auto-generated method stub
    }
 
 
    public void dofilter(servletrequest request, servletresponse response,
                         filterchain chain) throws ioexception, servletexception {
        httpservletrequest req = (httpservletrequest) request;
        httpservletresponse res = (httpservletresponse) response;
        myrequestwrapper myrequestwrapper = null;
        // 获取请求body
        try {
            myrequestwrapper = new myrequestwrapper(req);
        } catch (ioexception e) {
            log.error("get request body exception", e);
            throw new runtimeexception(e);
        }
 
        if ("post".equalsignorecase(req.getmethod())) {
            string param = myrequestwrapper.getbody();
            chain.dofilter(myrequestwrapper, response);
        } else {
            chain.dofilter(myrequestwrapper, response);
        }
    }
    
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com