我在我的客户端中使用 Apache HTTP 客户端库和 Jackson。当我将 JSON 发布到服务器时,出现错误:
org.codehaus.jackson.JsonParseException: Invalid UTF-8 middle byte 0x65
at [Source: HttpInputOverHTTP@22a4ac95; line: 1, column: 81]
如果我没有设置任何标题,我会得到invalid media type
,这是有道理的。
如果我使用curl和相同的标头,服务器会接受它,所以我认为服务器没问题(巧合的是它也使用Jackson)
这是文件;我仅使用 8 位字符将其硬编码为 Java 文字,以避免在任何其他地方发生损坏
// "Stra\u00DFe" = "Straße"
static String TINY_UTF8_DOC = "[{ \"id\" : \"2\", \"fields\" : { \"subject\" : [{ \"name\" : \"subject\", \"value\" : \"Stra\u00DFe\" }] } }]";
这是我一直在使用的代码,以及各种尝试的评论:
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost( url );
// Attempt A
// post.setEntity( new StringEntity( content ) );
// Attempt B
// post.setEntity( new StringEntity( content ) );
// post.setHeader("Content-Type", "application/json; charset=utf-8");
// Attempt C
// post.setEntity( new StringEntity( content, ContentType.create("application/json") ) );
// Attempt D
// post.setEntity( new StringEntity( content, ContentType.create("application/json; charset=UTF-8") ) );
// Attempt F
// post.setEntity( new StringEntity( content, ContentType.create("application/json; charset=utf-8") ) );
// Attempt G
// StringEntity params = new StringEntity( content );
// params.setContentType("application/json; charset=UTF-8");
// post.setEntity(params);
// And then send to server
HttpResponse response = httpClient.execute( post );
int code = response.getStatusLine().getStatusCode();
// ...etc...
我注意到的其他奇怪的事情:
- 有一段时间,这在 Mac 上的 Eclipse 上与在 Linux 上运行 .jar 的表现有所不同;显然,这是特定于平台的编码或解码的症状,但我不知道在哪里。讽刺的是broke当我将 Eclipse 设置为将代码视为 UTF-8(相对于 ASCII)时,我怀疑这是一个重要的线索,但不确定它适合在哪里。
- 我见过几次,流中不是 2 个字节,而是 4 个字节,尽管这在写入磁盘时可能是不同的编码问题,尽管我在文件 IO 上专门设置了 UTF-8
- 当我在调试器中查看字符串实体时,我看到了字节,但 8 位字符是负数。当您运行“二人赞美”数学时,它仍然是正确的 Unicode 代码点,因此名义上没问题,假设 httpclient 没有错误。
真的没有想法,正如我所说,它与curl一起工作,所以我认为服务器没问题。
Edit:
发布到服务器时,curl 可以工作,但我无法共享服务器代码。有人指出,由于curl不是用Java编写的,因此它的行为可能有所不同,因此服务器代码仍然值得怀疑。
因此,作为进一步的测试,下面的代码确实NOT使用 Apache httpclient 库,并且在发布到服务器时确实有效。这证明服务器没问题,但我在客户端使用 Apache 库的方式仍然有问题(或者可能有错误)。
非 apache-httpclient 代码,确实有效:
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
class PostUtf8 {
static String POST_URL = "http://...";
// \u00DF = LATIN SMALL LETTER SHARP S, looks like letter B
static String TINY_UTF8_DOC = "[{ \"id\" : \"2\", \"fields\" : { \"subject\" : [{ \"name\" : \"subject\", \"value\" : \"Stra\u00DFe\" }] } }]";
public static void main( String [] args ) throws Exception {
System.out.println( "Posting to " + POST_URL );
URL url = new URL( POST_URL );
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty( "Content-Type", "application/json; charset=UTF-8" );
conn.setRequestMethod("POST");
conn.setDoOutput(true);
OutputStream sout = conn.getOutputStream();
OutputStreamWriter wout = new OutputStreamWriter(sout, "UTF-8" );
wout.write( TINY_UTF8_DOC );
wout.flush();
int result = conn.getResponseCode();
System.out.println( "Result = " + result );
}
}