1

I've made an JSP page that has the following input in a form:

<input type="file" name="image" id="image" accept="image/*">

And a button that runs submit().

The submitted info is then processed by a Servlet, the thing is I need to get the bytes (a byte array - byte[]) out of the "image" parameter.

Is it possible? I've been looking for it but wansn't able to find it.

Solution by /u/jmeisner707 on reddit.com/r/javahelp:

Add the tag: enctype="multipart/form-data" to the form and write the following code in the servlet:

Part part = request.getPart("image"); InputStream = part.getInputStream();

After that you should be able to get the byte array out of the input stream, it's necessary to add the following annotations to the servlet:

` @MultipartConfig

@WebServlet(
    name = "Servlet",
    urlPatterns = { "/url"},
    loadOnStartup = 1

)`

Thank you for your answers.

BrunoSG
  • 21
  • 1
  • 7
  • What do you mean by "parameter"? Do you mean you want to get a byte array from the bytes in the image file that is received by your servlet? – Dave0504 Oct 10 '16 at 22:55

2 Answers2

1

the thing is I need to get the bytes (a a byte array - byte[]) out of the "image" parameter.

No you don't. You get the request input stream, then you copy bytes wherever they need to go via the standard Java copy loop.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • The thing is I think there are other parameters stored in the input stream (a string called "name"). Should I still get the input stream? – BrunoSG Oct 11 '16 at 00:22
0

Do it in two parts, get the file first, then get the byte array from the file.

Have a look at this tutorial for getting the file.

Fie upload to Sevlets

Then look at this trail from the Oracle site for IO and byte streams. Once you've worked through both you should be able to work it out.

Basic I/O


UPDATE

In relation to the comments to this answer, a working implementation using FileInputStream and the File from the server is given below using a slightly modified version of the tutorial. It may not be the best way, but it does work.

package cmpdhoug;

import java.io.*;
import java.util.*;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.output.*;


@WebServlet (
        name = "UploadServlet",
        urlPatterns = "/UploadServlet",
        loadOnStartup = 1
)
public class UploadServlet extends HttpServlet {

    private boolean isMultipart;
    private String filePath, tempPath;
    private int maxFileSize = 5242880;
    private int maxMemSize = 5 * 1024;
    private File file ;

    public void init( ){
        // Get the file location where it would be stored.
        filePath =
                getServletContext().getInitParameter("file-upload");
        tempPath = getServletContext().getInitParameter("temp-upload");
    }
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
            throws ServletException, java.io.IOException {
        // Check that we have a file upload request
        isMultipart = ServletFileUpload.isMultipartContent(request);
        response.setContentType("text/html");
        java.io.PrintWriter out = response.getWriter( );
        if( !isMultipart ){
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet upload</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<p>No file uploaded</p>");
            out.println("</body>");
            out.println("</html>");
            return;
        }
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // maximum size that will be stored in memory
        factory.setSizeThreshold(maxMemSize);
        // Location to save data that is larger than maxMemSize.
        factory.setRepository(new File(tempPath));

        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);
        // maximum file size to be uploaded.
        upload.setSizeMax( maxFileSize );

        try{
            // Parse the request to get file items.
            List fileItems = upload.parseRequest(request);

            // Process the uploaded file items
            Iterator i = fileItems.iterator();

            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet upload</title>");
            out.println("</head>");
            out.println("<body>");
            while ( i.hasNext () )
            {
                FileItem fi = (FileItem)i.next();
                if ( !fi.isFormField () )
                {
                    // Get the uploaded file parameters
                    String fieldName = fi.getFieldName();
                    String fileName = fi.getName();
                    String contentType = fi.getContentType();
                    boolean isInMemory = fi.isInMemory();
                    long sizeInBytes = fi.getSize();
                    // Write the file
                    if( fileName.lastIndexOf("\\") >= 0 ){
                        file = new File( filePath +
                                fileName.substring( fileName.lastIndexOf("\\"))) ;
                    }else{
                        file = new File( filePath +
                                fileName.substring(fileName.lastIndexOf("\\")+1)) ;
                    }
                    fi.write( file ) ;
                    out.println("Uploaded Filename: " + fileName + "<br>");
                }
            }


            // Get byte stream from file uploaded to server.
            FileInputStream fis = new FileInputStream(file);
            byte[] byteArray = new byte[(int) file.length()];

            // Add the bytes from the file to the array
            for(int j = 0; j < byteArray.length; j++){
                byteArray[j] = (byte)fis.read();
                // Just to show the bytes are in the array.
                System.out.println(byteArray[j]);
            }
            fis.close();
            out.println("</body>");
            out.println("</html>");
        }catch(Exception ex) {
            System.out.println(ex);
        }


    }
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
            throws ServletException, java.io.IOException {

        throw new ServletException("GET method used with " +
                getClass( ).getName( )+": POST method required.");
    }
}

You also need to make sure that you update your web.xml file to provide the correct file paths to wherever your server deploys your app to, which may be different from where the Tomcat installation files are locally. For example my Tomcat installation is in /dave/servers/Tomcat/ but my server deploys to the params given below (make sure you create the webapps/data and webapps/temp folders)

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >



<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <context-param>
    <param-name>file-upload</param-name>
    <param-value>/Users/dave/Library/Caches/IntelliJIdea2016.2/tomcat/webapps/data/</param-value>
  </context-param>
    <context-param>
        <param-name>temp-upload</param-name>
        <param-value>/Users/dave/Library/Caches/IntelliJIdea2016.2/tomcat/webapps/temp/</param-value>
    </context-param>
</web-app>

pom.xml with dependencies

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>UploadServlet</groupId>
  <artifactId>UploadServlet</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>UploadServlet Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.3.2</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>UploadServlet</finalName>
  </build>

index file

<html>
<head>
    <title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="UploadServlet" method="post"
      enctype="multipart/form-data">
    <input type="file" name="file" size="50" />
    <br />
    <input type="submit" value="Upload File" />
</form>
</body>
</html>
Dave0504
  • 1,057
  • 11
  • 30
  • Thank you for your answer, I read the tutorial in the first link but I wasn't able to understand it at all. So far I tried: `Part filePart = request.getParameter("image"); InputStream is = filePart.getInputStream();` And then I tried getting the bytes out of the InputStream but filePart is null :/ – BrunoSG Oct 10 '16 at 23:08
  • Have a look at FileInputStream first of all instead of InputStream, it has a method read(byte[] b) to get the bytes into an array. It also has a constructor which takes an object of type File as its only argument. – Dave0504 Oct 10 '16 at 23:16
  • @Dave0504 `InputStream` has the same method, and you can only use `FileInputStream` if you have an input file to open. The data here is coming from a socket. The 'constructor which takes an object of type `File`' is useless here, as is the `FileInputStream`. Also pointless. – user207421 Oct 10 '16 at 23:31
  • @EJP I assumed this would work as the file is uploaded to the server/servelet. The init() method in the tutorial gets the file path from the servlet context. Also, the tutorial uses a File object... Am I wrong? Thanks. – Dave0504 Oct 10 '16 at 23:40