0

I've been reading a lot in the past 3 days, trying to figure out a way to solve my problem, Is it posible to change upload path with a servlet?, I've tried many many ways, and now I understand a lot more about Java, but I still haven't been able to find a solution to my problem.

The closest to a work around I've found is using a filter and HttpServletRequestWrapper and HttpServletResponseWrapper, but my problem is, like a lot of people has asked in here, is that after getting the response once, it is gone, many suggest using the wrappers, but the wrapper is gone too after 1 use.

My code trying to achieve a very simple working example:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {

    HttpServletRequest httpReq = (HttpServletRequest) request;
    HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(httpReq);

    List<FileItem> items = upload.parseRequest(reqWrapper); //<--All cool 
    filterChain.doFilter(reqWrapper, response); //<--reqWrapper still
           //has request but when I try to get the file 
           //through org.apache.commons.fileupload.FileUpload, the file is null
}

Also if I try it like the example explained here: Differences between ServletResponse and HttpServletResponseWrapper?

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {

    HttpServletRequest httpReq = (HttpServletRequest) request;
    HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(httpReq);

    filterChain.doFilter(reqWrapper, response); //<--All cool

//**It goes and does an action, which gets Form parameters and file from a POST request and saves file to folder within context**

    List<FileItem> items = upload.parseRequest(reqWrapper);//<--throws exception: 
     //org.apache.commons.fileupload.FileUploadException: Stream Closed
}

I have also implemented classes for my wrappers and they work fine, but still, when I try to use the request again in the same instance, its gone. What's the proper approach to do this, or is it impossible to do?

I only dare to ask this risking negative votes because I've spend over 40 hours trying to find a solution to this, but I simply can't figure it out. Thanks for patience and understanding.

EDIT: Forgot to mention that I'm doing this to get the input values and a file from a post request multipart data

EDIT2: Changed comments on code to try to be more clear.

EDIT3: Changed comments again to show stack trace exceptions

What I'm trying to achieve is to use the form POST data twice. This is to replicate the uploaded file without having to modify the original action(servlet). I thought HttpServletRequestWrapper, would wrap my POST Data from my form, so that I could reuse it, but now I understand it doesn't.

Is there anyway to achieve this?

Community
  • 1
  • 1
Lauro182
  • 1,597
  • 3
  • 15
  • 41
  • What do you mean it's gone? What is `null`? – Sotirios Delimanolis Feb 19 '15 at 02:12
  • And what do you mean _try to use the request again_? Reuse it how, where? What does `parseRequest` do? – Sotirios Delimanolis Feb 19 '15 at 02:13
  • By null I mean that the request parameters has been consumed already and the request is null. – Lauro182 Feb 19 '15 at 05:21
  • I still don't understand. What request parameters? Where do you consume them? Where do you need them a second time? What _request_ is `null`? It's impossible for `reqWrapper` to be `null`. It's improbably for `httpReq` to be `null` unless you have other `Filter`s. – Sotirios Delimanolis Feb 19 '15 at 05:24
  • Please post a stack trace and/or reproducible code because the things you are describing are impossible. In the first snippet, the only way for the marked line to cause a NPE is if `filterChain` is `null`. The API precludes that. In your second snippet, `reqWrapper` cannot be `null`. You've initialized it at the beginning of the method and left it it that way. – Sotirios Delimanolis Feb 19 '15 at 05:34
  • You are right man, I was overwhelmed with so many things I have read and tested, but now I have a different problem, stream is closed on my second request, I get this exception: org.apache.commons.fileupload.FileUploadException: Stream Closed – Lauro182 Feb 19 '15 at 17:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71291/discussion-between-user2958190-and-sotirios-delimanolis). – Lauro182 Feb 19 '15 at 20:35

1 Answers1

0

Now I know what they really do, well, like their names implies, they wrap the request and the response, and this has some use, but not for what I wanted to do. You can't request data from client twice, the client sends you the data once, and only once, so if you wrap request to use again, you will request the data again, but the client won't send it again since it already sent it. And the wrappers doesn't wrap the POST data, once you recieve it, you have to figure out a way to store it somewhere and use it again however you want.

In my case I made the form methods statics and I could access the form elements and values from the filter. Example:

public class MyActionForm extends org.apache.struts.action.ActionForm {

private static org.apache.struts.upload.FormFile file;
private static String anyname;

public static FormFile getFile() {
    return file;
}

public void setFile(FormFile file) {
    this.file = file;
}

public static String getAnyname() {
    return anyname;
}

public void setAnyname(String anyname) {
    this.anyname = anyname;
}

And inside the filter:

    String name = MyActionForm.getAnyname();                
    FormFile imagen = MyActionForm.getFile();

And now I don't need to process request again, since I wouldn't get the data anyways, and I don't need to parse the data or anything, I simply use the form elements values, which is what I wanted to get.

Hope this helps somebody.

Lauro182
  • 1,597
  • 3
  • 15
  • 41