Marlon Maxwel
Marlon Maxwel

Reputation: 53

@PathVariable problems with encoding - Spring MVC

I got 1 problem and can not solve. I'm getting a POST request and am getting a variable from RequestMapping, but the encoding is getting it all wrong.

Request URL: 127.0.0.1:8080/projeto/ws/cidade/Uberl%C3%A2ndia

Controller:

@RequestMapping (value = "/city/{name}", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE) 
     public ResponseEntity<?> doGetPath(@PathVariable("name") String name) {
} 

Value returned on @PathVariable("name"): Uberlândia

Correct return: Uberlândia

Can anyone help me?

Upvotes: 1

Views: 8750

Answers (2)

Marlon Maxwel
Marlon Maxwel

Reputation: 53

My solution is: Creating class:

public class UrlPathHelperFixed extends UrlPathHelper {

    public UrlPathHelperFixed() {
        super.setUrlDecode(false);
    }

    @Override
    public void setUrlDecode(boolean urlDecode) {
        if (urlDecode) {
            throw new IllegalArgumentException("Handler does not support URL decoding.");
        }
    }

    @Override
    public String getServletPath(HttpServletRequest request) {
        String servletPath = getOriginatingServletPath(request);
        return servletPath;
    }


    @Override
    public String getOriginatingServletPath(HttpServletRequest request) {
        String servletPath = request.getRequestURI().substring(request.getContextPath().length());
        return servletPath;
    }
}

Change spring-mvc.xml to:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="order" value="-1"></property>
        <property name="urlPathHelper">
          <bean class="br.com.delivery.utils.UrlPathHelperFixed"/>
        </property>
    </bean>

And config maven-compilter to:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
...
<artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>

And

UriUtils.decode(nome, "UTF-8")

Upvotes: 0

Angular University
Angular University

Reputation: 43087

This is due to the character encoding being used by the JVM where the controller is running being different than the encoding used to encode the request.

To see this, take the encoded URL 127.0.0.1:8080/projeto/ws/cidade/Uberl%C3%A2ndia and pass it through http://www.url-encode-decode.com/ with UTF-8, the result is Uberlândia.

But if the decoding is done with ISO-2022-CN, the result is Uberlândia.

To fix this, the string needs to be decoded in the same way that it was encoded.

To change the encoding used by the server in a global way it´s possible to set the encoding used by the JVM to UTF-8, see this answer. The CharacterEncodingFilter would ensure that the content of HTTP requests would be decoded with a given encoding.

Another way is to have the client that sends the request to encode it in the way the server is expecting.

But to avoid these problems in general, you probably want that every component in your system is configured to use UTF-8.

Upvotes: 2

Related Questions