On Fri Nov 10 15:57:50 2023 Christopher Schultz <ch...@christopherschultz.net> 
wrote:
>
> 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.  ...
> >>> 
> >>> [deleted]
> >>>
> >>> 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.
> >>
> >> [deleted]
> > 
> > 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:

This program was originally written 9 years ago and I just monkey-typed the
original solution from advice and help I found on the web. Likewise, when things
broke on my upgrade to Tomcat 10.0.17 I got the "how to fix" from StackOverflow.
In short, I've always depended on the kindness of strangers to get this Upload 
mechaism working!

> 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've removed my "horrifying" code and put your suggested code in place. I
replaced your:

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

with:

    out.println("Expected multi-part");

Just to get things compiling OK.  I'll deal with errors later. With that 
change, it
compiled w/o problem.  I then attempted an upload.  The line:

   if(null == contentType || !contentType.startsWith("multipart/form-data;")) {

returned TRUE so it did detect a multipart upload. Yay! That was a relief 
However

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

Gave me the error:

java.lang.IllegalStateException: Unable to process parts as no multi-part 
configuration has been provided

So, what does it mean that "no multi-part configuration has been provided"? Is
"param-name" something I'm supposed to fill in? I tried substituting the 
<input type="file"> field name, "taxResults", but that gave the same error.

> 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.

I may revisit this after I get your basic solution working. This particular app
can upload more than one file, but first things first.

> 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.

In this case, this same app reads the "uploaded" file and updates a database,
but thanks for this tip.

> 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

Thanks --Mark F.

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

Reply via email to