views:

117

answers:

6

I have the following form setup:

<html>
<head></head>

<body>
<form method="post" enctype="multipart/form-data" action="FileUpload">
    <table>
        <th>WEX SI Online Validation</th>
        <tr>
            <td>Step 1: Select File for Validation: </td>
            <td><input name="filename" type="file"/></td>
        </tr>
        <tr>
            <td>Step 2: Validate File:</td>
            <td><input name="validate" type="button" value="Validate"/></td>
        </tr>
        <tr>
            <td>Step 3: Download and Fix Errors:</td>
            <td><input name="download" type="button" value="Download"/></td>
        </tr>
        <tr>
            <td>Step 4: Submit</td>
            <td><input name="submit" type="submit" value="Submit"/></td>
        </tr>
    </table>
</form>
</body>

</html>

How should I handle this? I'm using Java/JSP/Servlets but am not sure how to handle the post for the upload portion of this and than the other actions.

I think it would be best to create some kind of form controller that handled the post of the form and delegated to other servlets depending on what the user is doing. I'm not sure how to tell what the user has selected though.

Thoughts? Comments? Thanks.

A: 

Apache Commons FileUpload can handle all these for you.

kgiannakakis
and how exactly?
Bozho
I'm already using it to handle the actual upload. Not all of the buttons are submitting files, but triggering other processes in the background.
Casey
+1  A: 

The type="button" buttons do not automatically submit the form. Only the type="submit" will.

If you want various buttons that each submit and perform different actions then you have several options. I think that the option you mention to have a single servlet decide what the user is doing and forward to another servlet is a good idea. You can tell what the user is doing by looking for the name of the button in the attribute map.

   String btn = request.getParameter("submitbuttonname");
   if(btn != null){
      //this was the button clicked.
   }

The second option that I can think of is to break up the form into multiple forms. Do you need to submit the file for each button? If not create a form with the data that you need to submit each with its own submit button.

Vincent Ramdhanie
+2  A: 

The value of the submit button is transmitted in the POST request along with all the other form values, with the name being the button name and the value being the button value.

So you can detect which button was pushed by checking the existance of values for each key associated with varying buttons (or if you name your buttons the same, you can merely check what the value of the key is).

Also, BUTTON elements need onClick handlers to actually submit the form and/or do any work (for SUBMIT elements the default onClick handler calls the form's submit() )

DVK
A: 

It can be handled with JavaScript.

function submitTo(url) {
    form.action = url;
    form.submit();
}

...

<input name="download" onClick="submitTo('/download')" ... />
artemb
A: 

The best approach is to have a form controller to delegate the logic to others classes, depending on the input type values passed as parameters.

Aito
+2  A: 

As for every other normal <input> element, the name-value pair of a <input type="button"> will be sent as request parameter.

The major caveat is only that <input type="button"> and <button> elements does not work properly in MSIE. In all MSIE versions, the value attribute of a button element won't be sent as parameter value, but instead its body (the tag content) will be sent!

Also, in IE6 there's another astonishing bug: not only the name-value pair of the pressed button will be sent, but those of every other unpressed button in the form will be sent as well! This way you cannot distinguish the pressed button in the server side at all.

The solution which works in combination with all browsers is to use <input type="submit"> and to give them all a different name (or the same name but a different value).

E.g.

<input type="submit" name="validate" value="Validate">
<input type="submit" name="download" value="Download">
<input type="submit" name="submit" value="Submit">

in combination with

if (request.getParameter("validate") != null) {
    // Validate button pressed.
} else if (request.getParameter("download") != null) {
    // Download button pressed.
} else if (request.getParameter("submit") != null) {
    // Submit button pressed.
}

or

<input type="submit" name="action" value="Validate">
<input type="submit" name="action" value="Download">
<input type="submit" name="action" value="Submit">

in combination with

String action = request.getParameter("action");
if ("Validate".equals(action)) {
    // Validate button pressed.
} else if ("Download".equals(action)) {
    // Download button pressed.
} else if ("Submit".equals(action)) {
    // Submit button pressed.
}

The last way provides more possibilities to abstract the one and other more nicely away at Java level.

By the way, I of course assume that you're already using Apache Commons FileUpload to process the multipart form data, if necessary with help of a Filter which puts the multipart form data back in the request parameter map, else you won't get anything from HttpServletRequest#getParameter().

BalusC
I am trying to use the last suggestion you made, all submit buttons, with the same name, different values, but when I retrieve the action from my request it is always null. I have the same html as above, except with the name changes.
Casey
Read the last paragraph of my answer :)
BalusC
At the moment, I am not parsing anything. I just have the form calling my controller servlet. However, since the form is set to multipart/form-data, I take it I have to put the information in the correct place?
Casey
ah got you! Thanks.
Casey
works great. Thanks again.
Casey
You're welcome.
BalusC