Accentuation of request parameter in JSF page

Asked

Viewed 1,264 times

5

I have a JSF page that receives as a parameter, in the URL, the error message to be displayed. Ex.: http://example.com/application_error.jsf?exception=Não+permitido

On the page, the parameter is displayed as follows:

#{param['exception']}

However, accented characters are wrong.

I am using the Demoiselle framework and the Tomcat 7 server. My pages are UTF-8.

The page in question is the page application_error, to which Demoiselle redirects when a ApplicationException is launched.

How do I fix the accent problem without having to change the character encoding I’m using on my pages?

  • Please try the message encounter before redirecting to the screen: http://stackoverflow.com/questions/5330104/encoding-url-query-parameters-in-java

  • The problem is that it is the framework that redirects when an exception is thrown. When I do the message encounter, some characters are doubly encoded. For example, the message "a b" turns "a+b" and when it redirects, it turns "a%2Bb".

  • I understand... do the Code by javascript then: http://stackoverflow.com/questions/12042592/decoding-ur-parameters-with-javascript

  • It may be, but I’m still looking for a better solution.

2 answers

4


Tomcat considers the entire request to be ISO-8859-1 by default "factory".

The direct and specific solution for Tomcat is to change the server configuration (server.xml):

<Server port="8105" shutdown="SHUTDOWN">
...
    <Service name="Catalina">
        <Connector port="8180" URIEncoding="UTF-8" />
        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" />
        </Engine>
    </Service>
....
</Server>

However, I don’t consider this ideal solution because when you need to do the deploy of its application in an environment controlled by third parties will probably not have access to this change.

A solution that can be implemented in the application itself is divided (at least) into: adjust the encoding in the body of requests, parameters and headers.

To solve the problem for data in the request body, I usually add a filter to the web.xml that forces the encoding to be of a certain type. In a project where I use Spring, the following excerpt solves the problem:

<filter>
    <filter-name>encoding-filter</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>encoding-filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

If you don’t use Spring, you can use apache library code and put the class in its own design.

For data in headers or parameters, we can encapsulate the HttpServletRequest through a filter. I did the implementation below, but I don’t have an application in hand to test, so any problem give me a feedback:

public class ParametersEncodingFilter implements Filter {

    private String charset = "UTF-8";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String charsetParam = filterConfig.getInitParameter("charset");
        if (charsetParam != null && !charsetParam.isEmpty()) {
            this.charset = charsetParam;
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new FilteredRequest(charset, request), response);
    }

    @Override
    public void destroy() {
        //nothing to clean up
    }

    final private static class FilteredRequest extends HttpServletRequestWrapper {

        public FilteredRequest(String charset, ServletRequest request) {
            super((HttpServletRequest)request);

            //convert encoding params
            Map<String, String[]> originalParams = super.getParameterMap();
            for(Object key : originalParams.keySet()) {

                String[] entry = originalParams.get(key);
                for (int i = 0; i < entry.length; i++) {

                    try {
                        entry[i] = new String(entry[i].getBytes("ISO-8859-1"), charset);
                    } catch (UnsupportedEncodingException e) {
                        return; //if can't convert one, it cannot convert any of them
                    }

                }

            }

        }        

    }

}

Note: This implementation considers that the filter has a parameter with the desired encoding, as in the Spring filter settings above.

And one last comment: if it is possible to encode the URL parameters, for example N%C3%A3o%2Bpermitido instead of Não+Permitido, perhaps solve the parameter specific problem without further implementations.

  • I already use this solution to fix an accentuation problem in Forms submission, but for some reason it didn’t work for my current request parameter display problem.

  • @rodrigorgs, have you tried switching browsers? Which one are you testing?

  • I tried in Chrome and Firefox, using Ubuntu; the other accented characters on the page appear ok, the problem is only with what comes from param.

  • I understand, I think the filter I posted doesn’t affect the headers, just the body of the requisition. I believe that a more generic effective solution would be to create a filter with an Httpservletrequestwrapper that does this conversion that you do in Converter. Or, as the tomcat documentation, changes the general configuration of the server. Unfortunately touching this is complicated because your application may present problems in different environments.

  • this Httpservletrequestwrapper solution looks promising. What do you think about developing this solution in your answer?

  • @rodrigorgs Feito.

Show 2 more comments

1

From what I understand, Tomcat decodes GET parameters using ISO-8859-1. As I do not have access to the server configuration, I adopted an outline solution. I created a convert to turn into UTF-8:

@Named
public class EncodingConverter implements Converter {

  @Override
  public Object getAsObject(FacesContext context, UIComponent component,
      String value) {
    return null;
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    String result = null;

    if (value != null) {
      String string = (String)value;
      Charset toCharset = Charset.forName("ISO-8859-1");
      Charset fromCharset = Charset.forName("UTF-8");
      result = new String(string.getBytes(toCharset), fromCharset);
    }

    return result;
  }
}

When displaying the value on xhtml page, step by convert.

<h:outputText value="#{param['exception']}" converter="#{encodingConverter}" />

Browser other questions tagged

You are not signed in. Login or sign up in order to post.