当前位置:网站首页>【实习】解决请求参数过长问题
【实习】解决请求参数过长问题
2022-07-02 18:54:00 【王六六的IT日常】
又要解决bug啦!!!
由于前端传过来的json数据过长导致请求参数太长,最后出现空指针异常。
HTTP/1.1 414 Request-URI Too Large
解决方法:
参考:Java使用GZIP进行压缩和解压缩(GZIPOutputStream,GZIPInputStream)
使用gzip压缩/解压缩字符串
一、使用gzip压缩字符串(str 要压缩的字符串)

①
参考:
Java ByteArrayOutputStream类
//创建一个32字节(默认大小)的缓冲区
ByteArrayOutputStream out = new ByteArrayOutputStream();
源码:
②
//创建具有默认缓冲区大小out的新字节数组输出流对象。
GZIPOutputStream gzip = new GZIPOutputStream(out);
参考:
Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07
源码:
创建具有默认缓冲区大小的新输出流。
新的输出流实例是通过调用2参数构造函数GZIPOutputStream(out,false)创建的。

使用默认缓冲区大小和指定的刷新模式创建新的输出流。
参数:
out–输出流syncFlush–如果此实例的继承flush()方法的调用为true,则使用flush mode Deflater刷新压缩器。在刷新输出流之前进行SYNC\u刷新,否则仅刷新输出流.
③
gzip.write(str.getBytes());
getBytes() 是Java编程语言中将一个字符串转化为一个字节数组byte[]的方法。
//getBytes() 源码:
public byte[] getBytes() {
return StringCoding.encode(value, off:0, value.length);
}
write源码:
将b.length字节写入此输出流。
FilterOutputStream的write方法使用参数b、0和b.length调用其三个参数的write方法。
注意,该方法不使用单参数b调用其底层流的单参数write方法。
其三个参数的write方法源码:
从偏移量off开始,将指定字节数组中的len字节写入此输出流。
FilterOutputStream的write方法调用每个字节上一个参数的write方法进行输出。
请注意,此方法不会使用相同的参数调用其底层输入流的write方法。FilterOutputStream的子类应提供此方法的更有效实现。
将指定的字节写入此输出流。
FilterOutputStream的write方法调用其底层输出流的write方法,即执行。写入(b)。实现OutputStream的抽象写入方法。
将指定的字节写入此输出流。
写入的一般约定是将一个字节写入输出流。要写入的字节是参数b的八个低位。忽略b的24个高位。OutputStream的子类必须提供此方法的实现。
④
if (gzip != null) {
try {
gzip.close();
} catch (IOException e) {
e.printStackTrace();
}
}
close源码:
将剩余的压缩数据写入输出流并关闭底层流。
private boolean closed = false;
boolean usesDefaultDeflater = false;

将压缩数据写入输出流而不关闭底层流。
当对同一输出流连续应用多个过滤器时,请使用此方法。
关闭压缩机并丢弃任何未处理的输入。当压缩器不再使用时,应调用此方法,但也将由finalize()方法自动调用。调用此方法后,Deflater对象的行为未定义。
关闭此输出流并释放与此流关联的任何系统资源。
关闭的一般约定是关闭输出流。关闭的流无法执行输出操作,也无法重新打开。
OutputStream的close方法不起任何作用。
⑤
//编码-压缩
return new sun.misc.BASE64Encoder().encode(out.toByteArray());
参考:
- sun.misc.BASE64Encoder详解
- base64编码解码及sun.misc.BASE64Decoder的用法
- 关于Base64编码(Encode)与解码(Decode)的几种方式,这里面有道道
在JAVA中要实现Base64的编码和解码是非常容易的,因为JDK中已经有提供有现成的类:
//编码:
String src ="BASE64编码测试";
sun.misc.BASE64Encoder en = new sun.misc.BASE64Encoder();
String encodeStr = en.encode(src.getBytes());
//解码:
sun.misc.BASE64Decoder dec = newsun.misc.BASE64Decoder();
byte[] data = dec.decodeBuffer(decodeStr);

二、使用gzip解压缩(compressedStr 压缩字符串)


①
//初始化,建立默认大小的缓冲分区
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = null;
GZIPInputStream ginzip = null;
byte[] compressed = null;
String decompressed = null;
②
//decodeBuffer()解码
compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
③
in = new ByteArrayInputStream(compressed);
创建ByteArrayInputStream,以便使用buf作为其缓冲区数组。未复制缓冲区阵列。pos的初始值为0,count的初始值为buf的长度。
④
ginzip = new GZIPInputStream(in);
创建具有默认缓冲区大小的新输入流。
⑤
while ((offset = ginzip.read(buffer)) != -1) {
out.write(buffer, 0, offset);
}
最多读取字节。将此输入流中的数据长度字节设置为字节数组。此方法会阻塞,直到有一些输入可用。
该方法只执行调用读取(b,0,b.length)并返回结果。重要的是,它不适用于。改为(b);FilterInputStream的某些子类取决于实际使用的实现策略。
从该输入流中读取多达len个字节的数据到一个字节数组中。如果len不为零,该方法将阻塞,直到有一些输入可用;否则,不读取任何字节,并返回0。
此方法仅在中执行。读取(b,off,len)并返回结果。
参数:
b–读取数据的缓冲区。off–目标阵列b len中的开始偏移量–读取的最大字节数。
从偏移量off开始,将指定字节数组中的len字节写入此字节数组输出流。
⑥
//转换为String类型
decompressed = out.toString();
针对java,注意:
- 如果项目的JDK版本小于1.8,请使用org.apache.commons.codec.binary.Base64;
- 如果项目的JDK版本大于1.8,请使用java.util.Base64;
- 使用org.apache.commons.codec.binary.Base64时,要选择与项目JDK相符的JAR包,否则实现不了效果;
- java.util.Base64与org.apache.commons.codec.binary.Base64包冲突,不能同时存在一个类中;
- 注意,UTF-8和GBK中文格式的Base64编码结果是不同的。
三、修改service实现类-Json转换为sql方法中conditionJson的压缩格式
原来:
params.put("conditionJson", URLEncoder.encode(tagInfo.getGenerationLogic(),"UTF-8")); // conditionJson条件json字段 同 生成逻辑字段:generationLogic
修改后: 请求url的时候经过压缩后的参数不会过长
//压缩后的逻辑json
String compressGenerationLogic = CompressUtil.compress(tagInfo.getGenerationLogic());
params.put("conditionJson", URLEncoder.encode(Base64.encodeBase64String(compressGenerationLogic.getBytes()),"UTF-8"));
URLEncoder.encode(String s, String enc):
s–要翻译的字符串。enc–支持的字符编码的名称。
URLEncoder.encode(tagInfo.getGenerationLogic(),"UTF-8")
使用特定的编码方案将字符串转换为application/x-www-form-urlencoded格式。此方法使用提供的编码方案来获取不安全字符的字节。
String encode(String s, String enc)
使用base64算法对二进制数据进行编码,但不将输出分块。
注:我们将该方法的行为从多行分块(commons-codec-1.4)更改为单行非分块(commons-codec-1.5)。
使用base64算法对二进制数据进行编码,可以选择将输出分块为76个字符块。
isChunked–如果为true,则此编码器将base64输出分为76个字符块
使用base64算法对二进制数据进行编码,可以选择将输出分块为76个字符块。
参数:
binaryData–包含要编码的二进制数据的数组。
isChunked–如果为true,则此编码器将base64输出分为76个字符块
urlSafe–如果为true,则此编码器将发出-和_而不是通常的+和/字符。注意:使用URL安全字母表编码时不添加填充。
使用base64算法对二进制数据进行编码,可以选择将输出分块为76个字符块。
参数:
binaryData–包含要编码的二进制数据的数组。
isChunked–如果为true,则此编码器将base64输出分为76个字符块
urlSafe–如果为true,则此编码器将发出-和_而不是通常的+和/字符。
注意:使用URL安全字母表编码时不添加填充。
maxResultSize–要接受的最大结果大小。
四、修改Controller的接口
往request中添加条件json—是解压缩后的。
String decodeConditionJson = new String(Base64.decodeBase64(request.getConditionJson()));
request.setConditionJson(CompressUtil.uncompress(decodeConditionJson));
将Base64字符串解码为八位字节:
解码包含N进制字母中字符的字符串。
解码包含N进制字母中字符的字节数组。
发送端在数据发送前的处理流程如下(接收端互逆):
1.先对原始字符串签名,以保证签名忠实于原始内容;
2.然后压缩,以精简内容的尺寸,提高后续加密和传输的效率;
3.最后加密,保证数据安全。
边栏推荐
- 编写完10万行代码,我发了篇长文吐槽Rust
- [译]深入了解现代web浏览器(一)
- 452-strcpy、strcat、strcmp、strstr、strchr的实现
- AcWing 383. 观光 题解(最短路)
- AcWing 1131. Saving Private Ryan (the shortest way)
- Windows2008r2 installing php7.4.30 requires localsystem to start the application pool, otherwise 500 error fastcgi process exits unexpectedly
- Overview of browser caching mechanism
- Dictionaries
- AcWing 1137. 选择最佳线路 题解(最短路)
- 蓝牙芯片ble是什么,以及该如何选型,后续技术发展的路径是什么
猜你喜欢

mysql函数

After writing 100000 lines of code, I sent a long article roast rust

RPD product: super power squad nanny strategy

励志!大凉山小伙全奖直博!论文致谢看哭网友

安装单机redis详细教程
![[NLP] a detailed generative text Abstract classic paper pointer generator](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[NLP] a detailed generative text Abstract classic paper pointer generator

攻防世界pwn题:Recho

KS004 基于SSH通讯录系统设计与实现

Istio1.12: installation and quick start

rxjs Observable 自定义 Operator 的开发技巧
随机推荐
AcWing 1129. Heat wave solution (shortest path SPFA)
KT148A语音芯片ic的用户端自己更换语音的方法,上位机
AcWing 1128. 信使 题解(最短路—Floyd)
Istio1.12:安装和快速入门
Motivation! Big Liangshan boy a remporté le prix Zhibo! Un article de remerciement pour les internautes qui pleurent
Use cheat engine to modify money, life and stars in Kingdom rush
[NLP] a detailed generative text Abstract classic paper pointer generator
esp32c3 crash分析
AcWing 181. 回转游戏 题解(搜索—IDA*搜索)
AcWing 1137. Select the best line solution (the shortest circuit)
RPD出品:Superpower Squad 保姆级攻略
Bubble sort array
嵌入式(PLD) 系列,EPF10K50RC240-3N 可编程逻辑器件
AcWing 1125. 牛的旅行 题解(最短路、直径)
Use IDM to download Baidu online disk files (useful for personal testing) [easy to understand]
What is the Bluetooth chip ble, how to select it, and what is the path of subsequent technology development
R language uses econcharts package to create microeconomic or macroeconomic maps, and indifference function to visualize indifference curve
基于SSM实现网上购物商城系统
B端电商-订单逆向流程
Correspondence between pytoch version, CUDA version and graphics card driver version