I am trying to implement a file-upload functionality using webkitdirectory with java backend.
Step1. Design a HTML form with webkitdirectory
<form action="DataUpload" method="post" enctype="multipart/form-data">
<input type="text" name="dbName" value="Database Name Here" id="dbName"/>
<input type="file" id="ctrl" webkitdirectory directory multiple/>
<input type="submit" />
</form>
Step 2. Passing information from form to Servlet
public class DataUpload extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator fileIterator;
try {
fileIterator = upload.getItemIterator(request);
InputStream inputStream = null;
BufferedReader br = null;
System.out.println("CheckPoint 1");
while(fileIterator.hasNext()) {
System.out.println("CheckPoint 2");
FileItemStream item = fileIterator.next();
String inputFileName = FilenameUtils.getName(item.getName());
inputStream = item.openStream();
inputFileName = inputFileName.split("\\.")[0];
List<String[]> list = new ArrayList<String[]>();
// Getting File
br = new BufferedReader(new InputStreamReader(inputStream)); // Getting the object to read file
String line;
while((line = br.readLine())!= null){// While condition ends then end of file is reached.
list.add(line.split(","));
}
// Checking if File is Empty
if (list.size() == 0){
System.err.println("File Empty");
}else{
// TODO : Parameter Parser.
// DO JOB HERE
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My code, doesn't give any programming error, but it does not pass through the CheckPoint 2, i.e. it doesn't go inside the while loop. I tried looking into various post, such as:
Keep Directory Structure When Uploading
How to upload files to server using JSP/Servlet? - While this question shows maximum resemblance to problem in question, This question works for selecting multiple files in a folder, where the problem here is question is to upload files in different sub directories inside a folder.
I was wondering, if this was possible using solely java servlets without using javascript. I was able to upload multiple files inside a single folder. But, code doesn't seem to work, when I select a folder as input, instead it works when I select a particular file or a subset of files.
HTML File Form
<form onsubmit="readFiles()">
<input type="file" name="files" webkitdirectory directory multiple id="files">
<input type="submit">
</form>
JavaScript Function
function readFiles(){
var files = document.getElementById("files").files;
for (var file = 0 ; file < files.length; file++) {
var reader = new FileReader();
reader.onload = function(e){
var object = new Object();
object.content = e.target.content;
var json_upload = "jsonObject=" + JSON.stringify(object);
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
xmlhttp.open("POST", "http://localhost:8080/readFileServlet");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(json_upload);
}
reader.readAsBinaryString(files);
}
}
Java Function:
JSONObject jObj = new JSONObject(request.getParameter("jsonObject"));
in a post method try
make #Autowired ServletContext c;
or take object from it in servlets
byte[] bytes = file.getBytes();
String UPLOAD_FOLDEdR=c.getRealPath("/images");
Path path = Paths.get(UPLOAD_FOLDEdR +"/"+ file.getOriginalFilename());
Files.write(path, bytes);
Related
I'm trying to make a web app version of a Java program I wrote, using Java JAX RS and Tomcat.
I wrote a .java service for uploading CSV files and performing some data operations on them which results in an ArrayList. After the users upload their first .csv file they proceed to another web page, where they need to upload a 2nd .csv file.
A very similar Reponse class service is used for this 2nd file upload. The difference is that to do the data operations on the 2nd file, I need the ArrayList that was created by the first Java file associated with the prior CSV upload page. I'm not sure how to get that data into this service.
The HTML in question is simply
<!DOCTYPE html>
<html >
<head ng-cloak>
<meta charset="UTF-8">
<title>Laureate SilverBullet</title>
<link rel="stylesheet" href="../css/normalize.css">
<link rel="stylesheet" href="../css/style.css">
</head>
<body ng-cloak ng-app="fileUpload" ng-controller="MyCtrl">
<h1>Upload Prediction (Scoring) Data</h1>
<link rel="stylesheet" href="../css/style.css">
<form action="../services/upload/csv_scoring" method="post" enctype="multipart/form-data">
<p>
<input type="file" name="file" size="45" accept=".csv"/>
</p>
<input type="submit" value="Score" class="file-upload-button" />
</form>
and what I have so far for the 2nd service is (skipping the import statements):
#Path("/upload")
public class UploadFileServiceScoring
{
#POST
#Path("/csv_scoring")
#Consumes({MediaType.MULTIPART_FORM_DATA})
public Response uploadCsvFile( #FormDataParam("file") InputStream fileInputStream,
//public ArrayList uploadCsvFile( #FormDataParam("file") InputStream fileInputStream,
#FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception {
String UPLOAD_PATH = "D:/sb_user_uploads/";
try {
int read = 0;
byte[] bytes = new byte[1024];
OutputStream out = new FileOutputStream(new File(UPLOAD_PATH + fileMetaData.getFileName()));
while ((read = fileInputStream.read(bytes)) != -1)
{
out.write(bytes, 0, read);
}
out.flush();
out.close();
String filelocation = new String(UPLOAD_PATH + fileMetaData.getFileName());
String[] csvarff = new String[2];
csvarff[0] = filelocation;
csvarff[1] = "datafile_scoring.arff";
CSV2Arff.main(csvarff);
BufferedReader datafile = null;
Instances test = null;
datafile = readDataFile.readDataFile("datafile_scoring.arff");
test = new Instances(datafile);
// need first ArrayList here!!
I ended up writing out the ArrayList as an I/O file in the first script:
String ioFile = "temp.dat";
try{
ObjectOutputStream outputStream =
new ObjectOutputStream(
new FileOutputStream(ioFile));
outputStream.writeObject(al1);
outputStream.close();
}
catch ( IOException e ){
System.out.println("Error writing to file " + ioFile);
System.exit(0);
}
Then reading it back in within the 2nd service:
String ioFile = "temp.dat";
ArrayList al1 = null; // ArrayList al = new ArrayList();
try{
ObjectInputStream inputStream =
new ObjectInputStream(
new FileInputStream (ioFile));
al1 = (ArrayList)inputStream.readObject();
inputStream.close();
System.out.println("Successfully read the file " + ioFile);
}
catch (Exception e){
System.out.println("Problem reading the file " + ioFile);
System.exit(0);
}
If there's a better solution, such as one that avoids writing to disk and thereby creating another copy of the object, please add it as an answer and I'll accept it.
This question already has answers here:
How can I upload files to a server using JSP/Servlet?
(14 answers)
Closed 7 years ago.
I am writing an Application to Upload Image files in to the server.
I am declaring a form giving the type as enctype="multipart/form-data">
I have declare few hidden variables also inside this form. When I am trying to get the Values of these hidden variable inside a Servlet it comes as "Null".
If I remove the enctype, I could retrieve the correct values of the variable.
JSP Form :
<FORM name="form1" enctype="multipart/form-data"><!-- T1787NM -->
<input type=hidden name="stringurl" value="<%=stringurl%>">
<input type=hidden name="savetype" value="<%=ACTION%>">
<INPUT type="hidden" name="iReq" value="<%=iReq%>">
<INPUT type="File" name="FileUpload" id="fileInput">
</FORM>
Servlet :
String stringurl=(String) req.getParameter("stringurl");
other code..
I want to know how to access these variables in Servlet. Thanks in Advance.
You need to write following code in servlet
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
} else {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<?> items = null;
String stringUrl = null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
Iterator<?> itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
if (item.isFormField()) {
System.out.println("Form Field");
String parameterName = item.getName();
if(parameterName.equals("stringurl")) {
stringUrl = item.getString();
}
} else {
// upload file logic here
}
}
}
likewise you need to get all other form fields using if else ladder.
Also you have to add commons-fileupload.jar, commons-logging.jar and commons-io.jar to project build path.
In my file upload servlet, I have 4 input tags as follows
<li>Left File : <input type="file" name="dataFile1" id="fileChooser1" /></li><li><br></li>
<li>Right File : <input type="file" name="dataFile2" id="fileChooser2" /></li><li><br></li>
<li>Config File :<input type="file" name="dataFile3" id="fileChooser3" /></li><li><br></li>
<li>final File : <input type="file" name="dataFile4" id="fileChooser4" /></li><li><br></li>
<li><button type="button" id="execute" onclick="ValidateFile()">Click to Upload files</button></li>
Now, in my upload.java I want to identify which file from which input is being uploaded.
I've tried using,
String file1 = request.getParameter("dataFile1").toString();
String file2 = request.getParameter("dataFile2").toString();
String file3 = request.getParameter("dataFile3").toString();
String file4 = request.getParameter("dataFile4").toString();
and
if (file1 != null)
{
//use apache commons and upload file
out.println("left file uploaded");
}
But this does not work.
How to identify from which input tag the file is being uploaded?
this is not the way you deal with file uploads
Maybe check this answer
The relevant part is that ServletFileUpload and FileItem from apache commons-fileupload is used, in turn FileItem has a method to get the field name.
Here is some sample code (from the answer linked above):
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = null;
try {
items = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
Iterator itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
if (item.isFormField()) {
} else {
try {
String itemName = item.getName();
String itemField = item.getFieldName();
if (itemField.equals("datafile1")) {
// do things for left side
} else if (itemField.equals("datafile2")) {
// do things for right side
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I need to upload a file by HTML but my form request has to include other parameters and values, for this i made the following:
I have the following html form:
<form action="CustomerAccountingServlet" method="post" name="payment_list_form" enctype="multipart/form-data">
<input type="hidden" name="action" value="save_payment" />
<input type="hidden" name="customer_id" value="123"/>
<input type="hidden" name="payment_id" value="444" />
<input type="file" name="invoice_file" />
<input type="submit" value="upload" />
</form
I use the following java code to get the file:
public static InputStream uploadFile(HttpServletRequest request, String fileFieldName) {
int maxFileSize = 5000 * 1024;
int maxMemSize = 5000 * 1024;
ServletContext context = request.getServletContext();
String filePath = context.getInitParameter("file-upload");
// Verify the content type
String contentType = request.getContentType();
if ((contentType.indexOf("multipart/form-data") >= 0)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File(filePath));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax(maxFileSize);
upload.setHeaderEncoding("utf-8");
try {
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
while (i.hasNext()) {
FileItem fi = (FileItem) i.next();
if (!fi.isFormField()) {
if(fi.getFieldName().equals(fileFieldName)){
return fi.getInputStream();
}
}
}
} catch (Exception ex) {
System.out.println(ex);
}
} else {
System.out.println("No file was found");
}
return null;
}
The problem that i get null when i do in the servlet the following:
request.getParameter("action");
request.getParameter("customer_id");
request.getParameter("payment_id");
Anyone can help please?
Thanks!
You cannot reference request parameters for multipart/form-data request in the conventional way. All the parameters are encoded in the multipart data, along with the uploaded file. See for example this blog post for an extended example of how this should be handled.
This question already has answers here:
How can I upload files to a server using JSP/Servlet?
(14 answers)
Closed 3 years ago.
Note:
Before reading this question and its answer, please check your input element has name attribute.
I am trying to upload file using servlet. Eclipse console shows no errors. But the file is not getting uploaded. For me, it seems everything is fine. But I am making mistake somewhere.
In console I get just
Inside Servlet //Printed by code
Items: [] // Printed by Cdoe
Html Code:
<form action="ImageUploadServlet" method="post" enctype="multipart/form-data">
<table>
<tr>
<td><label>Select Image: </label></td>
<td><input type="file" id="sourceImage" /></td>
<tr>
<td colspan="3">
<input type="submit" value="Upload"/><span id="result"></span>
</td>
</tr>
</table>
</form>
Servlet Code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
System.out.println("Inside Servlet");
if(!isMultiPart){
System.out.println("Form type is not multipart/form-data");
System.out.println("File Not Uploaded");
}
else
{
FileItemFactory dfit = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(dfit);
List aList = null;
try {
aList = sfu.parseRequest(request);
System.out.println("Items: "+aList);
}
catch (FileUploadException fue)
{
fue.printStackTrace();
}
Iterator itr = aList.iterator();
while(itr.hasNext())
{
FileItem fi = (FileItem) itr.next();
if(fi.isFormField())
{
System.out.println("File Name: "+fi.getFieldName());
System.out.println("File Size: "+fi.getSize());
try
{
File f = new File("D:/MyUploads/", fi.getName());
fi.write(f);
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
System.out.println("It's Not Form Item;");
}
}
}
}
}
Any suggestions would be appreciated.
Thanks!
There are two problems:
First, you need to give the field a name. It becomes then the request parameter name.
<input type="file" id="sourceImage" name="sourceImage" />
Second, you need to handle the file uploads in the else case of FileItem#isFormField() as per the commons fileupload guide. Your code is currently ignoring them and doing only a sysout.
if (item.isFormField()) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldname = item.getFieldName();
String fieldvalue = item.getString();
// ... (do your regular form field processing job here)
} else {
// Process form file field (input type="file").
String fieldname = item.getFieldName();
String filename = FilenameUtils.getName(item.getName());
// ... (do your uploaded file job here)
File file = new File("D:/MyUploads/", filename);
item.write(file);
}
Note that you need to use FilenameUtils#getName() to extract the file name, because MSIE browser incorrectly sends the full client side file path along the file name. See also Commons FileUpload FAQ.
You also need to keep in mind that this approach will overwrite any previously uploaded file with the same name. You may want to add an autogenerated suffix to the filename.
See also:
How to upload files in JSP/Servlet?
Maybe this will help:
http://www.theserverside.com/news/1365153/HttpClient-and-FileUpload