Using a file form field with a Java servlet - forms

I am tring to retrieve a filename or the file itself for use in a java servlet (from a web form).
I have a file form field:
<form enctype="multipart/form-data" method="post" action="SaveDictionary.do">
<label>
<input type="file" name="dictionary_file" id="dictionary_file" />
<br />
</label>
<label>
<br />
<input type="submit" name="saveDic" id="saveDic" value="Save Dictionary" />
</label>
</form>
I wanto then process it in my servlet, what do I do to process this - for a normal text field I would use something like
String myValue = (String) request.getParameter("parameter_name");
Assuming I have this class, what do I put in the doPost() method to get either the file path or the actual file contents.
#SuppressWarnings("serial")
public class SaveDictionary extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// I can't work out what goes here, the same
// String myValue = (String) request.getParameter("parameter_name"); doesn't work
response.sendRedirect("dictionary.jsp");
}
}

Multipart/form-data encoded requests are not supported by the default servlet API. You basically need to parse the request body yourself based on the HttpServletRequest#getInputStream(). But that's a precious and tedious work. You don't want to do that if you're already asking this question here at SO. Fortunately there's already a robust, thoroughly developed and maintained API out for that, the Apache Commons FileUpload API. It's in fact easy to use. You can find examples in their User Guide and tips&tricks in their FAQ.
You can also wrap it in a Filter which does all the parsing work and puts all the parameters back in the request, so that it's all transparent in the servlet code and you can continue using HttpServletRequest#getParameter() and consorts the usual way. Uploaded files can then be obtained as request attributes. Here's a basic example.
Hope this helps.

Related

Consume RESTful Service from form post

I've built a RESTful service with Spring (java annotation based configuration) which I can execute successfully via Curl. I'm trying to submit files via a HTML Form too, however that's not working.
#RequestMapping(path = "/upload", method = RequestMethod.POST)
public String handleFileUpload(#RequestPart(value = "file") MultipartFile file,
RedirectAttributes redirectAttributes) {
logger.info("POST '/upload'");
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
And I'm submitting a file via Curl as follows:
curl -i -H "Content-Type: multipart/*; boundary=------------BOUNDARY--" -X POST --noproxy localhost, localhost:8080/upload -F "file=#test.txt"
Even though my form submission has an input of type file, with the name file, I get this error via a HTML form
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
From what I've been investigating, it would seem as if the controller would expect a Model Attribute when the file is submitted via HTML Form, so what could be a good practice to resolve this? Include a controller parameter for a Model Attribute, which would be checked for null value (to distinguish between html form or other submission methods), or would a sort of Proxy controller between the HTML Form and the RESTful service be better?
The service looks good. It works fine for me on both CURL and HTML form submit.
Here is my form. Please try using this.
<html>
<head>
<title>Post Tool</title>
</head>
<body>
<h1>Sample Requests</h1>
<h2>Upload Document</h2>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
Choose a file : <input type="file" name="file" multiple/>
<input type="submit" value="Upload" />
</form>
</body>
</html>
After more research I got to know that the commons multi part resolver doesn't fare well with the new versions of spring boot. It struggles obtaining POST parameters from forms.
One solution is to use the StandardServletMultipartResolver implementation of the MultipartResolver interface!

Java RESTful service errs on #FormParam annotation

I'm writing a RESTful service app in Java EE 6. I've encountered a difficulty along defining HTTP GET service method which uses the #FormParam annotation.
Technologies that I use:
Eclipse EE Kepler IDE
JDK v7
Glassfish 3 (based on Java 6)
Jersey (part of Glassfish)
Java:
#GET
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.TEXT_HTML)
#Path("/getFromForm")
public String getFromForm(#FormParam("input") String input){
log.log(Level.INFO, "Invoked getFromForm");
String html = "<html> <body>"
+"<center><h1> "+input+"</h1></center>"
+"</body></html>";
return html;
}
JSP:
<form action="/RESTfulServiceDrill/rest/v6/html/getFromForm" method="get"
enctype="application/x-www-form-urlencoded">
<label> Add message: </label>
<input type="text" name="input"/>
<input type="submit" value="OK"/>
<input type="reset" value="clear"/>
</form>
Exception:
java.lang.IllegalStateException: The #FormParam is utilized when the content type of the request entity is not application/x-www-form-urlencoded
Any ideas what the culprit is?
You should be using POST, not GET. With GET, the browser will not set the Content-Type header as the params are sent in the URL, not the body. If you want to keep it with GET, use #QueryParam, which captures the param from the query string in the URL

JSF - Passing parameter between two RequestScoped Managed beans in JSF page [duplicate]

I am using JSF 2.2 on Glassfish 4.1.
I am trying to pass in a query parameter to as an action method argument as follows:
// Example 1. This does not work.
// at url http://localhost:8080/app/order.xhtml?email=test#email.com
<p:commandButton value="Place order" action="#{orderManager.placeOrder(param['email'])}" />
(Know that param is an implicit EL object.)
In the server log I have configured it to print the method parameter, but I can see that an empty string was passed-in, not "test#email.com" as I expected.
I have confirmed that my overall configuration is working. If I replace the above snippet with the following, then "test#email.com" is output in the server log:
// Example 2. This works.
<p:commandButton value="Place order" action="#{orderManager.placeOrder('test#email.com')}" />
I have also confirmed that my use of EL implicit objects is feasible. The following snippet works if I retrieve the parameter from the FacesContext (after removing the email parameter from placeOrder's signature, of course):
// Example 3. This works.
<p:commandButton value="Place order" action="#{orderManager.placeOrder()}" >
<f:param name="email" value="#{param['email']}"/>
</p:commandButton>
And here is a final mystery, one that truly confuses me, if I use the following snippet, I can retrieve the "email" parameter from both the method parameter and the FacesContext, but recall that the method parameter wasn't retrievable in Example 1!
// Example 4. This works, and BOTH parameters are retrievable!
<p:commandButton value="Place order" action="#{orderManager.placeOrder(param['email'])}" >
<f:param name="email" value="#{param['email']}"/>
</p:commandButton>
Can I pass in an implicit JSF EL object as an action method parameter?
And do you have an explanation for why it seems to work in Example 4, but not Example 1?
The action attribute is evaluated during apply request values phase of the HTTP request triggered by the form submit, which is thus a different HTTP request than the one which produced the HTML output with therin the form (and having the email parameter present in the request).
The <f:param> tag is evaluated during render response phase of the HTTP request which needs to produce the HTML output with therein the form. This thus ends up "hardcoded" in the generated HTML output (on contrary to the EL method arguments in the action attribute!). When the user submits the form, this just gets passed back to the server as a plain vanilla String request parameter (which you would need to convert back if it was originally a complex type).
This has got nothing to do with whether the value is an implicit EL object or not.
That said, there are 2 other ways:
Pass it as hidden input (no, not with <h:inputHidden>).
<h:form>
<input type="hidden" name="email" value="#{param.email}" />
...
</h:form>
Set it as property of a view scoped bean, it'll stay in bean as long as the view lives.
<f:metadata>
<f:viewParam name="email" value="#{viewScopedBean.email}" />
</f:metadata>

Restful web service using #formparam to produce xml file(marshalling)

I have a basic html form with a text box and a submit button
I am interested in creating a restful web service wherein I will be exposing a method
of MY EJB(from a working search based application) to retrieve values from the database..
I will be using the value entered in the text box as a where clause of SQL query in the EJB method of my application.
I am new to restful service.
I want to generate a xml file on click of the submit button
Any suggestions..?
The IDE I am using is net beans.
If you want to retrieve data, a simple GET request should be enough.
HTML form
<form action="/path/to/the/resource" method="GET">
<input type="text" name="query" id="query"/>
<input type="submit" value="Submit Query/>
</form>
JAX-RS Resource
#Path("/path/to/the/resource")
public class MyResource {
#GET
#Produces("application/xml")
public Response query(#QueryParam("query") String query) {
// retrieve values from the database using the query
MyJaxbAnnotatedDataClass result = ...;
return Response.ok(result).build();
}
}
JAXB annotated class
#XmlRootElement
public class MyJaxbAnnotatedDataClass {
// many fields, getters, setters with JAXB annotations
}

How to change a form's action in Lift

I am building a Lift application, where one of the pages is based on the "File Upload" example from the Lift demo at: http://demo.liftweb.net/file_upload.
If you look at the source code for that page... you see that there is a Lift "snippet" tag, surrounding two "choose" tags:
<lift:snippet type="misc:upload" form="post" multipart="true">
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
</choose:post>
<choose:get>
Select a file to upload: <ul:file_upload></ul:file_upload><br >
<input type="submit" value="Upload File">
</choose:get>
</lift:snippet>
The idea is that when a user hits the page for the first time (i.e. a GET request), then Lift will show the form for uploading a file. When the user submits the form (i.e. a POST request to the same page), then Lift instead displays the outcome of the file being processed.
With my application, the new wrinkle is that my "results" POST view needs to also contain a form. I want to provide a text input for the user to enter an email address, and a submit button that when pressed will email information about the processed file:
...
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!-- BEGIN NEW STUFF -->
Output: <br/>
<textarea rows="30" cols="100"><ul:output></ul:output></textarea>
<br/><br/>
Email the above output to this email address:<br/>
<ul:email/><br/>
<input type="submit" value="Email"/>
<!-- END NEW STUFF -->
</choose:post>
...
However, both the GET and POST versions of this page are wrapped by the same Lift-generated form, which has its "action" set to the same snippet in both cases. How can I change this such that in the POST version, the form's action changes to a different snippet?
In a typical web framework, I would approach something like this with an "onclick" event and two basic lines of JavaScript. However, I haven't even begun to wrap my mind around Lift's... err, interesting notions about writing JavaScript in Scala. Maybe I need to go down that route, or maybe there's a better approach altogether.
First, I will suggest you use Lift's new designer friendly CSS binding instead of the custom XHTML tag.
And one thing you should remember when you're using Lift's snippet, is that it is recursive, you could put an lift snippet inside another snippet's HTML block.
For example, if you wish there is another form after POST, then just put it into the block.
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!--
The following is same as <lift:snippet type="EMailForm" form="post" multipart="true">
-->
<form action="" method="post" data-lift="EMailForm">
<input type="text" name="email"/>
<input type="submit" />
</form>
</choose:post>
Then deal with the email form action at snippet class EMailForm.
Finally, you may pass the filename / minetype and other information by using hidden form element or SessionVar.
I agree with Brian, use Lift's new designer friendly CSS binding.
Use two separate forms, one for the file upload and one for the submitting the email. Use S.seeOther to redirect the user to the second form when the first has finished processing.
I also prefer the new 'data-lift' HTML attribute.
File upload HTML:
<div data-lift="uploadSnippet?form=post">
<input type="file" id="filename" />
<input type="submit" id="submit" />
</div
File upload snippet:
class uploadSnippet {
def processUpload = {
// do your processing
....
if (success)
S.seeOther("/getemail")
// if processing fails, just allow this method to exit to re-render your
// file upload form
}
def render = {
"#filename" #> SHtml.fileUpload(...) &
"#submit" #> SHtml.submit("Upload", processUpload _ )
}
}
GetEmail HTML:
<div data-lift="getEmailSnippet?form=post">
<input type="text" id="email" />
<input type="submit" id="submit" />
</div
Get Email Snippet:
class getEmailSnippet {
def processSubmit = {
....
}
def render = {
"#email" #> SHtml.text(...) &
"#submit" #> SHtml.submit("Upload", processSubmit _ )
}
There's a bit more on form processing in my blog post on using RequestVar's here:
http://tech.damianhelme.com/understanding-lifts-requestvars
Let me know if you want more detail.
Hope that's useful
Cheers
Damian
If somebody comes up with a more elegant (or "Lift-y") approach within the next few days, then I'll accept their answer. However, I came up with a workaround approach on my own.
I kept the current layout, where the view has a GET block and a POST block both submitting to the same snippet function. The snippet function still has an if-else block, handling each request differently depending on whether it's a GET or POST.
However, now I also have a secondary if-else block inside of the POST's block. This inner if-else looks at the name of the submit button that was clicked. If the submit button was the one for uploading a file, then the snippet handles the uploading and processing of the file. Otherwise, if it was the send email submit button shown after the first POST, then the snippet processes the sending of the email.
Not particularly glamorous, but it works just fine.