OutputStreamWriter的flush方法在尝试写入汉字时抛出IOException
下面是我用来在 Android 应用程序中发送 SOAP 请求的代码,它可以很好地处理除一个请求之外的所有请求。当 requestBody
变量中存在中文字符时,此代码会在 wr.flush();
上抛出 IOException : Content-length超过。
在这种情况下,内容长度是 409
URL url = new URL(Constants.HOST_NAME);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Modify connection settings
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("SOAPAction", soapAction);
String requestBody = new String(soapRequest.getBytes(),"UTF-8");
int lngth = requestBody.length();
connection.setRequestProperty("Content-Length", (""+lngth));
// Enable reading and writing through this connection
connection.setDoInput(true);
connection.setDoOutput(true);
// Connect to server
connection.connect();
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
wr.write(requestBody);
wr.flush();
wr.close();
当字符串中存在中文字符时,有什么线索会出现问题吗?
编辑:我已经删除了“内容长度”标头字段并且它有效,但为什么呢?
Below is the code I am using to send SOAP requests in my Android app and it works fine with all requests except one. This code throws IOException : Content-length exceeded on wr.flush();
when there are chinese characters in requestBody
variable.
The content-length in that case is 409
URL url = new URL(Constants.HOST_NAME);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Modify connection settings
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
connection.setRequestProperty("SOAPAction", soapAction);
String requestBody = new String(soapRequest.getBytes(),"UTF-8");
int lngth = requestBody.length();
connection.setRequestProperty("Content-Length", (""+lngth));
// Enable reading and writing through this connection
connection.setDoInput(true);
connection.setDoOutput(true);
// Connect to server
connection.connect();
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
wr.write(requestBody);
wr.flush();
wr.close();
Any clue what is going wrong when there are chinese characters in the string?
EDIT: I have removed the 'content-lenght' header field and it works, but why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
此代码将请求的 Content-Length 属性设置为消息的字符串表示形式中的字符数:
但随后您在写入之前将该字符串表示形式转换回字节:
因此,您最终会写入比您声明的字节更多的字节。对于任何非 ASCII 字符,您都会遇到同样的问题。相反,您应该执行类似的操作(复制粘贴,因此可能存在语法错误):
This code sets the request's Content-Length property to the number of characters in the string representation of the message:
But then you convert that string representation back to bytes before writing:
So you end up writing more bytes then you've claimed. You'll run into the same problem with any non-ASCII characters. Instead, you should do something like this (copy-and-paste, so may have syntax errors):
为了简化另一个答案:Content-Length 必须是以字节为单位的长度,并且您以字符(Java 的 16 位字符类型)指定长度。一般来说,这些是不同的。由于 UTF-8 是一种可变字节长度编码,因此超出基本 7 位 ASCII 范围的任何内容都存在差异。另一个答案显示了编写代码的正确方法。
To simplify the other answer: Content-Length MUST be length in bytes, and you are specifying length in chars (Java's 16-bit char type). These are different, in general. Since UTF-8 is a variable-byte-length encoding, there is difference for anything beyond basic 7-bit ASCII range. The other answer shows proper way to write code.
我的猜测是你没有将中文转换为utf-8。如果您支持用户在字段中输入双宽和扩展字符集,则需要确保将输入从这些字符集(ASCII、UNICODE 或 UCS)转换为 UTF-8。
一旦确定了正在使用的字符编码,您可以使用以下内容:
参考
创建用于读/写的流以在两者之间进行转换时。
另一种选择是研究设置控制 http 请求语言的请求属性。我对此了解不多。
My guess is that you have not converted the chinese to utf-8. If you support users entering doublewide and extended character sets into your fields, you'll need to make sure to convert your inputs from those character sets (ASCII, UNICODE or UCS) to UTF-8.
Once you determine the character encodings you are working with, you can use something like:
Reference
when creating your streams for reading/writing to convert between two.
Another alternative is to look into setting the request property controlling the language of the http request. I do not know much about that.