[v0.10.0][JSP][Spring] Encoding problem

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[v0.10.0][JSP][Spring] Encoding problem

gotian
Hello,

I have problem with encoding in my application. I use dandelion datatables on jsp page. In one of the columns I put  link to download a file. Files are downloaded from servlet like this:

@RequestMapping(value = "/getFileById/{type}/{id:.*}", method = RequestMethod.GET)
        public @ResponseBody
        void download(@PathVariable("type") int type, @PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
                if (!Strings.isNullOrEmpty(id)) {
                        try {
                                xxxFile file = filesRepositoryService.getxxxFileById(id);
                                if (file != null) {
                                        String mimeType = "application/octet-stream";
                            response.setContentType(mimeType);
                            int length = new Long(file.getLength()).intValue();
                            response.setContentLength(length);
                            response.setCharacterEncoding("");
                           
                            if (type == 0) {
                            response.setHeader("content-Disposition", "attachment; filename=" + file.getFilename());
                            } else {
                            response.setHeader("content-Disposition", "inline; filename=" + file.getFilename());
                            }
                            //IOUtils.copyLarge(file.getInputStream(), response.getOutputStream());
                           
                            OutputStream out = response.getOutputStream();
                            FileInputStream in = new FileInputStream(file.getFile());
                            byte[] buffer = new byte[1024];
                            length = 0;
                            while ((length = in.read(buffer)) > 0){
                                out.write(buffer, 0, length);
                            }
                            in.close();
                            out.flush();
                           
                                } else {
                                        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                                }
                } catch (Exception ex) {
                    logger.info("Error writing file to output stream. File id was '" + id + "'");
                    throw new RuntimeException("IOError writing file to output stream");
                }
                } else {
                        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
                }
        }

Some of the files are in ISO-8859-2 encoding. When I remove  ''response.setCharacterEncoding("");'' line from download servlet then some of the characters are mishmash. But when I left this line I get error as follow:

java.io.UnsupportedEncodingException:
        sun.nio.cs.StreamEncoder.forOutputStreamWriter(StreamEncoder.java:61)
        java.io.OutputStreamWriter.<init>(OutputStreamWriter.java:100)
        org.apache.tomcat.util.buf.WriteConvertor.<init>(C2BConverter.java:174)
        org.apache.tomcat.util.buf.C2BConverter.<init>(C2BConverter.java:47)
        org.apache.catalina.connector.OutputBuffer.setConverter(OutputBuffer.java:537)
        org.apache.catalina.connector.OutputBuffer.checkConverter(OutputBuffer.java:502)
        org.apache.catalina.connector.Response.getWriter(Response.java:646)
        org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
        com.github.dandelion.core.web.DandelionFilter.doFilter(DandelionFilter.java:146)

Here is my web.xml: (almost the same as petclinic example)
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

    <display-name>xxx</display-name>
    <description>xxx</description>
   
    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>jdbc</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/business-config.xml, classpath:spring/tools-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>yyy</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/mvc-core-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>yyy</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
   
   
   <servlet>
      <servlet-name>dandelionServlet</servlet-name>
      <servlet-class>com.github.dandelion.core.web.DandelionServlet</servlet-class>
      <load-on-startup>2</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>dandelionServlet</servlet-name>
      <url-pattern>/dandelion-assets/*</url-pattern>
   </servlet-mapping>
   
   <filter>
      <filter-name>dandelionFilter</filter-name>
      <filter-class>com.github.dandelion.core.web.DandelionFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>dandelionFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

   <filter>
      <filter-name>datatables</filter-name>
      <filter-class>com.github.dandelion.datatables.core.web.filter.DatatablesFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>datatables</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
   
    <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <servlet-name>clientportal</servlet-name>
    </filter-mapping>
   
    <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>
 
  <filter>
          <filter-name>springSecurityFilterChain</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
       
        <filter-mapping>
          <filter-name>springSecurityFilterChain</filter-name>
          <url-pattern>/*</url-pattern>
        </filter-mapping>
</web-app>

Spring configuraction is also very similar to petclinic example. On JSP pages I use utf-8 encoding.

Thanks for all help.

BR
Reply | Threaded
Open this post in threaded view
|

Re: [v0.10.0][JSP][Spring] Encoding problem

Thibault Duchateau
Administrator
Hi Gotian,

The Spring encoding filter should be declared before any other filter to ensure that encoding works properly.
Could you please try to change the order of declaration?

Regards,
Thibault.
Reply | Threaded
Open this post in threaded view
|

Re: [v0.10.0][JSP][Spring] Encoding problem

gotian
Thanks for help but I again get characters mishmash. Difference is with error on ' response.setCharacterEncoding(""); '

web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

    <display-name>xxx</display-name>
    <description>xxx</description>
   
    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>jdbc</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/business-config.xml, classpath:spring/tools-config.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>yyy</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/mvc-core-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>yyy</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
   
       <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>
   
    <filter>
        <filter-name>httpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>httpMethodFilter</filter-name>
        <servlet-name>clientportal</servlet-name>
    </filter-mapping>
 
  <filter>
          <filter-name>springSecurityFilterChain</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
       
        <filter-mapping>
          <filter-name>springSecurityFilterChain</filter-name>
          <url-pattern>/*</url-pattern>
        </filter-mapping>
   
   
   <servlet>
      <servlet-name>dandelionServlet</servlet-name>
      <servlet-class>com.github.dandelion.core.web.DandelionServlet</servlet-class>
      <load-on-startup>2</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>dandelionServlet</servlet-name>
      <url-pattern>/dandelion-assets/*</url-pattern>
   </servlet-mapping>
   
   <filter>
      <filter-name>dandelionFilter</filter-name>
      <filter-class>com.github.dandelion.core.web.DandelionFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>dandelionFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

   <filter>
      <filter-name>datatables</filter-name>
      <filter-class>com.github.dandelion.datatables.core.web.filter.DatatablesFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>datatables</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
 
</web-app>

error:
java.io.UnsupportedEncodingException:
        sun.nio.cs.StreamEncoder.forOutputStreamWriter(StreamEncoder.java:61)
        java.io.OutputStreamWriter.<init>(OutputStreamWriter.java:100)
        org.apache.tomcat.util.buf.WriteConvertor.<init>(C2BConverter.java:174)
        org.apache.tomcat.util.buf.C2BConverter.<init>(C2BConverter.java:47)
        org.apache.catalina.connector.OutputBuffer.setConverter(OutputBuffer.java:537)
        org.apache.catalina.connector.OutputBuffer.checkConverter(OutputBuffer.java:502)
        org.apache.catalina.connector.Response.getWriter(Response.java:646)
        org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
        javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
        javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
        org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper.getWriter(SaveContextOnUpdateOrErrorResponseWrapper.java:125)
        com.github.dandelion.core.web.DandelionFilter.doFilter(DandelionFilter.java:146)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
        org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
        org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)

BR
Reply | Threaded
Open this post in threaded view
|

Re: [v0.10.0][JSP][Spring] Encoding problem

gotian
I find a solution.

The problem is in DandelionFilter class in isFilterApplyable method.

I just add "?dandelionAssetFilterState=false" to GET request and that solve a problem.