Spring:在IE中,对@ResponseBody param编码的Ajax调用失败

时间:2013-04-25 13:54:11

标签: jquery ajax spring spring-mvc encoding

我正在使用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)

response header

我的新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 debugged values

4 个答案:

答案 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)

参数编码问题

我可以想象出现这种情况的两个原因:

  1. 由于某种原因,浏览器认为您的网页未以UTF-8编码
  2. 您尚未加入CharacterEncodingFilter
  3. 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-typeproduces确实很重要。如果你不需要它来缩小请求映射,我建议摆脱它。

答案 3 :(得分:0)

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