Eugene Eugene - 5 months ago 44
Java Question

FileUpload filename encoding

It's been quite a while since I'm banging my head against this: multipart/mixed content.

@RequestPart(name="view") CoolView,
@RequestPart(name="files") Part [] files


Also using spring's (it does not matter because CommonsMultipartResolver fails too) :

StandardServletMultipartResolver


Now the thing is that when uploading files that have some names outside US_ASCII characters, the server is converting them into something weird. And by weird I mean it converts them to ISO_8859_1, and I think I've set the UTF-8 encoding everywhere imaginable.


  • -Dfile.encoding=UTF-8

  • LANG="en_US.UTF-8" LC_ALL="en_US.UTF-8"

  • URIEncoding = UTF-8 (in server.xml tomcat)

  • CharacterEncodingFilter is the first filter that is being picked up



  • It's interesting that this only happens when I try this on the azure linux machine, locally everything is just fine.

    For example I'm using curl to send some files to be uploaded :

    curl -X POST -F "files=@Définition fonctionnalités.pdf"


    And in Controller I'm trying to see the name that is actually being captured from Content-Disposition filename.

    Définition fonctionnalités.pdf


    At this point I would accept any suggestion what-so-ever. thank u

    Answer

    According to your description, the string Définition fonctionnalités.pdf can be converted into the correct string by the below code.

    String str = new String("Définition fonctionnalités.pdf".getBytes("ISO-8859-1"), "UTF-8");
    System.out.println(str); // Output is "Définition fonctionnalités.pdf"
    

    Per my experience, it seems to be caused by the Character Encoding format of your Java source file if your development environment is on Windows.

    So for the case, the solution is using the text editor supported UTF-8 Encoding to be sure the encoding format of Java source files before compiling them.

    If you are using Eclipse IDE, you can set the encoding for your project. The steps as below.

    1. Select your project to right click to select the Properties or directly enter the combine keys Alt+Enter.
    2. Set up the text file encoding for the current project in the Resource tab, please see below.

    enter image description here

    Note: If you set the text file encoding for the existing project, you may need to repair these incorrect encoding string manually。

    Hope it helps.


    Update: Please try to do some configurations below.

    1. Configuring the server.xml file for connection to enable the URIEncoding with UTF-8.

      <Connector port="80" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/> 
      
    2. Adding a global filter for your Java webapp.

    Configure the web.xml file for your project

    <filter>
        <filter-name>charsetFilter</filter-name>
        <filter-class>com.XXXX.xxxx.CharsetFilter</filter-class>
        <init-param>
            <param-name>requestEncoding</param-name>
           <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>charsetFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    Create the filter class CharsetFilter

    public class CharsetFilter implements Filter {
        private String encoding;
        private Logger log = Logger.getLogger(this.getClass());
    
        public void init(FilterConfig config) throws ServletException {
            encoding = config.getInitParameter("requestEncoding");
            if (encoding == null) encoding = "UTF-8";
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)
                throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            request.setCharacterEncoding(encoding);
            next.doFilter(request, response);
        }
    
        public void destroy() {
        }
    }
    
    1. When receiving the uploaded file, converting the bytes of the file name string with ISO-8859-1 into a UTF-8 string, as I said above.

      String originFN = ....;
      String fileName = new String(originFN.getBytes("ISO-8859-1"), "UTF-8");