diff --git a/src/com/silverwrist/util/ServletMultipartHandler.java b/src/com/silverwrist/util/ServletMultipartHandler.java index 67b9796..24fdb17 100644 --- a/src/com/silverwrist/util/ServletMultipartHandler.java +++ b/src/com/silverwrist/util/ServletMultipartHandler.java @@ -25,6 +25,7 @@ import javax.activation.DataSource; import javax.mail.*; import javax.mail.internet.*; import javax.servlet.*; +import org.apache.log4j.*; // This class was built in a process I call "Java Junkyard Wars," in which I put together // a bunch of APIs in ways that their designers would never have anticipated. It's @@ -83,19 +84,29 @@ public class ServletMultipartHandler static class MultipartDataValue implements Blob { + private static final int BLKSIZE = 4096; + private byte[] actual_data; // the actual data we contain public MultipartDataValue(MimeBodyPart part) throws MessagingException, IOException { + if (logger.isDebugEnabled()) + logger.debug("creating new MultipartDataValue"); + + // set up the streams to copy between InputStream in = part.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] copybuf = new byte[4096]; - int ct = in.read(copybuf); + byte[] copybuf = new byte[BLKSIZE]; + + // begin the copy loop + int ct = in.read(copybuf,0,BLKSIZE); while (ct>=0) { // do a simple read and write + if (logger.isDebugEnabled()) + logger.debug("read blksize = " + ct); if (ct>0) out.write(copybuf,0,ct); - ct = in.read(copybuf); + ct = in.read(copybuf,0,BLKSIZE); } // end while @@ -103,6 +114,9 @@ public class ServletMultipartHandler actual_data = out.toByteArray(); out.close(); + if (logger.isDebugEnabled()) + logger.debug("finished copying, " + actual_data.length + " bytes transferred"); + } // end constructor public long length() @@ -127,6 +141,7 @@ public class ServletMultipartHandler public long position(byte[] pattern, long start) throws SQLException { + logger.warn("position() function is not implemented for MultipartDataValue"); throw new SQLException("function not implemented"); } // end position @@ -172,6 +187,15 @@ public class ServletMultipartHandler } // end if + if (logger.isDebugEnabled()) + { // tell us what kind of parameter we have + if (filename!=null) + logger.debug("new file parameter \"" + name + "\" defined (filename = " + filename + ")"); + else + logger.debug("new text parameter \"" + name + "\" defined"); + + } // end if + } // end constructor public String getName() @@ -201,6 +225,7 @@ public class ServletMultipartHandler } // end try catch (Exception e) { // turn any exception returns here into null returns + logger.warn("parameter getValue() method threw a " + e.getClass().getName(),e); return null; } // end catch @@ -216,6 +241,7 @@ public class ServletMultipartHandler } // end try catch (Exception e) { // just dump a null on error + logger.warn("parameter getContentType() method threw a " + e.getClass().getName(),e); return null; } // end catch @@ -231,6 +257,7 @@ public class ServletMultipartHandler } // end try catch (Exception e) { // just dump a -1 on error + logger.warn("parameter getSize() method threw a " + e.getClass().getName(),e); return -1; } // end catch @@ -244,6 +271,9 @@ public class ServletMultipartHandler if (cached_value==null) { // we don't have the value cached yet + if (logger.isDebugEnabled()) + logger.debug("getting MultipartDataValue for parameter \"" + name + "\""); + try { // extract the value cached_value = new MultipartDataValue(part); @@ -251,11 +281,13 @@ public class ServletMultipartHandler } // end try catch (MessagingException me) { // translate exception here + logger.error("MIME parse error getting data content: " + me.getMessage(),me); throw new ServletMultipartException("Error getting data content: " + me.getMessage(),me); } // end catch catch (IOException ioe) { // translate exception here + logger.error("IO error getting data: " + ioe.getMessage(),ioe); throw new ServletMultipartException("Error getting data content: " + ioe.getMessage(),ioe); } // end catch @@ -268,6 +300,13 @@ public class ServletMultipartHandler } // end class MultipartParameter + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Category logger = Category.getInstance(ServletMultipartHandler.class.getName()); + /*-------------------------------------------------------------------------------- * Attributes *-------------------------------------------------------------------------------- @@ -284,13 +323,22 @@ public class ServletMultipartHandler public ServletMultipartHandler(ServletRequest request) throws ServletMultipartException { + if (logger.isDebugEnabled()) + logger.debug("creating new ServletMultipartHandler"); + if (!canHandle(request)) + { // we can't handle ordinary requests, just multipart/form-data ones + logger.error("this request is not of type multipart/form-data"); throw new ServletMultipartException("not a multipart/form-data request"); + } // end if + try { // build the MimeMultipart based on the ServletDataSource multipart = new MimeMultipart(new ServletDataSource(request)); int count = multipart.getCount(); + if (logger.isDebugEnabled()) + logger.debug("retrieved " + count + " parameter(s) from request"); // allocate the multipart parameters and slot them into our arrays param_byname = new Hashtable(); @@ -306,6 +354,7 @@ public class ServletMultipartHandler } // end try catch (MessagingException me) { // translate a MessagingException into the nicer ServletMultipartException + logger.error("multipart parsing failed: " + me.getMessage(),me); throw new ServletMultipartException("Error parsing request data: " + me.getMessage(),me); } // end catch @@ -356,7 +405,11 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return false; + + } // end if else return parm.isFile(); @@ -366,7 +419,11 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return null; + + } // end if else return parm.getValue(); @@ -376,7 +433,11 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return null; + + } // end if else return parm.getContentType(); @@ -386,7 +447,11 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return -1; + + } // end if else return parm.getSize(); @@ -396,7 +461,11 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return null; + + } // end if else return parm.getContent(); @@ -406,7 +475,12 @@ public class ServletMultipartHandler { MultipartParameter parm = (MultipartParameter)(param_byname.get(name)); if (parm==null) + { // no such parameter! + logger.warn("parameter \"" + name + "\" not found"); return null; + + } // end if + MultipartDataValue val = parm.getContent(); return val.getBinaryStream(); diff --git a/src/com/silverwrist/util/test/FormDataTest.java b/src/com/silverwrist/util/test/FormDataTest.java index b3081ba..b1ed78c 100644 --- a/src/com/silverwrist/util/test/FormDataTest.java +++ b/src/com/silverwrist/util/test/FormDataTest.java @@ -4,10 +4,13 @@ import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; +import org.apache.log4j.*; import com.silverwrist.util.*; public class FormDataTest extends HttpServlet { + private static Category logger = Category.getInstance(FormDataTest.class.getName()); + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -22,41 +25,6 @@ public class FormDataTest extends HttpServlet } // end doGet - private void old_doPost(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException - { - TestMultiHandler tmh = null; - String errmsg = null; - int count = -1; - - try - { // attempt to launch the multi handler - tmh = new TestMultiHandler(request); - count = tmh.getCount(); - - } // end try - catch (IOException e) - { // we got an error from the parser - errmsg = e.getMessage(); - - } // end catch - - PrintWriter out = response.getWriter(); - out.println("Form Test Results"); - out.println("

Form Test Results

"); - if (errmsg==null) - out.println("Success!

"); - else - out.println("ERROR: " + errmsg + "

"); - out.println("Data count was: " + String.valueOf(count) + "

"); - out.println("

");
-    tmh.dump(out);
-    out.println("
"); - out.println("Go back."); - out.println(""); - - } // end old_doPost - public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { @@ -67,40 +35,70 @@ public class FormDataTest extends HttpServlet String text_value = null; String file_name = null; String file_type = null; + int file_size = -1; try { // create the multipart handler smh = new ServletMultipartHandler(request); + + // retrieve the text parameter value text_value = smh.getValue("text"); + if (logger.isDebugEnabled()) + logger.debug("text param value = \"" + text_value + "\""); + + // check to make sure the file parameter is really a file! file_check = smh.isFileParam("file"); if (file_check) - { // copy out to file + { // get the file name and type file_name = smh.getValue("file"); file_type = smh.getContentType("file"); + file_size = smh.getContentSize("file"); + if (logger.isDebugEnabled()) + logger.debug("file param = \"" + file_name + "\", ctype = " + file_type + ", size = " + file_size); + if ((file_name!=null) && (file_name.length()>0)) - { // build the file name and save it - FileOutputStream stm = new FileOutputStream(save_dir + "/" + file_name); + { // build the file name and open a stream to save it + String real_name = save_dir + "/" + file_name; + FileOutputStream stm = new FileOutputStream(real_name); InputStream in = smh.getFileContentStream("file"); byte[] copybuf = new byte[1024]; + + // go into a copy loop int ct = in.read(copybuf); + int nbytes = 0; while (ct>=0) { // copy loop... + if (logger.isDebugEnabled()) + logger.debug("read blksize = " + ct); if (ct>0) + { // write out copy buffer data stm.write(copybuf,0,ct); + nbytes += ct; + + } // end if + ct = in.read(copybuf); } // end while + // all done - file saved stm.close(); in.close(); + if (nbytes!=file_size) + logger.warn("YIKES! expected " + file_size + " bytes but got " + nbytes + "!"); + if (logger.isDebugEnabled()) + logger.debug("saved " + nbytes + " bytes to file " + real_name); } // end if } // end if + else // this shouldn't happen + logger.warn("file param was not a file?!?!?!?"); } // end try catch (ServletMultipartException e) { // load error message + logger.error("caught ServletMultipartException: " + e.getMessage(),e); errmsg = e.getMessage(); } // end catch @@ -115,6 +113,7 @@ public class FormDataTest extends HttpServlet { // get file name and type out.println("File name: " + file_name + "

"); out.println("File type: " + file_type + "

"); + out.println("File size: " + file_size + " bytes

"); out.println("Saved to directory: " + save_dir + "

"); } // end if @@ -124,7 +123,7 @@ public class FormDataTest extends HttpServlet } // end if else out.println("ERROR: " + errmsg + "

"); - out.println("Go back."); + out.println("Go back."); out.println(""); } // end doPost