I'm a beginner in Java, and I use the Apache's commons-fileupload and conmmons-io to upload large file.It took me 20 seconds to copy a file size of 40m using this code. Is this normal?I have found a lot of places without an answer,and I would be grateful for any help,Thanks.
This is an example of copying official code:
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.commons.io.FileUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet2 extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(req);
System.out.println("start....");
long startTime = System.currentTimeMillis();
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
} else {
String value = item.getName();
int start = value.lastIndexOf("\\");
String fileName = value.substring(start + 1);
System.out.println(fileName);
FileUtils.copyInputStreamToFile(stream, new File("C:/dest.exe"));
long endTime = System.currentTimeMillis();
System.out.println("total seconds:" + (endTime - startTime) / 1000);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}
Related
package Connectivity;
import java.io.File;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.RequestContext;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
#WebServlet("/upload")
#MultipartConfig
public class upload extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws
ServletException{
try { boolean isMultipart = ServletFileUpload.isMultipartContent(request);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (isMultipart)
{
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try
{
// Parse the request
List<FileItem> items = upload.parseRequest((RequestContext) request);
Iterator<FileItem> iterator = items.iterator();
while (iterator.hasNext())
{
FileItem item = (FileItem) iterator.next();
if (!item.isFormField())
{
String fileName = item.getName();
File uploadedFile = new File("C:\\Users\\Ragul prasath\\Desktop\\Register\\src\\main\\webapp\\uploaded\\"+fileName);
System.out.println(uploadedFile.getAbsolutePath());
if(fileName!="")
item.write(uploadedFile);
else
out.println("file not found");
out.println("File Uploaded Successfully....");
}
else
{
}
}
}
catch (Exception e)
{
out.println(e);
}
}
else
{
out.println("Not Multipart");
}}
catch(Exception f) {
System.out.println(f);
}
}}
This is my code.i get the error
java.lang.ClassCastException: class
org.apache.catalina.connector.RequestFacade cannot be cast to class
org.apache.tomcat.util.http.fileupload.RequestContext
(org.apache.catalina.connector.RequestFacade and
org.apache.tomcat.util.http.fileupload.RequestContext are in unnamed
module of loader java.net.URLClassLoader #66d2e7d9)
How can i cast this request to request context
How can I upload file directly a to HTTP server memory without using a temporal file in Java?
I'm currently using Struts 2 and apache ServletFileUpload on tomcat and I haven't found a way to accomplish this.
In apache the class FileUploadBase parseRequest(RequestContext ctx)... is creating the temporary file
public List<FileItem> parseRequest(RequestContext ctx)
...
Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
Based on this doc here I wrote the following servlet to upload to a byte array without creating a temporal file.
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;
#WebServlet("/upload")
public class UploadByteArrayServlet extends HttpServlet {
private static final long serialVersionUID = 1123445L;
private static final int MAX_FILE_SIZE = 1024 * 1024 * 1; // 1MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 1; // 1MB
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
byte[] bytes = "".getBytes();
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
ServletFileUpload upload = new ServletFileUpload();
upload.setFileSizeMax(MAX_FILE_SIZE);
upload.setSizeMax(MAX_REQUEST_SIZE);
try {
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
System.out.println("Form field " + name + " with value "
+ Streams.asString(stream) + " detected.");
} else {
System.out.println("File field " + name + " with file name "
+ item.getName() + " detected.");
//loads only the first file
if(bytes.length==0)
bytes = IOUtils.toByteArray(item.openStream());
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
} else {
response.getWriter().print("is not a multipart request");
response.setStatus(200);
}
response.getWriter().print("bytes uploaded in file" + bytes.length);
//TODO store in session etc...
}
}
So I have an image in an ImageView on Android. I convert the bitmap to a PNG file and encode it into a Base64 string. I then post this string as a parameter in the body of the POST request, along with a few other details.
private void uploadImage() {
img.buildDrawingCache();
Bitmap bmp = img.getDrawingCache();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 90, stream);
byteArray = Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT);
StringRequest req = new StringRequest(Request.Method.POST, url+"/AddFoto", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError response) {
}
}){
#Override
protected Map<String, String> getParams(){
Map <String, String> params = new HashMap<String, String>();
Log.d(ProfileFragment.class.getSimpleName(), params.toString());
params.put("tussenstopID",tussenstopID.toString());
params.put("description", description);
params.put("image", byteArray);
Log.d("image byte array", byteArray);
return params;
}
};
AppController.getInstance().addToRequestQueue(req);
}
So then my servlet receives this file and converts it into a byte array so I can upload it to the database.
package Servlets;
import Core.Foto;
import Core.Tussenstop;
import DAO.FotoFacade;
import DAO.TussenstopFacade;
import com.sun.xml.messaging.saaj.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* #author Lukas
*/
public class AddFoto extends HttpServlet {
#EJB
FotoFacade fotoFacade;
#EJB
TussenstopFacade tussenstopFacade;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
Long tussenstopID = Long.parseLong(request.getParameter("tussenstopID"));
String description = request.getParameter("description");
String imageString64 = request.getParameter("image");
System.out.println(imageString64);
String imageString = Base64.base64Decode(imageString64);
byte[] image = imageString.getBytes();
upload(image, description, tussenstopID);
}
}
public void upload(byte[] imageString, String descr, Long tussenstopID) {
try {
InputStream fin2 = new ByteArrayInputStream(imageString);
//InputStream fin2 = new ByteArrayInputStream( imageString.getBytes() );
Class.forName("com.mysql.jdbc.Driver");
// Connect to the database
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/Project_1?user=root&password=root");
// Set autocommit to false to manage it by hand
connection.setAutoCommit(false);
PreparedStatement pre = connection.prepareStatement("INSERT INTO foto (beschrijving,image,tussenstop_id) values(?,?,?)");
pre.setString(1, descr);
pre.setBinaryStream(2, fin2);
Long tempID=tussenstopID;
pre.setLong(3, tempID);
pre.executeUpdate();
System.out.println("Inserting Successfully!");
connection.commit();
pre.close();
} catch (Exception e) {
System.out.println("Exception-File Upload." + e.getMessage());
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
public String getServletInfo() {
return "Short description";
}
}
Everything goes fine, the image is added to the database along with the other parameters I sent. However, the image is not readable. When I open the image's "text", I can clearly see that it says PNG at the start (Actually there's 1 character in front). The bytes look alright as well: http://i.stack.imgur.com/L1vaJ.jpg
I really don't know what's wrong this code. Other images (uploaded from a website) work just fine. Can anyone help me?
I fixed my issue. The base64 decoding was not working really well.
I imported sun.misc.BASE64Decoder and converted it like this:
String imageString64 = request.getParameter("image");
BASE64Decoder decoder = new BASE64Decoder();
byte[] image = decoder.decodeBuffer(imageString64);
what i m try to achieve is, creating dynamically zip file and write it to ServletOutput stream. I can manage to download a zip file through my code. But downloaded zip content is unusable.
Thanks for your answer.
package mainpackage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.coyote.Response;
public class DownloadZipServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DownloadZipServlet() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/zip");
response.setHeader("Content-Disposition",
"attachment;filename=download.zip");
ServletOutputStream sos;
ZipOutputStream zos;
InputStream fis;
List<File> filesToDownload = new ArrayList<File>();
filesToDownload.add(new File(getDirectory(), "download.png"));
filesToDownload.add(new File(getDirectory(), "download2.png"));
sos = response.getOutputStream();
zos = new ZipOutputStream(sos);
for (File fileToSend : filesToDownload) {
ZipEntry ze = new ZipEntry(fileToSend.getName());
zos.putNextEntry(ze);
fis = new FileInputStream(fileToSend);
byte[] buffer = new byte[4096];
int readBytesCount = 0;
while ((readBytesCount = fis.read(buffer)) >= 0) {
sos.write(buffer, 0, readBytesCount);
}
fis.close();
sos.flush();
zos.flush();
zos.closeEntry();
}
zos.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
public String getDirectory() {
Properties prop;
String home;
String fileSeparator;
String directoryName;
prop = System.getProperties();
home = prop.getProperty("user.dir").toString();
fileSeparator = prop.getProperty("file.separator").toString();
directoryName = "FileToDownload";
return home + fileSeparator + directoryName;
}
}
You're writing the file contents to your ServletOutputStream instead of yourZipOutputStream.
sos = response.getOutputStream();
zos = new ZipOutputStream(sos);
// ...
while ((readBytesCount = fis.read(buffer)) >= 0) {
sos.write(buffer, 0, readBytesCount); // <-- should be zos instead of sos
}
I have a problem with the servlet that I'm making. You have to log into a system and you also need to log out, I use a file register the users. Login works fine, it reads the user from the file, but for some reason logout doesn't. I get an error when I press the logout-button:
Here is the code for the class LogoutServlet
package nl.hu.sp.lesson1.dynamicexample;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
RequestDispatcher rd = null;
try {
String data = null;
File file = new File(
"C:/apache-tomcat-8.0.5/webapps/LoginAssignment/loggedusers.txt");
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while ((data = br.readLine()) != null) {
String[] de = data.split(" ");
if (de[0].equals("vimal")) {
data.trim();
rd = req.getRequestDispatcher("testpage.html");
}
}
rd.forward(req, resp);
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You are reading a text file and searching for "vimal", if it is found you are initializing rd; if it is not found rd is null. It cannot find "vimal" in text file and rd becomes null so it throws null pointer exception.
Add null check
if (rd != null) {
rd.forward(req, resp);
}