当从Android应用程序发送POST请求时,重音字符会导致Jackson在对象映射阶段失败,但在使用适用于chrome的Advanced Rest Client插件时工作正常。
这让我相信这个问题与Android代码发送请求的方式有关,但我尝试添加对UTF-8的显式引用但没有成功。当我在执行期间调试过程时,所有值都是正确的。
我在Android上开发了一个应用程序,它连接到一个公开在Spring中实现的端点的服务器。该服务器使用Spring MVC开发,并使用Google App Engine。
特定端点可以接收用户输入的值,其中可以包括重音字符。
有效负载遵循此结构,映射到服务器端的对象:
{
"senderEmail":"<email here>",
"token":"<token here>",
"friendList":["<email here>"],
"base64Value":"<base64 encoded value here>",
"message":"ú"
}
当从REST客户端发送此有效负载时,服务器处理请求并返回200.从Android应用程序发送时,会引发以下异常:
org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver resolveException: Resolving exception from handler [public org.springframework.http.ResponseEntity<java.lang.Object> com.web.controllers.PictureController.postPic(com.web.controllers.viewobjects.PostPicRequest)]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Invalid UTF-8 middle byte 0x22
at [Source: com.google.apphosting.runtime.jetty.RpcConnection$RpcRequestInput@832f7f; line: 1, column: 15] (through reference chain: com.web.controllers.viewobjects.PostPicRequest["message"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid UTF-8 middle byte 0x22
at [Source: com.google.apphosting.runtime.jetty.RpcConnection$RpcRequestInput@832f7f; line: 1, column: 15] (through reference chain: com.web.controllers.viewobjects.PostPicRequest["message"])
发送请求的Android代码(已编辑以供公众查看):
URL url = new URL( URL_POST );
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept-Encoding", "");
String base64Value = "blabla"
//Get JSON
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate(Api.POST_PARAM_BASE64VALUE, base64Value);
jsonObject.accumulate(Api.POST_PARAM_SENDEREMAIL, senderEmail);
jsonObject.accumulate(Api.POST_PARAM_TOKEN, token);
jsonObject.accumulate(Api.POST_PARAM_MESSAGE, message);
//Make array from friends string
String[] allFriendsArray = friendList.split(",");
JSONArray friendsJsonArray = new JSONArray();
for(String x : allFriendsArray) {
friendsJsonArray.put(x.trim());
}
jsonObject.accumulate(Api.POST_PARAM_FRIENDLIST, friendsJsonArray);
jsonObject.accumulate(Api.POST_PARAM_ISANONYMOUS, isAnonymous);
DataOutputStream wr = new DataOutputStream(urlConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
int httpResponseCode = urlConnection.getResponseCode();
在Android中使用以下代码时得到相同的响应:
HttpPost httpPost = new HttpPost(Api.URL_POST);
httpPost.setEntity(new StringEntity(jsonObject.toString()));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse resp = new DefaultHttpClient().execute(httpPost);
Spring方法定义,它包含在用@RestController注释的控制器中:
@RequestMapping(value= "/post", method = RequestMethod.POST)
public ResponseEntity<Object> post(@RequestBody PostRequest postRequest) { /*code here*/}
答案 0 :(得分:0)
找到以下代码片段(here),它们正确编码了有效负载,并在服务器端也正确接收。
谢谢大家!
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write( jsonObject.toString() );
writer.close();
os.close();
int httpResponseCode = urlConnection.getResponseCode();