I am newbie to restful webservice.My requirement is to upload a multiple files.i successfully write the code for uploading multiple files in restful web service.Below is my code.
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces("text/plain")
#Path("/multipleFiles")
public String registerWebService(#Context HttpServletRequest request)
{
String responseStatus = SUCCESS_RESPONSE;
String candidateName = null;
//checks whether there is a file upload request or not
if (ServletFileUpload.isMultipartContent(request))
{
final FileItemFactory factory = new DiskFileItemFactory();
final ServletFileUpload fileUpload = new ServletFileUpload(factory);
try
{
/*
* parseRequest returns a list of FileItem
* but in old (pre-java5) style
*/
final List items = fileUpload.parseRequest(request);
if (items != null)
{
final Iterator iter = items.iterator();
while (iter.hasNext())
{
final FileItem item = (FileItem) iter.next();
final String itemName = item.getName();
final String fieldName = item.getFieldName();
final String fieldValue = item.getString();
if (item.isFormField())
{
candidateName = fieldValue;
System.out.println("Field Name: " + fieldName + ", Field Value: " + fieldValue);
System.out.println("Candidate Name: " + candidateName);
}
else
{
final File savedFile = new File(FILE_UPLOAD_PATH + File.separator
+ itemName);
item.write(savedFile);
}
}
}
}
catch (FileUploadException fue)
{
responseStatus = FAILED_RESPONSE;
fue.printStackTrace();
}
catch (Exception e)
{
responseStatus = FAILED_RESPONSE;
e.printStackTrace();
}
}
return responseStatus;
}
Is it good to upload multifiles in single request?
I want to consume the above restful webservice using restful template or jersey or any other java client.
Can anybody please guide me to write the client code for consuming the above webservice?
Any help will be greatly appreciated!!!
Related
I need to upload images in my project. How to get the upload path in SpringMVC.
The path is;
/home/cme/project/eclipse/workspace_12_11/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/fileUploadTester/upload
The following error;
The method getServletContext() is undefined for the type HomePageController
appears when I use this code;
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
My code is
public ModelAndView UploadPhoto(#ModelAttribute User user, HttpServletRequest request, HttpServletResponse response) throws IOException {
final String UPLOAD_DIRECTORY = "upload";
final int THRESHOLD_SIZE = 1024 * 1024 * 3; // 3MB
final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
String value[] = new String[10];
int i = 0;
// checks if the request actually contains upload file
if (!ServletFileUpload.isMultipartContent(request)) {
PrintWriter writer = response.getWriter();
writer.println("Request does not contain upload data");
writer.flush();
return; //here is error This method must return a result of type ModelAndView
}
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(THRESHOLD_SIZE);
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(MAX_FILE_SIZE); //here error The method setFileSizeMax(int) is undefined for the type ServletFileUpload
upload.setSizeMax(MAX_REQUEST_SIZE);
String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; // here error The method getServletContext() is undefined for the type Homepage Controller
// creates the directory if it does not exist
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
try {
List < FileItem > items = upload.parseRequest(request); // request is HttpServletRequest
for (FileItem item: items) {
if (item.isFormField()) { // text fields, etc...
String fieldName = item.getFieldName();
System.out.print("fieldname" + fieldName);
value[i] = item.getString();
System.out.print("from uploader" + value[i]);
i++;
} else {
//String fileName=new File(item.getName()).getName(); Use this to use default file name
String name = value[0];
System.out.println("file uploader name" + name);
String filePath = uploadPath + File.separator + name;
System.out.println(filePath);
File storeFile = new File(filePath);
try {
item.write(storeFile);
} catch (Exception ex) {
}
}
}
System.out.println("uploaded successfully");
} catch (Exception ex) {
System.out.println("error not uploaded");
}
return new ModelAndView("ChangePhoto");
}
Three error
This method must return a result of type ModelAndView
The method setFileSizeMax(int) is undefined for the type ServletFileUpload
The method getServletContext() is undefined for the type Homepage Controller
Use below code to autowire ServletContext object in SpringMVC
#Autowired
ServletContext context;
and after that try to execute your code like
String uploadPath = context.getRealPath("") + File.separator + UPLOAD_DIRECTORY;
You can get it in your controller like this;
private ServletContext context;
public void setServletContext(ServletContext servletContext) {
this.context = servletContext;
}
but for this your controller must implement ServletContextAware interface
Try this:
#Autowired
ServletContext servletContext;
This is just another alternative
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getServletContext()
The parameters you passed or set to the ServletContext object, are stored into HttpServletRequest object, you can access them anywhere in application in following way:
public void method(HttpServletRequest request){
String email=request.getServletContext().getInitParameter(“email”);
}
My question is how does setSizeThreshold and setRepository work.
Correct me if I am wrong, my understand is if the file size > setSizeThreshold(what ever the number) then it should send the file to setRepository temporary stored. But I never see this file being stored in the setRepository(filePath). I didn't setFileCleaningTracker so technically the file should still be in setRepository(filePath)?
how to test if Repository is working? is there a way?
Here is my code, everything is from the doc nothing really special.
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(20480); // purposely make it small to test
factory.setRepository(new File(root + "tempFile"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
//upload.setSizeMax(20480); // This makes the upload stop
try
{
// Parse the request
List<FileItem> items = upload.parseRequest(request);
// Process the uploaded items
Iterator<FileItem> i = items.iterator();
while(i.hasNext())
{
FileItem item = i.next();
//request.setAttribute("item", item);
if(item.isFormField()){
String fieldName = item.getFieldName();
String fieldValue = item.getString();
out.println(fieldName + ": " + fieldValue);
}
else
{
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
File name = new File(item.getName());
// File.separator: "/"
item.write( new File(root + "uploads" + File.separator + name));
}
}
} catch (FileUploadException ex)
{
ex.printStackTrace();
} catch (Exception ex)
{
Logger.getLogger(uploadFileServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
In the Doc
Larger items should be written to a temporary file on disk.
Very large upload requests should not be permitted.
What is exactly "very large"? what size is consider very large?
Thanks in advance...
public class NServletController extends HttpServlet {
private static final long serialVersionUID = 1L;
//private boolean isMultipart;
private String FilePath;
private File file;
private String Address="";
private String Telephone="";
private String Email="";
private String MobileNumber="";
private String Name ="";
private String Workdetails="";
private String AccountName="";
private String BankName="";
private String Accountnumber="";
private String BranchName="";
private String Ifsdetails="";
private String Pannumber="";
//private String submit="";
private String filename="";
FileInputStream fis=null;
// private String name="";
private int rs1 = 0;
private String r="";
private int rs3=0;
String filePath = "E:\\Myuploads\\";
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> fields = upload.parseRequest(request);
Iterator<FileItem> it = fields.iterator();
if (!it.hasNext()) {
return;
}
while (it.hasNext()) {
FileItem fileItem = it.next();
boolean isFormField = fileItem.isFormField();
if (isFormField && fileItem.getFieldName().equals("name")) {
Name=fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("address"))
{
Address = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("email"))
{
Email = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("mobileno"))
{
MobileNumber = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("telephone"))
{
Telephone = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("work"))
{
Workdetails= fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("accountholdername"))
{
AccountName = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("bankname"))
{
BankName = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("accountno"))
{
Accountnumber = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("branchname"))
{
BranchName = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("ifsccode"))
{
Ifsdetails = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("pannumber"))
{
Pannumber = fileItem.getString();
}
else if(isFormField && fileItem.getFieldName().equals("submit"))
{
String submit = fileItem.getString();
}
else {
filename = FilenameUtils.getName(fileItem.getName());
OutputStream outputStream = new FileOutputStream(filename);
InputStream inputStream = fileItem.getInputStream();
int readBytes = 0;
byte[] buffer = new byte[10000];
while ((readBytes = inputStream.read(buffer, 0, 10000)) != -1) {
outputStream.write(buffer, 0, readBytes);
}
if(fileItem.getName()!= null){
// out.println("<td><img width='100' heigth='100' src="+ request.getContextPath() + "/images/"+ fileItem.getName() + "></td>");
if (filename.lastIndexOf("\\") >= 0) {
file = new File(filePath
+ filename.substring(filename
.lastIndexOf("\\")));
} else {
file = new File(filePath
+ filename.substring(filename
.lastIndexOf("\\") + 1));
}
fileItem.write(file);
}
}
}
}catch(Exception e)
{
e.printStackTrace();
}
I have a multipart/form-data form with some <input type='text'> and <input type='file'> fields.
I use this code
List<FileItem> multipartItems = null;
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
System.out.println("false");
} else {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
multipartItems = null;
try {
multipartItems = upload.parseRequest(request);
System.out.println("true "+multipartItems.toString());
} catch (FileUploadException e) {
e.printStackTrace();
}
}
to find out if the form has multipart content.
Then, I use
Map<String, String[]> parameterMap = new HashMap<String, String[]>();
for (FileItem multipartItem : multipartItems) {
if (multipartItem.isFormField()) {
processFormField(multipartItem, parameterMap);
} else {
request.setAttribute(multipartItem.getFieldName(), multipartItem);
}
}
By running the first snippet of code, the else is executed, but at the end multipartItems is null.
For this reason, the for in the second code snippet is never executed.
I don't know why there is this behaviour. I'm using Struts 1.3.10
EDIT
How can I check if struts has already parsed the request?
If so, is there a way to turn off it only for a particular form?
EDIT 2
I have a dynamic form, coded in json format. I have a form bean for json and for hidden properties. Then I parse the json "by hand". All works perfectly, but now I have to add input type=file fields and use the multipart/form-data enctype.
To prevent struts request parsing I put in the web.xml:
<init-param>
<param-name>multipartClass</param-name>
<param-value>none</param-value>
</init-param>
But it doesn't seem to work
Initialize a FileItem, like below:
FileItem fileItem = null;
Then call this method
public boolean getParameters(HttpServletRequest request, PrintWriter out) {
List fileItemsList = null;
try {
if (ServletFileUpload.isMultipartContent(request)) {
ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());
try {
fileItemsList = servletFileUpload.parseRequest(request);
} catch (FileUploadException ex) {
}
String optionalFileName = "";
Iterator it = fileItemsList.iterator();
while (it.hasNext()) {
FileItem fileItemTemp = (FileItem) it.next();
if (fileItemTemp.isFormField()) {
// for other form fields that are not multipart
// if (fileItemTemp.getFieldName().equals("commonName")) {
// commonName = fileItemTemp.getString();
// }
} else {
if (fileItemTemp.getFieldName().equals("media_file")) {
fileItem = fileItemTemp;
}
}
}
}
} catch (Exception e) {
}
return true;
}
I have used this example to file upload using servlet and jsp is working fine for me . Click here
Example has been explained in detail and if you face any problem then ask me, I have used this.
I'm using jsp and a servlet to do this.
I have a contact form that send a email with some data (name, subject, question,contact email etc) and a file.
when I submit the form, and get the servlet response only the first thing is returned.
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
In this order the file is uploaded succesfully, but the other parameters (name, mail etc) are null.
In the order below, the parameters are ok, they return the data correctly. But the file is not uploaded.
//testing the rest of parameters
out.println("REQUEST LIST"
"\n" request.getParameter("name")
"\n" request.getParameter("mail")
"\n" request.getParameter("subject")
"\n" request.getParameter("ask")
"\n");
String file= fileUpload(request); //upload the client's file and return the absolute path of the file in the server
How can I have both?
Thanks!
You should extract the request parameters using the same API (e.g. Apache Commons FileUpload) as you've extracted the uploaded file. This is usually not interchangeable with calling getParameter() as the request body can be parsed only once (the enduser ain't going to send the same request twice, one to be parsed by the file upload parsing API and other to be parsed by getParameter()).
See also:
How to upload files to server using JSP/Servlet?
Look if the following code helps you. This is just an example. You may have to tweak it
Create a class called FileUploader which returns ServletFileUpload object
public class FileUploader
{
private static ServletFileUpload uploader;
private FileUploader()
{
}
public static synchronized ServletFileUpload getservletFileUploader(String tempDir, int maxSizeInMB)
{
if(uploader == null)
{
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(new File(tempDir));
uploader = new ServletFileUpload(factory);
uploader.setFileSizeMax(maxSizeInMB * 1024 * 1024);
}
return uploader;
}
}
Now you can process a request and read all the data
protected MultiPartFormData handleMultiPartRequest(HttpServletRequest request)
throws FileSizeLimitExceededException
{
if(!isMultipartRequest(request))
return null;
ServletFileUpload upload = FileUploader.getservletFileUploader(tempDir, 50);
MultiPartFormData data = new MultiPartFormData();
try
{
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items)
{
if(item.isFormField())
{
data.getParameters().put(item.getFieldName(), item.getString());
}
else
{
String filename = item.getName();
//Internet explorer and firefox will send the file name differently
//Internet explorer will send the entire path to the file name including
//the backslash characters etc ... we should strip it down
//THIS IS HACKY
if(filename.indexOf("\\") != -1)
{
int index = filename.lastIndexOf("\\");
filename = filename.substring(index + 1);
}
if(filename == null || filename.equals(""))
{
//do nothing
}
else
{
File uploadFile = new File(uploadDir + File.separator + randomFileName);
item.write(uploadFile);
data.addFile(item.getFieldname(), item.getString());
}
}
}
}
catch(FileSizeLimitExceededException e)
{
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
return data;
}
After parsing the request I am storing it in some object called MultipartFormData which can be used to get request parameters
public class MultiPartFormData {
private Hashtable<String, String> parameters;
private Hashtable<String, String> uploadedFiles;
public MultiPartFormData()
{
this.parameters = new Hashtable<String, String>();
this.uploadedFiles = new Hashtable<String, String>();
}
public Hashtable<String, String> getParameters() {
return parameters;
}
public void setParameters(Hashtable<String, String> parameters) {
this.parameters = parameters;
}
public void getParameter(String paramName) {
if(this.parameters.contains(paramName))
return tyhis.parameters.get(paramName);
return null;
}
public void addFile(String key, String filename) {
uploadedFile.put(key, filename);
}
public void getFilename(String key) {
uploadedFile.get(key);
}
}
I am not able to get values from both files and text input in a servlet when my form includes multipart/form-data. I am using the apache.commons.fileuploads for help with the uploads. Any suggestions. Also in the code below there are some things that I feel should be more efficient. Is there a better way to store these multiple files in a db.
public void performTask(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
{
boolean promo = false;
Database db = new Database();
Homepage hp = db.getHomePageContents();
String part = ParamUtils.getStringParameter(request, "part", "");
if(part.equals("verbage"))
{
String txtcontent = (String)request.getParameter("txtcontent");
String promoheader = (String)request.getParameter("promoheader");
String promosubheader = (String)request.getParameter("promosubheader");
hp.setBodyText(txtcontent);
hp.setPromoHeader(promoheader);
hp.setPromoSubHeader(promosubheader);
System.err.println(txtcontent);
}
else
{
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart)
{
}
else {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
try {
items = upload.parseRequest(request);
//System.err.print(items);
} catch (FileUploadException e) {
e.printStackTrace();
}
Iterator itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
if(item.getFieldName().equals("mainimg1"))
{
if(item.getName() !="") hp.setMainImg1(item.getName());
}
if(item.getFieldName().equals("mainimg2"))
{
if(item.getName() !="") hp.setMainImg2(item.getName());
}
if(item.getFieldName().equals("mainimg3"))
{
if(item.getName() !="") hp.setMainImg3(item.getName());
}
if(item.getFieldName().equals("promoimg1"))
{
promo = true;
if(item.getName() !="")
{
hp.setPromoImg1(item.getName());
try {
File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg1.jpg");
item.write(savedFile);
//System.err.print(items);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
if(item.getFieldName().equals("promoimg2"))
{
if(item.getName() !="")
{
hp.setPromoImg2(item.getName());
try {
File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg2.jpg");
item.write(savedFile);
//System.err.print(items);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
if(item.getFieldName().equals("promoimg3"))
{
if(item.getName() !="")
{
hp.setPromoImg3(item.getName());
try {
File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg3.jpg");
item.write(savedFile);
//System.err.print(items);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
System.err.println("FNAME =" + item.getFieldName() + " : " + item.getName());
if (item.isFormField()) {
}
else {
try {
if(!promo)
{
String itemName = item.getName();
File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/"+itemName);
item.write(savedFile);
}
//System.err.print(items);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
}
}
db.updateHomePageContent(hp);
When using multipart/form-data, the normal input field values are not available by request.getParameter() because the standard Servlet API prior to version 3.0 doesn't have builtin facilities to parse them. That's exactly why Apache Commons FileUpload exist. You need to check if FileItem#isFormField() returns true and then gather them from the FileItem.
Right now you're ignoring those values in the code. Admittedly, the FileItem is a misleading name, if it was me, I'd called it MultipartItem or just Part representing a part of a multipart/form-data body which contains both uploaded fields and normal parameters.
Here's a kickoff example how you should parse a multipart/form-data request properly:
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// Process normal fields here.
System.out.println("Field name: " + item.getFieldName());
System.out.println("Field value: " + item.getString());
} else {
// Process <input type="file"> here.
System.out.println("Field name: " + item.getFieldName());
System.out.println("Field value (file name): " + item.getName());
}
}
Note that you also overlooked a MSIE misbehaviour that it sends the full client side path along the file name. You would like to trim it off from the item.getName() as per the FileUpload FAQ:
String fileName = item.getName();
if (fileName != null) {
filename = FilenameUtils.getName(filename);
}
I have had similar problems in the past. The only way i could find round the problem was to put the fileupload into its own form.