2

I'm having some issues including parameters with special characters in a <s:url/> struts2 tag.

Params inside a <s:form/>, either as hidden or explicit fields are behaving just fine although some can have special characters, but the trouble comes when I try to append any param which contains special characters (in this case 'é') to a struts2 URL and trigger an action with it.

This is the <s:url/>:

<s:url var="urlRegular" action="fetchUserServices" escapeAmp="false">
    <s:param name="username" value="%{username}" />
    <s:param name="type" value="%{type}"/>
</s:url>

Debugging with Eclipse, whenever the method fetchUserServices is called, the parameter username, which should be 'cInglés', appears to be stored as 'cInglés' , and thus I guess it's not decoded properly from UTF-8 comming from the HTTP request.

Inside the HTTP request I can see the parameter username is encoded and sent like this:

myPath/fetchUserServices.action?username=cIngl%C3%A9s&type=1

So, it appears to me that it's successfully sent to the controller from the view..

I have also tried specifying the username parameter like this, but with no luck:

<s:url var="urlRegular" action="fetchUserServices" escapeAmp="false">
    <s:param name="username" >
      <s:property value="%{username}" />
    </s:param>
    <s:param name="type" value="%{type}"/>
</s:url>

this just changes the way it behaves, and if I use that notation, the param is now encoded on the url like this (XHR request):

myPath/fetchUserServices.action?username=%5BcIngl%26eacute%3Bs%5D&type=1

And my fetchUserServices method receives it this way: cIngl&\eacute;s (without the '\', I had to use it because markdown language used here decodes it as cInglés).

At this point I'm a little bit lost, all my pages specify UTF-8 encoding and params with special characters aren't an issue when they go inside a <s:form /> tag.

How can I fix this and have my parameter decoded on my fetchUserServices method?


Question update: Tried this solution here which suggests using the Spring character encoding filter but it didn't work either.

JorgeGRC
  • 1,032
  • 2
  • 18
  • 37
  • Using tomcat? https://struts.apache.org/docs/how-to-support-utf-8-uriencoding-with-tomcat.html – Aleksandr M Oct 01 '15 at 17:29
  • @AleksandrM I'll definitely try this, but I don't understand why parameters get decoded successfully when inside `` tags (hidden or not). If it was a ´tomcat´ issue, wouldn't them have to fail decoding too? – JorgeGRC Oct 02 '15 at 07:13
  • @AleksandrM didn't work.. parameter is still decoded as I declared on my question.. Maybe this has to do with the nature of the request. It's made using `AJAX` for loading the contents of a dinamic tab and it aims to the `URL` I posted on my question. – JorgeGRC Oct 02 '15 at 07:23
  • POST parameters are not affected by uriencoding. Can you try with plain link w/o ajax to eliminate this part. – Aleksandr M Oct 02 '15 at 07:58
  • The parameters are encoded by default , but if you not output them to the response you can disable this parameter. – Roman C Oct 02 '15 at 08:33
  • thanks for your help @AleksandrM and Roman , always there for us ;). I've finally managed to solve the issue and posted an answer to help others facing the same problem. – JorgeGRC Oct 02 '15 at 08:50

1 Answers1

1

Finally I managed to get it to work. All I had to do was to specify the URI encoding in the connector at port 8080, where my tomcat handles the requests.

The version I'm using is tomcat7, and all I had to do was to add URIEncoding = "UTF-8" so now it looks like this:

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

Also, it is possible to specify a character encoding filter, for instance, the one provided by Spring. All you have to do is add this as the first filter in your 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>

This was not mandatory for me, as only stating the URI encoding worked out, didn't need to include the filter too, but I have read over the net that it can help.


Regarding the lack of understanding why it would work using POST requests and don't with the GET ones, I've learnt that POST requests specify the character encoding on their own, while the others don't. Quoted from tomcat apache wiki:

What is the default character encoding of the request or response body?

If a character encoding is not specified, the Servlet specification requires that an encoding of ISO-8859-1 is used. The character encoding for the body of an HTTP message (request or response) is specified in the Content-Type header field. An example of such a header is Content-Type: text/html; charset=ISO-8859-1 which explicitly states that the default (ISO-8859-1) is being used.

And finally, there is very elaborated answer here that addresses this issue and can help if you need more advanced help (it covers the point of using mysql and having the need of allowing UTF-8 decoding too)

Community
  • 1
  • 1
JorgeGRC
  • 1,032
  • 2
  • 18
  • 37