我在我的客户端使用Apache HTTP Client libs和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...
我注意到的其他奇怪的事情:
真的没有想法,正如我所说,它适用于curl,所以我认为服务器没问题。
修改
发布到服务器时,卷曲有效,但我无法共享服务器代码。有人指出,由于curl不是用Java编写的,所以它的行为可能不同,因此服务器代码仍然可能存在疑问。
因此,作为进一步的测试,下面的代码 NOT 使用Apache httpclient库,并且在发布到服务器时DOES工作。这证明服务器很好,而且我在客户端使用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 );
}
}
答案 0 :(得分:13)
看起来问题是如何创建HttpClient的ContentType
构造函数的StringEntity
参数。
使用ContentType.APPLICATION_JSON
常量作为参数(对应于“application / json; charset = utf-8”mime类型)使一切正常。
以下是将JSON字符串发布到公共http服务的示例,该服务将请求发送回客户端:
public class HttpClientEncoding {
static String TINY_UTF8_DOC = "[{ \"id\" : \"2\", \"fields\" : { \"subject\" : " +
"[{ \"name\" : \"subject\", \"value\" : \"Stra\u00DFe\" }] } }]";
public static void main(String[] args) throws IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost("http://httpbin.org/post");
StringEntity entity = new StringEntity(TINY_UTF8_DOC, ContentType.APPLICATION_JSON);
//StringEntity entity = new StringEntity(TINY_UTF8_DOC, ContentType.create("application/json; charset=utf-8"));
post.setEntity(entity);
HttpResponse response = httpClient.execute(post);
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(result, JsonNode.class);
System.out.println(node.get("json").get(0).get("fields").get("subject").get(0).get("value").asText());
}
}
输出:
{
"origin": "46.9.77.167",
"url": "http://httpbin.org/post",
"args": {},
"data": "[{ \"id\" : \"2\", \"fields\" : { \"subject\" : [{ \"name\" : \"subject\", \"value\" : \"Stra\u00dfe\" }] } }]",
"files": {},
"form": {},
"headers": {
"Content-Length": "90",
"User-Agent": "Apache-HttpClient/4.3.3 (java 1.5)",
"Host": "httpbin.org",
"Connection": "close",
"X-Request-Id": "c02864cc-a1d6-434c-9cff-1f6187ceb080",
"Content-Type": "application/json; charset=UTF-8"
},
"json": [
{
"id": "2",
"fields": {
"subject": [
{
"value": "Stra\u00dfe",
"name": "subject"
}
]
}
}
]
}
Straße
答案 1 :(得分:0)
这对我有用:(将“ UTF-8”指定为StringEntity)
Object obj = parser.parse(new FileReader(
"/home/user/paylod.txt"));
org.json.simple.JSONObject jsonObject = (org.json.simple.JSONObject) obj;
StringEntity input = new StringEntity( jsonObject.toString(),"UTF-8");
input.setContentType("application/json");