5

我正在使用 Spring 并尝试在我的控制器中对 @ResponseBody 进行 ajax 调用。

更新

好的,我将我被告知的更改添加到我的 ajax 设置中。我的参数“jtSearchParam”在 IE 中仍然存在相同的编码问题。+ 我收到另一个错误,406,响应标头的内容类型错误。

这是我的新代码

控制器:

@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 Not Acceptable)

响应头

还有我的新 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 中看起来还是一样的!

IE 调试值

4

4 回答 4

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 时的服务器端)

因此,无论何时向 URL 添加某些值,请确保encodeURI在实际将其添加到 URL 之前对该值使用 JavaScript 方法 示例:

encodeURI(jtSearchParam)

于 2013-05-02T06:40:38.137 回答
3

我可以发现您在纯文本和 json 之间使用的内容类型存在冲突

dataType: 'json'

contentType: "text/html; charset=utf-8"

我建议您将 json 用于 application/json标头和内容类型中的所有部分,也可以在 messageConverters 中添加杰克逊罐子,它会为您将 java 对象转换为 json,只是您需要将返回类型更改@ResponseBody String@ResponseBody User当 User 是pojo bean 包含属性的 getter 和 setter。

于 2013-04-29T07:16:31.943 回答
2

参数编码问题

我可以想象发生这种情况的两个原因:

  1. 由于某种原因,浏览器认为您的页面未以 UTF-8 编码
  2. 你没有包括CharacterEncodingFilter

解决了 Spring 用户遇到的CharacterEncodingFilter大部分编码问题。它必须是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服务器配置中的元素具有 property URIEncoding="utf-8"。其他服务器可能需要也可能不需要类似的设置。

JSON返回问题

这就像添加Jackson Mapper到类路径和@ResponseBody方法的返回类型一样简单。在您的情况下,我建议创建一个Message类似于您的 JSON 响应的类。在最简单的情况下,您的方法可能如下所示:

   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. 如果您不需要它来缩小请求映射的范围,我建议您摆脱它。

于 2013-04-30T19:07:03.867 回答
0

我会检查以确保它正在调用您的 json 方法,因为可能还有另一种类似的方法正在返回 text/html。

于 2013-04-30T19:44:19.223 回答