java向服务器post请求时首部字段content-length的计算方法

本文探讨了Java在发起POST请求时如何处理Content-length字段的问题。针对长表单或大型文档的发送,介绍了两种优化方案:一是预知数据大小时直接设置长度;二是未知数据大小时采用分块传输编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当java向服务器post请求时,首部中有一个Content-length字段,即请求主体中的字节数。首部在主体的前面。不过,要写入首部,需要知道主体的长度,而在写首部的时候可能还不知道主体的长度。正常情况下,对于这个两难的问题。
如图所示
这里写图片描述
Java的解决办法是:对于从HttpURLConnection获取的OutputStream ,将写入此OutputStream的所有内容缓存,直到流关闭。此时它就会知道主体中有多少字节,所以有足够的信息来写入Content-length首部。

这种模式对于响应典型Web表单的短请求很合适。不过,对于非常长的表单或一些SOAP消息,响应时负担会很大。用HTTP PUT发送中等到大型文挡时会很浪费,也很慢。如果Java 通过网络发送第一字节之前,不需要等待写入最后一字节,将会高效得多。

Java 为这个问题提供了两种解决方案。

解决方案1:如果你知道数据的大小,例如使用HTTP PUT上传一个已知大小的文件,可以将数据的大小告诉HttpURLConnection对象。

解决方案2:如果预先不知道数据大小,可以使用分块传输编码方式。在分块传输编码方式中,请求主体以多个部分发送,每个部分都有自己单独的内容长度。要启用分块传输编码方式,只要在连接URL之前将分块大小传入setChunkedStreamingMode()方法(需要服务器支持分块传输编码方式,所以,,除非确实需要,否则不要使用分块传输编码方式)。

如果恰好预先知道请求数据的大小,可以将这个信息提供给HttpURLConnection对象,从而优化连接。如果这样做,Java会立即通过网络将数据以流方式发送。否则,它必须缓存你写入的所有数据来确定内容长度,而且只有在你关闭流之后才能通过网络发送数据。如果知道数据的具体大小,可以将这个数传递给setFixedlengthStreamingMode()方法。由于这个数可能实际大于int所能存储的最大整数(大约21亿个字节,大约200M),所以在Java 7及以后版本中可以使用一个long。

注意两个问题:

  1. Java会在HTTP首部的Content-length字段中使用这个数。不过,如果接下来试图写入的数据多于或少于给出的这个字节数, Java会抛出一个IOException异常。
  2. 流模式确实会妨碍身份认证和重定向。如果给定的URL要求认证或重定向,就会抛出一个HttpRetryException异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值