I would like to upload a zip file in Angular, and send the zip file to the backend (java/micronaut) and extract it there. There is already some implementation done, the backend receives the zip file eg. "File.zip", however it can't find the file
Is it necessary to add the complete Path of the file? if yes, how I can get it? from the Frontend or Backend?
Angular:
<div style="width: 0px; height: 0px; overflow: hidden;">
<input #fileUploadInput type="file" style="visibility: hidden" accept=".zip"
(change)="uploadFile($event.target.files)">
uploadFile(files: FileList) {
if (!files || files.length !== 1) {
return;
}
this.orderService.importFile(this.order.id, files[0], this.appComponent, success => {
if (success) {
this.loadOrder(this.order.id);
}
});
}
Backend (Micronaut) Controller
#Post("/order/import/file/{orderId}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public HttpResponse importOrderFile(
CompletedFileUpload fileUpload,
#Parameter(String orderId) {
try {
service.orderService.importOrder(orderId, fileUpload.getInputStream(), fileUpload.getFilename());
return HttpResponse.ok();
}
catch (IOException e) {
return HttpResponse.badRequest("Bad input");
}
}
Service
public void importOrder(String orderId, InputStream in, String fileName) throws IOException {
Set<String> extractedFiles = getUncompressedFiles(fileName);
Iterator<String> itr = extractedFiles.iterator();
while(itr.hasNext()){
//...
}
}
public Set<String> getUncompressedFiles(String fileZip) throws IOException {
Set<String> files = new HashSet<>();
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(fileZip));
ZipEntry zipEntry = zipIn.getNextEntry();
while (zipEntry != null) {
String zipEntryName = zipEntry.getName();
String fileName = zipEntryName.substring(zipEntryName.indexOf("order-nr"));
files.add(fileName);
zipIn.closeEntry();
zipEntry = zipIn.getNextEntry();
}
zipIn.close();
return files;
}
You are making the assumption the file is on the filesystem and that its name is the name of the stored file.
Depending on your configuration, the file may only exist in memory. For cases when the file is stored on the file system, its name does not match what is returned from fileUpload.getFilename(). That method returns what the client reported the name of the file is.
Your getUncompressedFiles(String fileZip) method should instead pass the input stream of the file and it should be used instead of new FileInputStream(fileZip)
Related
This question already has answers here:
Can't Access Resources In Executable Jar
(4 answers)
Closed 3 years ago.
I'm running spring boot application with a jar file.
This application sends a mail alond with attachment. The attachment is the part of the jar file. I'm using the code below to fetch the attachment. I have referred this link Classpath resource not found when running as jar
public boolean sendEmail(String content, String subject, String from, String to, String cc, boolean isAttach, List<String> attachFiles, Session session) {
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from, "XXX"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
if(cc!=null && !cc.equals("")) {
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
}
message.setSubject(subject);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(content, "text/html; charset=utf8");
// creates multipart
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
if (isAttach) {
// adds attachments
if (!attachFiles.isEmpty()) {
for (String filePath : attachFiles) {
try {
ClassPathResource classPathResource = new ClassPathResource("Brochure.pdf");
InputStream inputStream = classPathResource.getInputStream();
MimeBodyPart attachPart = new MimeBodyPart();
attachPart.attachFile(IOUtils.toString(inputStream));
multipart.addBodyPart(attachPart);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
// sets the multipart as email's content
message.setContent(multipart);
Transport.send(message);
System.out.println("sent email for " + to);
return true;
} catch (MessagingException | UnsupportedEncodingException e) {
System.out.println("email sending failed for " + to);
e.printStackTrace();
// throw new RuntimeException(e);
return false;
}
}
I'm using the getInputStream() function itself in order to search for the file inside the jar file. But I'm getting the following error:
javax.mail.MessagingException: IOException while sending message;
nested exception is:
java.io.FileNotFoundException: Invalid file path
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1365)
at javax.mail.Transport.send0(Transport.java:255)
at javax.mail.Transport.send(Transport.java:124)
at com.inversation.app.integration.service.mail.clients.GenericMailClient.sendEmail(GenericMailClient.java:95)
at com.inversation.app.jobs.CronJob.executeInternal(CronJob.java:62)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.io.FileNotFoundException: Invalid file path
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:152)
at javax.activation.FileDataSource.getInputStream(FileDataSource.java:110)
at javax.activation.DataHandler.writeTo(DataHandler.java:318)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1694)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:996)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:561)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:84)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:901)
at javax.activation.DataHandler.writeTo(DataHandler.java:330)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1694)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1913)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1315)
... 7 more
Before podting this question here i have done research my myside, but still not able to solve the problem. Any help would be appreciated.
I'm able to solve the issue by using below code. Hope it helps others. Refer this issue - Similar issue
attachPart.setDataHandler(new DataHandler(new ByteArrayDataSource(this.getClass().getResourceAsStream("/"+filePath),"application/pdf")));
(Caution: You are hard-coding "Brochure.pdf", and ignoring filePath entirely in your loop. I shall assume you meant to attach each value of filePath.)
As you can see in the documentation for the attachFile method, the String argument must be a valid file name.
Converting the bytes in an InputStream to a String certainly will not result in a file name.
A resource in a .jar is not a file. It’s part of a .jar file, not a separate file.
You will need to set the MimeBodyPart’s content and file name manually, instead of using attachFile:
URL content = GenericMailClient.class.getResource("/" + filePath);
attachPart.setDataHandler(new DataHandler(content));
URI uri = content.toURI();
String path = uri.getPath();
String fileName = path.substring(path.lastIndexOf('/') + 1);
attachPart.setDisposition(Part.ATTACHMENT);
attachPath.setFileName(fileName);
(Do not attempt to use the getFile() method of URL. The getFile() method will not return a valid file name, both because the URL won’t be a file: URL, and because characters which are not allowed to appear directly in URLs (like spaces) will be percent-escaped. On the other hand, the URI class properly parses URI components and returns their unescaped forms.)
I Guess, You need to change the way of reading file using springs ResourceUtils from class path in spring boot application as:
File file = ResourceUtils.getFile("classpath:Brochure.pdf");
InputStream in = new FileInputStream(file);
I am sure, it will work for you
I have used this below code in my projects. Basically, what I do is scan the whole classpath for the file intended if I don't have the exact path. This is to help me in making sure that I don't need to have the file in a specific path.
This is because I encountered the same error as you when I use this line.
getClass().getClassLoader().getResource("Brochure.pdf")
So, I created two functions that takes a filename, and the classpaths included in the jar and recursively searched for the file.
private static File findConfigFile(String paths, String configFilename) {
for (String p : paths.split(File.pathSeparator)) {
File result = findConfigFile(new File(p), configFilename);
if (result != null) {
return result;
}
}
return null;
}
private static File findConfigFile(File path, String configFilename) {
if (path.isDirectory()) {
String[] subPaths = path.list();
if (subPaths == null) {
return null;
}
for (String sp : subPaths) {
File subPath = new File(path.getAbsoluteFile() + "/" + sp);
File result = findConfigFile(subPath, configFilename);
if (result != null && result.getName().equalsIgnoreCase(configFilename)) {
return result;
}
}
return null;
} else {
File file = path;
if (file.getName().equalsIgnoreCase(configFilename)) {
return file;
}
return null;
}
}
Here is an example of my code in action:
import java.io.File;
public class FindResourcesRecursive {
public File findConfigFile(String paths, String configFilename) {
for (String p : paths.split(File.pathSeparator)) {
File result = findConfigFile(new File(p), configFilename);
if (result != null) {
return result;
}
}
return null;
}
private File findConfigFile(File path, String configFilename) {
if (path.isDirectory()) {
String[] subPaths = path.list();
if (subPaths == null) {
return null;
}
for (String sp : subPaths) {
File subPath = new File(path.getAbsoluteFile() + "/" + sp);
File result = findConfigFile(subPath, configFilename);
if (result != null && result.getName().equalsIgnoreCase(configFilename)) {
return result;
}
}
return null;
} else {
File file = path;
if (file.getName().equalsIgnoreCase(configFilename)) {
return file;
}
return null;
}
}
}
Here I have a test case that is coupled with a file "test.txt" in my test/resources folder. The content of said file is:
A sample file
Now, here is my test case:
import org.junit.Test;
import java.io.*;
import static org.junit.Assert.fail;
public class FindResourcesRecursiveTest {
#Test
public void testFindFile() {
// Here in the test resources I have a file "test.txt"
// Inside it is a string "A sample file"
// My Unit Test will use the class FindResourcesRecursive to find the file and print out the results.
File testFile = new FindResourcesRecursive().findConfigFile(
System.getProperty("java.class.path"),
"test.txt"
);
try (FileInputStream is = new FileInputStream(testFile)) {
int i;
while ((i = is.read()) != -1) {
System.out.print((char) i);
}
System.out.println();
} catch (IOException e) {
fail();
}
}
}
Now, if you run this test, it will print out "A sample file" and the test will be green.
Now, is this okay with you?
I'm creating a web app using Java servlets and JSPs and I want to create an upload form in JSP for my clients to be able to upload and download stuff. I'm using Cloud Storage and my default bucket to upload stuff.
I followed Google's tutorial on Reading and Writing to Google Cloud Storage.
This is my Servlet:
public class Create extends HttpServlet {
public static final boolean SERVE_USING_BLOBSTORE_API = false;
private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
.initialRetryDelayMillis(10)
.retryMaxAttempts(10)
.totalRetryPeriodMillis(15000)
.build());
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFilename fileName = getFileName(req);
if (SERVE_USING_BLOBSTORE_API) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey = blobstoreService.createGsBlobKey(
"/gs/" + fileName.getBucketName() + "/" + fileName.getObjectName());
blobstoreService.serve(blobKey, resp);
} else {
GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, BUFFER_SIZE);
copy(Channels.newInputStream(readChannel), resp.getOutputStream());
}
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = getFileName(req);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
copy(req.getInputStream(), Channels.newOutputStream(outputChannel));
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}
}
I can upload and download successfully, but only text and not real files like images, pdfs, etc., which is my problem.
This tutorial is for reading and writing text but i want to upload real files. As you can see from my jsp the enctype is "text/plain":
<form action="/index.html" enctype="text/plain" method="get" name="putFile" id="putFile">
<div>
Bucket: <input type="text" name="bucket" />
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<textarea name="content" id="content" rows="3" cols="60"></textarea>
<br />
<input type="submit" onclick='uploadFile(this)' value="Upload Content" />
</div>
</form>
I tried to change it to "multipart/form-data" and put a
<input name="content" id="content" type="file">
but this does not upload the real file only the fake path of the file.
And I want to know how to upload real files, any help would be appreciated.
Here is one example on how to upload blobs to Cloud Storage:
First you initialize the storage with these lines:
private static Storage storage = null;
// [START init]
static {
storage = StorageOptions.getDefaultInstance().getService();
}
// [END init]
You may change the code to accept different file extensions according to your needs on the getImageUrl method in the line String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
/**
* Extracts the file payload from an HttpServletRequest, checks that the file extension
* is supported and uploads the file to Google Cloud Storage.
*/
public String getImageUrl(HttpServletRequest req, HttpServletResponse resp,
final String bucket) throws IOException, ServletException {
Part filePart = req.getPart("file");
final String fileName = filePart.getSubmittedFileName();
String imageUrl = req.getParameter("imageUrl");
// Check extension of file
if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
final String extension = fileName.substring(fileName.lastIndexOf('.') + 1);
String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
for (String s : allowedExt) {
if (extension.equals(s)) {
return this.uploadFile(filePart, bucket);
}
}
throw new ServletException("file must be an image");
}
return imageUrl;
}
Here a timestamp is appended in the filename which can be a good idea if you want to make the filename unique.
/**
* Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME
* environment variable, appending a timestamp to end of the uploaded filename.
*/
#SuppressWarnings("deprecation")
public String uploadFile(Part filePart, final String bucketName) throws IOException {
DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
DateTime dt = DateTime.now(DateTimeZone.UTC);
String dtString = dt.toString(dtf);
final String fileName = filePart.getSubmittedFileName() + dtString;
// the inputstream is closed by default, so we don't need to close it here
BlobInfo blobInfo =
storage.create(
BlobInfo
.newBuilder(bucketName, fileName)
// Modify access list to allow all users with link to read file
.setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
.build(),
filePart.getInputStream());
// return the public download link
return blobInfo.getMediaLink();
}
In this documentation you'll find more details: https://cloud.google.com/java/getting-started/using-cloud-storage#uploading_blobs_to_cloud_storage
The complete code for this example is in github: https://github.com/GoogleCloudPlatform/getting-started-java/blob/master/bookshelf/3-binary-data/src/main/java/com/example/getstarted/util/CloudStorageHelper.java
I found a solution.
This is my JSP:
<form action="/create" enctype="multipart/form-data" method="post" name="putFile" id="putFile">
<div>
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<input type="submit" value="Upload Content" />
</div>
</form>
When i submit the form, it goes into this Servlet:
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Part filePart = req.getPart("content"); /*Get file from jsp*/
/*Get file name of file from jsp*/
String name = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = new GcsFilename(BUCKET_NAME, name);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
/*Pass the file to copy function, wich uploads the file to cloud*/
copy(filePart.getInputStream(), Channels.newOutputStream(outputChannel));
req.getRequestDispatcher("download.jsp").forward(req, resp);
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}
This question already has answers here:
Recommended way to save uploaded files in a servlet application
(2 answers)
Closed 6 years ago.
<body>
<form method="post" action="DemoServlet" enctype="multipart/form-data" name="form1">
<input type="file" name="file" />
Image_Name:<input type="text" name="file"/>
<input type="submit" value="Go"/>
</form>
</body>
this is my index.jsp page.
This Servlet is DemoServlet when user click on submit button it will go here.while in jsp page suppose Image_Name given by user is IPL and actual name of image is funny.jpg then while saving the image it should store as IPL.png,here i'm able to upload image correctly with funny.jpg,but i need to save image as given name in text field of index.jsp page
public class DemoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Date date = new Date();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
if (isMultiPart) {
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator itr = upload.getItemIterator(request);
while (itr.hasNext()) {
FileItemStream item = itr.next();
if (item.isFormField()) {
String fieldname = item.getFieldName();
InputStream is = item.openStream();
byte[] b = new byte[is.available()];
is.read(b);
String value = new String(b);
response.getWriter().println(fieldname + ":" + value + "</br>");
} else {
String TempPath = getServletContext().getRealPath("");
String path = TempPath.substring(0, TempPath.indexOf("build"));
if (FileUpload.processFile(path, item)) {
out.println("File Uploaded on:" + date + "<br>");
response.getWriter().println("Image Upload Successfully");
} else {
response.getWriter().println("Failed.....Try again");
}
}
}
} catch (FileUploadException fue) {
fue.printStackTrace();
}
}
}
}
and this is java class
public class FileUpload {
public static boolean processFile(String path, FileItemStream item) {
try {
File f = new File(path + File.separator + "web/images");
if (!f.exists()) {
f.mkdir();
}
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName());
FileOutputStream fos = new FileOutputStream(savedFile);
InputStream is = item.openStream();
int x = 0;
byte[] b = new byte[1024];
while ((x = is.read(b)) != -1) {
fos.write(b, 0, x);
}
fos.flush();
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
Could anybody guide me how to change this dynamically.Thanks in advance.
I don't know how Servlet's and the like work however i can give you a rundown of what you need to do.
In DemoServlet you need to take in the input of the Image_Name field and make that one of your parameters of FileUpload
public static boolean processFile(String path, FileItemStream item, String fileName){
//Method Code
}
Because currently your processFile method is taking the name of the file from your FileItemStream. You need to change it from that to your actual fileName
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName());
to
File savedFile = new File(f.getAbsolutePath() + File.separator + fileName + ".png");
You can change the name of image in your java class code.
public class FileUpload {
public static boolean processFile(String path, FileItemStream item , String name) {
try {
File f = new File(path + File.separator + "web/images");
if (!f.exists()) {
f.mkdir();
}
File savedFile = new File(f.getAbsolutePath() + File.separator + item.getName()); // instead of item.getName() you can give your name.
FileOutputStream fos = new FileOutputStream(savedFile);
InputStream is = item.openStream();
int x = 0;
byte[] b = new byte[1024];
while ((x = is.read(b)) != -1) {
fos.write(b, 0, x);
}
fos.flush();
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
you will have to pass the file name in the method.
instead of item.getName() you can give your name.
List fileItems = upload.parseRequest(request);
Iterator i = fileItems.iterator();
System.out.println("In >>>>>>>>>>>>>>> :: "+fileItems);
while(i.hasNext()){
FileItem fi = (FileItem) i.next();
System.out.println("Val <<<<>>>>>>:: "+fi);
if(fi.isFormField()){
String fieldName = fi.getFieldName();
String val = fi.getString();
System.out.println(fieldName+" :: Val :: "+val);
}else{
String fileName = fi.getName();
String root = getServletContext().getRealPath("/");
File path = new File(root+"/uploads");
if (!path.exists()) {
boolean status = path.mkdir();
}
File uploadFile = new File(path+"/"+fileName);
fi.write(uploadFile);
}
In the code above you can change the file name at any time and it will automatically save with this name.
//How does not work in this way?Please tell me another way.
import java.io.File;
public class RenameFileExample {
public static void main(String[] args)
{
File oldfile =new File("oldfile.txt");
File newfile =new File("newfile.txt");
File file = new File("oldfilename.png");
file.renameTo(new File("newfilename.png"));
System.out.println("Rename To:"+file.getName());
if(oldfile.renameTo(newfile)){
System.out.println("Rename succesful");
}else{
System.out.println("Rename failed");
}
}
}
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 uploading an excel file from one jsp page. below is the code.
<form action="Upload.jsp" enctype="MULTIPART/FORM-DATA" method=post >
<input type="file" name="filename" />
<input type="submit" value="Upload" />
</form>
But how to get the excel file in the next page(Upload.jsp)?
I was using but getting error in the second line.
InputStream file = request.getInputStream();
POIFSFileSystem myFileSystem = new POIFSFileSystem(file );
Then how to get the excel file from the request?
You are getting a Multipart/form-data on the request from which you need to extract the Part containing your file bytes.
The simplest to do this is to use Apache Commons Fileupload
http://commons.apache.org/fileupload/
Create a FileUploader
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.;
import java.io.;
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;
}
}
Then use it when processing the request
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
{
String randomFileName = (new RandomGUID()).toString() + getFileExtension(filename);
File uploadFile = new File(uploadDir + File.separator + randomFileName);
item.write(uploadFile);
}
}
}
}
catch(FileSizeLimitExceededException e)
{
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
return data;
}
For your reference ... MultiPartForm data looks like
import java.util.Hashtable;
import java.util.ArrayList;
public class MultiPartFormData {
private ArrayList<Integer> fids;
private Hashtable<String, String> parameters;
public MultiPartFormData()
{
this.fids = new ArrayList<Integer>();
this.parameters = new Hashtable<String, String>();
}
public ArrayList<Integer> getFids() {
return fids;
}
public void setFids(ArrayList<Integer> fids) {
this.fids = fids;
}
public Hashtable<String, String> getParameters() {
return parameters;
}
public void setParameters(Hashtable<String, String> parameters) {
this.parameters = parameters;
}
}
Well guys, thanks for all the reply. But I have resolved the problem with below process.
Inside JSP:
<form action="/upload.do" enctype="MULTIPART/FORM-DATA" method=post >
<input type="file" name="file" id="file" size=25/>
<input type="submit" value="Upload" />
</form>
Created a form bean: inside that
private FormFile file;
public void setFile(FormFile file) {
this.file = file;
}
public FormFile getFile() {
return file;
}
In action class upload:
FileUploadForm uploadForm = (FileUploadForm) form;
FormFile file = uploadForm.getFile();
InputStream stream = file.getInputStream();
POIFSFileSystem fsFileSystem = new POIFSFileSystem(stream);
//
rest of code for reading the excel
//
Now its working fine.