Search code examples
jsptomcatservletsfile-uploadmultipartform-data

Servlet receives null values after uploading a file


I have a Java web application that includes a file upload feature. The HTML form fileUpload.html allows users to select and upload a file to the server. The form action is set to a servlet ServletFileUpload.java to process the uploaded file.

Here is the code mentioned above:

<!DOCTYPE html>
<html lang="de">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Datei Upload</title>
  </head>
  <body>
    <h1>Dateien hochladen</h1>
    <form action="../fileUpload" method="POST" enctype="multipart/form-data">
      <label for="name">Anzeigename:</label>
      <input type="text" name="name" id="name" required /><br />

      <label for="expirationDate">Ablaufdatum:</label>
      <input
        type="date"
        name="expirationDate"
        id="expirationDate"
        required
      /><br />

      <label for="category">Kategorie:</label>
      <select name="category" id="category" required>
        <option value="" disabled>Wählen Sie eine Kategorie aus</option>
        <option value="aushang1">Aushang 1</option>
        <option value="aushang2">Aushang 2</option>
        <option value="vorschriften">Sicherheitsvorschriften</option>
        <option value="notfaelle">Notfälle</option>
        <option value="organisation">Organisation</option>
        <option value="anlagenleistung">Anlagenleistung</option>
        <option value="abfuellplan">Abfüllplan</option>
        <option value="schichtplan">Schichtplan</option>
        <option value="jahresplanung">Jahresplanung</option>
      </select>
      <br />

      <label for="pdfFile">Wählen Sie eine PDF aus:</label>
      <input type="file" name="pdfFile"  id="pdfFile" accept=".pdf"required><br><br>
      <input type="submit" value="PDF hochladen">
    </form>
  </body>
</html>
@WebServlet("/fileUpload")
public class ServletFileUpload extends HttpServlet {
    private static final Logger logger = LogManager.getLogger(ServletFileUpload.class);

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        logger.debug("Name: {}, Expiration Date: {}, Category: {}",
                request.getParameter("name"),
                request.getParameter("expirationDate"),
                request.getParameter("category"));
    }

The problem I'm facing is that the FileUpload.java servlet doesn't seem to receive any data from the HTML form. When I submit the form, this is what gets logged:

15:38:19.860 [http-nio-8081-exec-51] DEBUG de.http.ServletFileUpload - Name: null, Expiration Date: null, Category: null

When submitting the form, I can see in the developer tools that the values in the form should be correct.

I'm using Tomcat 10.1 but when using Tomcat 9 I get the same results. In the catalina.log I can't find anything related to this issue.

When changing the action-reference in HTML or the @WebServlet in Java I still run into the same problem.

Hopefully, somebody has an idea, what is wrong here.


Solution

  • In this way, you will not be able to get parameters from the request. The multipart/form-data content type makes it necessary to parse the request body in parts. That is, if you are trying to get parameters using ServletRequest.getParameter():

    Returns the value of the query parameter as String or null if parameter does not exist. Request parameters - additional information, sent with the request. For HTTP servlets, the parameters are contained in the query line or in the body of the request where the form data is located.

    then you get null because the request body has a different format, and the above method works if the request body has the format application/x-www-form-urlencoded.


    More detailed information about the POST method:

    The HTTP POST method sends data to the server. Request body type indicated by the Content-Type header.

    The difference between PUT and POST is that PUT is idempotent: calling it one or more times in a row has the same effect effect (which is not a side effect), where sequential an identical POST may have additional effects, e.g. transmit the same data several times.

    A POST request is usually sent via an HTML form and results in changes on the server. In this case, the content type is selected by placing the appropriate string in the element's enctype attribute <form> or formenctype attribute of <input> elements or <button>:

    • application/x-www-form-urlencoded: keys and values ​​are encoded in key tuples separated by &, with = between key and meaning. Non-alphanumeric characters in both keys and values encoded as a percentage: this is the reason why this type is not suitable for use with binary data (use instead multipart/form-data);
    • multipart/form-data;
    • text/plain.

    In order to be able to get parameters and parts of files from a request, you can use the @MultipartConfig annotation:

    An annotation that can be placed on the Servlet class indicating that servlet instances expect requests matching the type MIME with multipart/form-data.

    Servlets annotated with MultipartConfig can retrieve Part components of a given multipart/form-data request, calling getPart() or getParts().


    You can also read about the @MultipartConfig annotation in the tutorial.

    In which you can also find an example of fileupload using this annotation.