?
Solved

how to create and send multipart object to servlet

Posted on 2003-03-19
3
Medium Priority
?
372 Views
Last Modified: 2012-08-14
I am a java rookie. Can anybody help me how to create a multipart object which should contain host IP, file name, volume name etc and a file. and also need some help on how to send this multipart object to a servlet.

would appreciate asap reply and some links on resources..

Thanks..
0
Comment
Question by:Juniorprog
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 2

Accepted Solution

by:
polmint earned 200 total points
ID: 8435646

hi Juniorprog,

I think u want to upload a file on to the webserver.

try this MultipartRequest.java file

import java.io.*;
import java.util.*;
import javax.servlet.*;

public class  MultipartRequest {
      private static final int DEFAULT_MAX_POST_SIZE=1024*1024; // 1 Meg

      private ServletRequest req;
      private File dir;
      private int maxSize;

      private Hashtable parameters = new Hashtable(); // name - value
      private Hashtable files = new Hashtable(); // name - UploadedFile

      public MultipartRequest()
      {
      }
      
      public void config(ServletRequest request,String saveDirectory) throws IOException {
            config(request,saveDirectory,DEFAULT_MAX_POST_SIZE);
      }

      public void config(ServletRequest request,
                                                      String saveDirectory,
                                                      int maxPostSize) throws IOException {
            // Sanity check values
            if(request == null)
                  throw new IllegalArgumentException("request cannot be null");
            if(saveDirectory == null)
                  throw new IllegalArgumentException("saveDirectory cannot be null");
            if(maxPostSize <= 0)
                  throw new IllegalArgumentException("maxPostSize must be positive");

            // Save the request, dir, and max size
            req = request;
            dir = new File(saveDirectory);
            maxSize = maxPostSize;

            //check saveDirectory is truly a directory
            if(!dir.isDirectory())
                  throw new IllegalArgumentException("Not a directory: " + saveDirectory);

            //check saveDirectory is writable
            if(!dir.canWrite())
                  throw new IllegalArgumentException("Not writable: " + saveDirectory);

            //Now parse the request saving data to "parameters" and "files";
            //write the file contents to the saveDirectory

            readRequest();
      }

      public Enumeration getParameterNames() {
            return parameters.keys();
      }

      public Enumeration getFileNames() {
            return files.keys();
      }

      public String getParameter(String name) {
            try {
                  String param = (String)parameters.get(name);
                  if(param.equals("")) return null;
                        return param;
            }
            catch(Exception e) {
                  return null;
            }
      }

      public String getFilesystemName(String name) {
            try {
                  UploadedFile file = (UploadedFile)files.get(name);
                  return file.getFilesystemName().replace(' ','_');//may be null
            }
            catch(Exception e) {
                  return null;
            }
      }

      public String getContentType(String name) {
            try {
                  UploadedFile file = (UploadedFile)files.get(name);
                  return file.getContentType();      //may be null
            }
            catch(Exception e) {
                  return null;
            }
      }

      public File getFile(String name) {
            try {
                  UploadedFile file = (UploadedFile)files.get(name);
                  return file.getFile(); //may be null
            }
            catch(Exception e) {
                  return null;
            }
      }

      protected void readRequest() throws IOException {
            // Check the content type to make sure it's "multipart/form-data"
            String type = req.getContentType();
            if(type==null||
                        !type.toLowerCase().startsWith("multipart/form-data")) {
                  throw new IOException("Posted content type is n't multipart/form-data");
            }

            // Check the content length to prevent denial of service attacks
            int length=req.getContentLength();
            if(length> maxSize) {
                  throw new IOException("Posted content length of " + length +
                                                                  " exceeds limit of "+maxSize);
            }

            // Get the boundary string; it's included in the content type
            // Should look something like "-------------------1212321"
            String boundary = extractBoundary(type);
            if(boundary==null) {
                  throw new IOException("seperation boundary was not specified");
            }

            // Construct the special input stream we 'll read from
            MultipartInputStreamHandler in =
                  new MultipartInputStreamHandler(req.getInputStream(), boundary, length);

            // Read the first line, should be the first boundary
            String line = in.readLine();
            if(line==null) {
                  throw new IOException("Corrupt form data: premature ending");
            }

            // Verify that the line is the boundary
            if(!line.startsWith(boundary)) {
                  throw new IOException("Corrupt from data: no leading boundary");
            }

            // Now that we are just beyond the first boundary, loop over eachpart
            boolean done = false;
            while(!done) {
                  done = readNextPart(in,boundary);
            }
      }

      protected boolean readNextPart(MultipartInputStreamHandler in,String boundary)throws IOException {
            // Read the first line, should look like this;
            // content-disposition: form-data; name="field1"; filename="file1.txt"
            String line = in.readLine();
            if(line==null) {
                  // No parts left, we are done
                  return true;
            }
            
            // Parse the content-disposition line
            String[] dispInfo=extractDispositionInfo(line);
            String disposition = dispInfo[0];
            String name = dispInfo[1];
            String filename = dispInfo[2];

            // Now onto the next line. this will either be empty
            // Or contain a content=type and then an empty line
            line = in.readLine();
            if(line==null) {
                  // No parts left, we are done
                  return true;
            }

            // Get the content type, or null if one specified
            String contentType = extractContentType(line);
            if(contentType !=null) {
                  // Eat the empty line
                  line = in.readLine();
                  if(line == null || line.length() > 0 ) { // line should be empty
                        throw new IOException("malformed line after content type:" + line);
                  }
            }
            else {
                  // Assume a default content type
                  contentType = "application/octet-stream";
            }

            // Now finally, we read the content(end after reading the boundary)
            if (filename == null) {
                  // This is a parameter
                  String value= readParameter(in, boundary);
                  parameters.put(name, value);
            }
            else {
                  // This is a file
                  readAndSaveFile(in, boundary, filename);
                  if(filename.equals("unknown")) {
                        files.put(name,new UploadedFile(null, null, null));
                  }
                  else {
                        files.put(name,new UploadedFile(dir.toString(),filename,contentType));
                  }
            }
            return false; // thres's more to read
      }

      protected String readParameter(MultipartInputStreamHandler in,
                                    String boundary) throws IOException {
            StringBuffer sbuf = new StringBuffer();
            String line;

            while((line = in.readLine()) != null) {
                  if(line.startsWith(boundary)) break;
                  sbuf.append(line+"\r\n");      // add the \r\n in case there are many lines
            }

            if(sbuf.length() == 0) {
                  return null; // nothing to read
            }

            sbuf.setLength(sbuf.length() - 2);      // cut off the last line's \r\n
            return sbuf.toString();
      }

      protected void readAndSaveFile(MultipartInputStreamHandler in,
                              String boundary,
                              String filename) throws IOException {
                  filename = filename.replace(' ','_');
            File f = new File(dir +File.separator + filename);
            FileOutputStream fos =  new FileOutputStream(f);
            BufferedOutputStream out = new BufferedOutputStream(fos, 8 * 1024);  // 8K
            byte[] bbuf = new byte[8 * 1024];      // 8K
            int result;
            String line;

            // ServletInputStream.readLine() has the annoying habit of
            // adding a \r\n to the end of the last line.
            // Since we want a byte-for-byte transfer, we have to cut those chars.

            boolean rnflag = false;
            while((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
                  // Check for boundary
                  if(result > 2 && bbuf[0] == '-' && bbuf[1]== '-' ) { // quick pre-check
                        line = new String(bbuf, 0, result, "ISO-8859-1");
                        if(line.startsWith(boundary)) break;
                  }

                  // Are we supposed to write \r\n for the last iteration?
                  if(rnflag) {
                        out.write('\r'); out.write('\n');
                        rnflag = false;
                  }

                  // Write the buffer, postpone any ending \r\n
                  if(result >= 2 && 
                        bbuf[result-2] == '\r' && 
                        bbuf[result -1]=='\n') {
                        out.write(bbuf, 0, result - 2);  // skip the last 2 chars
                        rnflag = true;      // make a note to write them on the next iteration
                  }
                  else {
                        out.write(bbuf, 0, result);
                  }
            }
            out.flush();
            out.close();
            fos.close();
      }

      private String extractBoundary(String line) {
            int index = line.indexOf("boundary=");
            if(index==-1) {
                  return null;
            }
            String boundary = line.substring(index +9); // 9 for "boundary="

            // The real boundary is always preceded by an extra "--"
            boundary = "--" +boundary;
            
            return boundary;
      }

      private String[] extractDispositionInfo(String line)throws IOException {
            // Return the line's data as an array: disposition, name, filename
            String[] retval = new String[3];

            // Convert the line to a lowercase string without the ending \r\n
            // Keep the original line for error messages and for variable names

            String origline = line;
            line = origline.toLowerCase();
            
            // Get the content disposition, should be "form-data"
            int start = line.indexOf("content-disposition:");
            int end = line.indexOf(";");
            if(start == -1 || end == -1) {
                  throw new IOException("Content disposition corrupt:" + origline);
            }

            String disposition = line.substring(start + 21, end);
            if(!disposition.equals("form-data")) {
                  throw new IOException("Invalid content disposition: " + disposition);
            }
            
            // Get the field name

            start = line.indexOf("name=\"",end);       // start al last semicolon
            end =  line.indexOf("\"",start +7); // skip name=\"
            if(start == -1 || end == -1) {
                  throw new IOException ("Content disposition coorupt: " + origline);
            }

            String name = origline.substring(start + 6, end);

            // Get the filename, if given
            String filename = null;
            start = line.indexOf("filename=\"", end + 2); // start after name
            end = line.indexOf("\"", start + 10); // skip filename=\"
            if(start != -1 && end != -1) {                  // note the !=
                  filename = origline.substring(start + 10, end);
                  // The filename may contain a full path. Cut to just the filename
                  int slash =
                        Math.max(filename.lastIndexOf('/'), filename.lastIndexOf("\\"));
                  if(slash > -1) {
                        filename = filename.substring(slash + 1); // past last slash
                  }
                  if(filename.equals("")) filename = "unknown"; // sanity check
            }

            // Return a String array: disposition, name, filename

            retval[0] = disposition;
            retval[1] = name;
            retval[2] = filename;
            return retval;
      }

      private String extractContentType(String line) throws IOException {
            String contentType = null;

            // Convert the line to a lowercase string
            String origline = line;
            line = origline.toLowerCase();

            // Get the content type, if any
            if(line.startsWith("content-type")) {
                  int start = line.indexOf(" ");
                  if(start == -1) {
                        throw new IOException("Content type corrupt: " + origline);
                  }
                  contentType = line.substring(start + 1);
            }
            else if(line.length() != 0) { // no content type, so should be empty
                  throw new IOException("Malformed line after disposition: " + origline);
            }

            return contentType;
      }
}

// A class to hold information about an uploaded file
//
class UploadedFile
{
      private String dir;
      private String filename;
      private String type;

      UploadedFile(String dir, String filename, String type) {
            this.dir = dir;
            this.filename = filename;
            this.type = type;
      }
      
      public String getContentType() {
            return type;
      }

      public String getFilesystemName() {
            return filename;
      }

      public File getFile() {
            if(dir == null || filename == null) {
                  return null;
            }
            else {
                  return new File(dir+ File.separator + filename);
            }
      }
}

// A class to aid in reading multipart/form-data from a servletInputStream.
// It keeps track of how many bytes have been read and detects when the
// Content-Length limit has been reached. This is necessary because some
// servlet engines are slow to notice the end of stream
//
class MultipartInputStreamHandler {

      ServletInputStream in;
      String boundary;
      int totalExpected;
      int totalRead = 0;
      byte[] buf = new byte[8 * 1024];

      public MultipartInputStreamHandler(ServletInputStream in,
                                                                              String boundary,
                                                                              int totalExpected) {
            this.in = in;
            this.boundary = boundary;
            this.totalExpected = totalExpected;
      }

      public String readLine() throws IOException {
            StringBuffer sbuf = new StringBuffer();
            int result;
            String line;

            do {
                  result = this.readLine(buf, 0, buf.length); // this.readLine() does +=
                  if(result != -1) {
                        sbuf.append(new String(buf, 0, result, "ISO-8859-1"));
                  }
            } while(result == buf.length); // loop only if the buffer was filled

            if(sbuf.length() == 0) {
                  return null; // nothing read, mush be at the end of stream
            }

            sbuf.setLength(sbuf.length() - 2); // out off the trailing \r\n
            return sbuf.toString();
      }
      
      public int readLine(byte b[], int off, int len) throws IOException {
            if(totalRead >= totalExpected) {
                  return -1;
            }
            else {
                  int result = in.readLine(b, off, len);
                  if(result > 0) {
                        totalRead += result;
                  }
                  return result;
            }
      }
}
0

Featured Post

Optimum High-Definition Video Viewing and Control

The ATEN VM0404HA 4x4 4K HDMI Matrix Switch supports 4K resolutions of UHD (3840 x 2160) and DCI (4096 x 2160) with refresh rates of 30 Hz (4:4:4) and 60 Hz (4:2:0). It is ideal for applications where the routing of 4K digital signals is required.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This is a guide to setting up a new WHM/cPanel Server to be used for web hosting accounts. It is intended for web hosting company administrators and dedicated server owners. For under $99 per month (considering normal rate of Big Data Cetnters like …
Introduction This article explores the design of a cache system that can improve the performance of a web site or web application.  The assumption is that the web site has many more “read” operations than “write” operations (this is commonly the ca…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question