Mark,

On 11/10/23 12:53, Mark Foley wrote:
On Fri, 10 Nov 2023 17:11:59 Mark Thomas <ma...@apache.org wrote:

On 10/11/2023 16:49, Mark Foley wrote:
I recently upgraded from Tomcat 10.0.17 to 10.1.13.  When I previously upgraded
from 9.0.41 to 10.0.17 (back in 2/22) the FileUpload class broke. I fixed that
thanks to postings on stackoverflow, but now that I've
upgraded to 10.1.13 it is broken again! Here's the error I get:

An error occurred at line: [40] in the jsp file: [/schDistImportResults.jsp]
The method isMultipartContent(ServletRequestContext) is undefined for the type 
FileUpload

Tomcat's internal fork of Commons FileUpload isn't intended for
applications to use. It is not a full fork - just a limited subset of
the functionality Tomcat needs to implement the Servley upload API.

If you want to use Commons File Upload, add the JAR to your web
application and use it.

Alternatively, if you want to use the Servlet upload API then use that.

If the javax.sevlet -> jakarta.servlet transition means you can't use
your preferred version of Commons File Upload in Tomcat 10.1.x (very
likely) then run your preferred version of Commons File Upload through
Tomcat's migration tool for Jakarta EE and use the converted version of
Commons File Upload in your web application.

Depending on Tomcat internals is very likely to lead to breakage.

Mark

Thanks for your quick reply. Whatever I've been using keeps breaking. I had it
working in 9.0.14 and earlier, then it broke with 10.0.17 and I fixed that, now
it's broken again with 10.1.13. So, my "prefered" solution is whatever is
recommended and is likely to continue to be supported without breaking in future
Tomcats.

What do you recommend? And do you have a quickie template somewhere which shows
the basic include(s) and method I need? I really don't do anything very fancy.
My current "basic" implementation is:

<%@ page import="org.apache.tomcat.util.http.fileupload.*,
     org.apache.tomcat.util.http.fileupload.disk.*,
     org.apache.tomcat.util.http.fileupload.servlet.*,
     org.apache.commons.io.*" %>

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(new ServletRequestContext(request));
Iterator iter = items.iterator();
FileItem item = null;

while (iter.hasNext())
{
     item = (FileItem) iter.next();

     resultsFile = new File(getServletContext().getRealPath("") + 
"/tmp/schTaxResults.txt");

     try { item.write(resultsFile); }
         catch ( Exception e) { out.println("Exception: " + e); }
}

If you could tell me what the officially prefered Apache Tomcat FileUpload
mechanism is, and what the correct jar and functions are to accomplish the 
above, I'd be
very grateful!


No offense, but the above is horrifying. All that Java code in a JSP makes me cringe. You can do this however you want, but I'd recommend putting Java code into a proper servlet and letting the JSP handle display only.

Anyway, I'll get off my soapbox.

The easiest thing IMO for you to do is stop trying to parse the upload yourself and use the container. You must have migrated this application forward for like 10 years or something if you are still using a separate library to handle multipart-form-uploads. This has been a part of the code servlet API for some time, now, and you should use it:

import jakarta.servlet.http.Part;

...

String contentType = request.getContentType();
if(null == contentType || !contentType.startsWith("multipart/form-data;")) {
    logger.warn("Received non-multipart request");

    throw new IllegalStateException("Expected multi-part");
}

java.io.File tmpDir = (java.io.File)request.getServletContext().getAttribute("javax.servlet.context.tempdir");

java.io.File targetFile = new java.io.File(tmpDir, "schTaxResults.txt");

Part fileUpload = request.getPart("param-name");

if(null != fileUpload) {
    fileUpload.write(targetFile.getAbsolutePath());
}

I have made some obvious and not-so-obvious changes, here. First, you don't need a separate library: you are relying on the container for the multi-part handling.

Second, I have changed from uploading the file directly into the servlet context (the live running application~) into a temporary directory. If you want to serve this file back out to clients, you may want to use WebDAV or some other protocol rather than file-upload, or maybe not.

If you want to serve this file back to clients, I *highly* recommend creating a directory OUTSIDE your web application where you can push uploaded files, and then use something like <PostResources> to allow Tomcat to load content from that location, mounted on a path that won't allow users to upload binaries, etc. that might get loaded by the application.

You may want to be careful about how you are writing. If two requests come-in at the same time, thee files may overwrite each other in unpredictable ways.

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to