HttpServletRequestWrapper写过滤器遇到的中文部分乱码问题解决

原开发需求
原需求是需要开发一个全局过滤器,需要对请求体重的内容进行过滤,如果出现特定字符需要阻拦请求。
实现
代码第一版对body数据的读取如下:

String data= req.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

出现问题:第一版对于body数据的读取没有问题,但是后续的请求都获取不到请求体的内容了,后面是了解到请求体内容只能读取一次,需要重写HttpServletRequestWrapper保存request中的inputStream内容。
代码第二版读取内容参考如下文章:添加链接描述

为了方便解释上诉文章部分核心代码会放到该文章中

构造函数中主要是:

isr = new BufferedReader(new InputStreamReader(ins));
char[] charBuffer = new char[1024];
int readCount = 0;
while ((readCount = isr.read(charBuffer)) != -1) {
    sb.append(charBuffer, 0, readCount);
}

getReader

public BufferedReader getReader() throws IOException {
    return new BufferedReader(new InputStreamReader(this.getInputStream(),"ISO-8859-1"));
}

getInputStream

ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());

具体body请求变成如下:

ServletRequest requestWrapper = new BodyReaderRequestWrapper(req);
String data = requestWrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

出现问题:请求参数出现部分中文乱码,如果中文内容为双数,则正常,如果是单数,单数的那个中文会出现乱码,实际推测是编码问题。后面经证实确实属于编码问题。
报文打印出现如下情况
三个字:测测测
问题实际打印
分析
请求进入过滤器,查看并测试报文请求入参编码是ISO-8859-1,天然的我给构造函数里面的

new InputStreamReader(ins)

改成了

new InputStreamReader(ins,"ISO-8859-1")

实际测试打印出来的数据能通过以下代码正常输出三个测字

new String(str.getBytes("ISO-8859-1"), Charset.forName("UTF-8"))

但是实际是以下代码获取的还是乱码一堆

String data = requestWrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator()));

在构造函数正确的情况下,能通过测试代码正常输出中文,那就是取值存在问题,我把上句代码改成以下方便测试

String data = requestWrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
data = new String(data.getBytes("ISO-8859-1"), Charset.forName("UTF-8"));
System.out.println(data);

经再次分析问题可能就是出在了getReader,然后getReader又是调用的getInputStream,所以我将getInputStream改成

ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes("ISO-8859-1"));

经过测试还是同样的报错,依旧乱码,这回只能去一个个debug看,结果发现InputStreamReader是默认带编码GBK,所以所有的数据其实全都没带编码的情况下都是GBK,getReader中也是,所以导致问题的发生,然后又要把getReader改成以下,问题解决

return new BufferedReader(new InputStreamReader(this.getInputStream(),"ISO-8859-1"));

以上问题会出现一种情况,就是如果不同的请求参数编码大概率会存在不兼容问题,所以需要修改的,不能直接用,该文只做分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值