Spring returns 在 POST 中使用重音字符时为 400
Spring returns 400 when using accented character in POST
问题:
当从 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 客户端发送此有效负载时,服务器会很好地处理请求并且 returns 一个 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 代码(为 public 查看而编辑):
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*/}
找到以下代码片段 (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();
问题:
当从 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 客户端发送此有效负载时,服务器会很好地处理请求并且 returns 一个 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 代码(为 public 查看而编辑):
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*/}
找到以下代码片段 (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();