我正在使用Spring并尝试在我的控制器中对@ResponseBody进行ajax调用。
更新
好的,我把我告诉的更改添加到了我的ajax设置中。 我的参数" jtSearchParam"在IE中仍然存在相同的编码问题。 +我收到另一个错误,406,响应Header的内容类型错误。
这是我的新代码
控制器:
@RequestMapping(method = RequestMethod.POST, consumes="application/json; charset=utf-8", produces="application/json; charset=utf-8")
public @ResponseBody JSONObject getUsers(@RequestParam int jtStartIndex, @RequestParam int jtPageSize,
@RequestParam String jtSorting, @RequestParam String jtSearchParam,
HttpServletRequest request, HttpServletResponse response) throws JSONException{
Gson gson = new GsonBuilder()
.setExclusionStrategies(new UserExclusionStrategy())
.create();
List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam);
Type userListType = new TypeToken<List<User>>() {}.getType();
String usersJsonString = gson.toJson(users, userListType);
int totalRecordCount = userDao.getAmountOfRows(jtSearchParam);
usersJsonString = "{\"Message\":null,\"Result\":\"OK\",\"Records\":" + usersJsonString + ",\"TotalRecordCount\":" + totalRecordCount + "}";
JSONObject usersJsonObject = new JSONObject(usersJsonString);
return usersJsonObject;
}
因为您看到我在produces
中设置了内容类型,但这并没有帮助。
如果我调试响应头它看起来像这样:
(这导致浏览器无法接受406)
我的新ajax设置:
...
headers: {
Accept : "application/json; charset=utf-8",
"Content-Type": "application/json; charset=utf-8"
},
contentType: "application/json; charset=utf-8",
mimeType:"application/json; charset=UTF-8",
cache:false,
type: 'POST',
dataType: 'json'
...
我的参数在IE中看起来仍然相同!
答案 0 :(得分:5)
好的,json内容类型的问题可以像这样解决:
使用ResponseEntity,您可以更改响应头的内容类型,这样ajax可以正确解释json对象,并且您不会收到406 Http错误。
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<String> getUsers(@RequestParam int jtStartIndex, @RequestParam int jtPageSize,
@RequestParam String jtSorting, @RequestParam String jtSearchParam,
HttpServletRequest request, HttpServletResponse response) throws JSONException{
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "application/json; charset=utf-8");
Gson gson = new GsonBuilder()
.setExclusionStrategies(new UserExclusionStrategy())
.create();
List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam);
Type userListType = new TypeToken<List<User>>() {}.getType();
String usersJsonString = gson.toJson(users, userListType);
int totalRecordCount = userDao.getAmountOfRows(jtSearchParam);
usersJsonString = "{\"Message\":null,\"Result\":\"OK\",\"Records\":" + usersJsonString + ",\"TotalRecordCount\":" + totalRecordCount + "}";
return new ResponseEntity<String>(usersJsonString, responseHeaders, HttpStatus.OK);
}
编码问题可以这样解决:
IE不会对您的“ü,ä等”进行编码正确地说,它只是将它添加到你的URL中:“jtSearchParam =wü”但它实际上应该是这样的:“jtSearchParam = w%C3%BC”(如果它不是你会得到编码错误使用IE时的服务器端
因此,无论您在网址中添加某些值,请务必在实际将其添加到网址之前对该值使用JavaScript方法encodeURI
例如:
encodeURI(jtSearchParam)
答案 1 :(得分:3)
我可以在纯文本和json
之间找到您正在使用的内容类型的冲突dataType: 'json'
contentType: "text/html; charset=utf-8"
我建议您在标题和内容类型中使用json的所有部分application/json
也可以在messageConverters中添加jackson jars,它会将java对象转换为json,只需要更改返回类型@ResponseBody String
到@ResponseBody User
,而User是一个pojo bean,包含属性的getter和setter。
答案 2 :(得分:2)
参数编码问题
我可以想象出现这种情况的两个原因:
CharacterEncodingFilter
CharacterEncodingFilter
解决了Spring用户遇到的大多数编码问题。它必须是web.xml
中的第一个过滤器。
<filter>
<filter-name>encodingfilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果您计划使用GET请求并使用Tomcat,请确保服务器配置中的Connector
元素具有属性URIEncoding="utf-8"
。其他服务器可能需要也可能不需要类似的设置。
JSON返回问题
这就像将Jackson Mapper
添加到类路径并将@ResponseBody
添加到方法的返回类型一样简单。在你的情况下,我建议创建一个类似于你的JSON响应的Message
类。在最简单的情况下,您的方法可能如下所示:
public @ResponseBody Message getUsers(int jtStartIndex, jtPageSize, String jtSorting, String jtSearchParam) {
List<User> users = userService.findUsers(jtStartIndex ,jtPageSize, jtSorting, jtSearchParam);
int totalRecordCount = userDao.getAmountOfRows(jtSearchParam);
Message message = new Message();
message.setRecords(users);
message.setTotalRecordCount(totalRecordCount);
return message;
}
我故意省略了@RequestParam
,因为当方法的参数与请求参数具有相同的名称时,通常不需要它。
如果您使用jQuery,那么响应的实际content-type
几乎不重要,只要内容可以成功解析为JSON。但是,使用dataType: 'json'
来阻止jQuery做出错误的猜测。
如果您使用content-type
,produces
确实很重要。如果你不需要它来缩小请求映射,我建议摆脱它。
答案 3 :(得分:0)
我会检查以确保它正在调用你的json方法,因为可能还有另一个类似的方法是返回text / html。