开发者

OutputStreamWriter's flush method throws IOException when trying to write chinese characters

开发者 https://www.devze.com 2023-02-05 06:24 出处:网络
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 ar

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?


This code sets the request's Content-Length property to the number of characters in the string representation of the message:

String requestBody = new String(soapRequest.getBytes(),"UTF-8");
int lngth = requestBody.length();
connection.setRequestProperty("Content-Length", (""+lngth));

But then you convert that string representation back to bytes before writing:

OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");

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):

byte[] message = soapRequest.getBytes();
int lngth = message.length;
connection.setRequestProperty("Content-Length", (""+lngth));

// ...

connection.getOutputStream().write(message);


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.


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:

FileInputStream(inputFile), "inputencoding");
Writer output = new OutputStreamWriter(new FileOutputStream(outputFile), "outputencoding");

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消