spring boot MVC wrong encoded POST request

2020-07-28 03:29发布

问题:

I can not make request encoding to work correctly. For encoding to work, i added filter to spring security:

@Bean
public CharacterEncodingFilter characterEncodingFilter() {
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("UTF-8");
    filter.setForceEncoding(true);
    return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(characterEncodingFilter(), CsrfFilter.class);
...
}

Add meta to my pages:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
...

Add UriEnconding to tomcat 8:

<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
   connectionTimeout="20000"
   redirectPort="8443" />

But it is not responding to none of them. When i send a request and debug it, the result is wrong. For example when i send بای as a part of request form, i recieve Ø¨Ø§Û as result. Is there any part of config i am missing?

When sending payload ajax request (with rest client and ofcource to another method) it workes correctly, but no luck with form data. My controller looks like this:

@RequestMapping(value = "/test1")
@ResponseBody
public String test1(@RequestBody String req) {
    return req;
}

@RequestMapping(value = "/test2")
@ResponseBody
public String test2(@RequestParam("search") String req) {
    return req;
}

different tries:

  1. for test1 with Content-Type=application/json it correctly recieves the parameter.
  2. for test2 with Content-Type=application/x-www-form-urlencoded and get method, again everything works great.
  3. for test2 with Content-Type=application/x-www-form-urlencoded and POST method, it returns wrong encoded values.

It seems the problem is with POST method only. any suggestions?

回答1:

After digging into lots of filter chains and moving character encoding in them, finally found the problem. Another filter was changing encoding before Character encoding kick in.

I just get filter from spring security's hand and add it manually as a bean to do the filtering for me:

@Bean
public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");
    registrationBean.setFilter(characterEncodingFilter);
    return registrationBean;
}

2 days or searching and trying and just a simple answer. What a hard way to find an answer

---UPDATE---

If you are using spring boot 1.2+, there is no need for CharacterEncoding at all. it is in its perfect position by default with character encoding equal to utf8. So next time, just set attributes if there are any! the properties to set are:

# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8 # the encoding of HTTP requests/responses
spring.http.encoding.enabled=true # enable http encoding support
spring.http.encoding.force=true # force the configured encoding

---UPDATE 2---

From Tomcat wiki: In Tomcat 8 starting with 8.0.0 (8.0.0-RC3, to be specific), the default value of URIEncoding attribute on the element depends on "strict servlet compliance" setting. The default value (strict compliance is off) of URIEncoding is now UTF-8. If "strict servlet compliance" is enabled, the default value is ISO-8859-1.

so generally saying, there is no need to set the UriEncoding in Tomcat Config neigter.