servlet-spec
  1. servlet-spec
  2. SERVLET_SPEC-57

Add getFileName() method to javax.servlet.http.Part

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      All

      Description

      The javax.servlet.http.Part interface lacks a method for retrieving the file name of a part. Most request parts have file names, typically provided by the client's browser as the name of the file on the client's file system when the file is uploaded through the form submission. Currently, consumers of Part must create their own method to extract the file name:

      public static String getFileName(Part filePart)
      {
          String header = filePart.getHeader("content-disposition");
          for(String headerPart : header.split(";"))
          {
              if(headerPart.trim().startsWith("filename"))
              {
                  return headerPart.substring(headerPart.indexOf('=') + 1).trim()
                                   .replace("\"", "");
              }
          }
          return null;
      }

      Tomcat, as an example, already has a method to extract the file name in its Part implementation, but since it is not exposed via the public Part interface developers cannot use it without limiting the portability of their applications. It's possible other containers already do something similar.

      The suggested getFileName() method should:

      • Locate the Content-Disposition header from the Part. If no such header exists, return null.
      • Extract the filename attribute from the Content-Disposition header and return its value trimmed.
      • If no filename attribute exists or the filename attribute value is null, return null.
      • Not throw any exceptions.

      Estimate 5 minutes to add the method to the interface and < 2 hours to add relevant documentation regarding the method to the spec.

        Activity

        Hide
        Nick Williams added a comment - - edited

        Note that the sample code submitted does not follow the second part of rule 1, "If no such header exists, return null." A more stable implementation would be:

        public static String getFileName(Part filePart)
        {
            String header = filePart.getHeader("content-disposition");
            if(header == null)
                return null;
            for(String headerPart : header.split(";"))
            {
                if(headerPart.trim().startsWith("filename"))
                {
                    return headerPart.substring(headerPart.indexOf('=') + 1).trim()
                                     .replace("\"", "");
                }
            }
            return null;
        }

        Of course, this is merely a sample implementation, and container developers are free to implement the spec in their own way.

        Show
        Nick Williams added a comment - - edited Note that the sample code submitted does not follow the second part of rule 1, "If no such header exists, return null ." A more stable implementation would be: public static String getFileName(Part filePart) { String header = filePart.getHeader( "content-disposition" ); if (header == null ) return null ; for ( String headerPart : header.split( ";" )) { if (headerPart.trim().startsWith( "filename" )) { return headerPart.substring(headerPart.indexOf('=') + 1).trim() .replace( "\" ", " "); } } return null ; } Of course, this is merely a sample implementation, and container developers are free to implement the spec in their own way.
        Hide
        carojkov added a comment -

        I'd like to propose a method name that clearly states that this is a file name specified by the client. e.g. getClientFileName(). getRequestedFileName() or getSubmittedFileName(). This should help avoid confusion if/when it's decided if adding another get*File() method to the Part is needed. i.e. getFile() returning File after a call to Part#write(String) method.

        Show
        carojkov added a comment - I'd like to propose a method name that clearly states that this is a file name specified by the client. e.g. getClientFileName(). getRequestedFileName() or getSubmittedFileName(). This should help avoid confusion if/when it's decided if adding another get*File() method to the Part is needed. i.e. getFile() returning File after a call to Part#write(String) method.
        Hide
        Nick Williams added a comment -

        I agree. I prefer getSubmittedFileName(). Seems the most applicable, as that's exactly what it is: nothing more or less than the submitted file name.

        Show
        Nick Williams added a comment - I agree. I prefer getSubmittedFileName() . Seems the most applicable, as that's exactly what it is: nothing more or less than the submitted file name.
        Hide
        markt_asf added a comment -

        +1

        Show
        markt_asf added a comment - +1
        Hide
        Nick Williams added a comment - - edited

        By the way, Mark, if this gets accepted for 3.1 I'll implement it in Tomcat. Should just be a matter of adding the method to the interface and then implementing the method in ApplicationPart to wrap ApplicationPart#getFilename().

        Show
        Nick Williams added a comment - - edited By the way, Mark, if this gets accepted for 3.1 I'll implement it in Tomcat. Should just be a matter of adding the method to the interface and then implementing the method in ApplicationPart to wrap ApplicationPart#getFilename().
        Hide
        Shing Wai Chan added a comment -

        Add a method Part#getSubmittedFileName

        Sending src/main/java/javax/servlet/http/Part.java
        Transmitting file data .
        Committed revision 59926.

        Show
        Shing Wai Chan added a comment - Add a method Part#getSubmittedFileName Sending src/main/java/javax/servlet/http/Part.java Transmitting file data . Committed revision 59926.

          People

          • Assignee:
            Shing Wai Chan
            Reporter:
            Nick Williams
          • Votes:
            3 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 2 hours
              2h
              Remaining:
              Remaining Estimate - 2 hours
              2h
              Logged:
              Time Spent - Not Specified
              Not Specified