C# file upload to Java EE server - java

My problem is, that after uploading the content of file is [object Object].
How can I upload a file properly?
Server:
package com.turbulence6th.servlets;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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 javax.servlet.http.Part;
#WebServlet("/saveFile")
#MultipartConfig
public class SaveFile extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String webAppPath = getServletContext().getRealPath("/");
Part file = request.getPart("file");
String filename = getFileName(file);
InputStream is = file.getInputStream();
String directoryPath = webAppPath + File.separator + "files";
File directory = new File(directoryPath);
if(!directory.exists()){
directory.mkdir();
}
String filePath = directoryPath + File.separator + filename;
FileOutputStream fos = new FileOutputStream(filePath);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
fos.write(bytes, 0, read);
}
fos.close();
}
private String getFileName(Part part) {
for (String content : part.getHeader("content-disposition").split(";")) {
if (content.trim().startsWith("filename")) {
return content.substring(
content.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
}
Client:
using (var wb = new WebClient())
{
wb.UploadFile("http://" + host + ":8080/saveFile", "POST", path);
}

I don't see any manipulations with response. Inside doPost you copy file content to the request. Is it what you want?
By the way - I don't see any reason to not use copy().

Related

Uploading file with jetty and servlet

I am writing a java application to upload a file from browser. I am using jetty 9.4.15 and java servlet. When I upload the file, I get the below error message.
java.lang.IllegalStateException: No multipart config for servlet
at org.eclipse.jetty.server.Request.getParts(Request.java:2342)
at org.eclipse.jetty.server.Request.getParts(Request.java:2330)
at org.eclipse.jetty.server.Request.getPart(Request.java:2318)
at com.RekognizeServlet.doPost(RekognizeServlet.java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:873)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:205)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:502)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:132)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:745)
Below is the code I have written
SimplestServer.java
package com;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
public class SimplestServer
{
public static void main(String[] args) throws Exception
{
Server server = new Server(8080);
ServletHandler handler = new ServletHandler();
server.setHandler(handler);
handler.addServletWithMapping(RekognizeServlet.class, "/tryAndRecognize");
server.start();
server.join();
}
}
RekognizeServlet.java
package com;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
#MultipartConfig
public class RekognizeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public RekognizeServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<!DOCTYPE html><html lang=\"en\"><head><title>File Upload</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"></head><body><form method=\"POST\" action=\"tryAndRecognize\" enctype=\"multipart/form-data\" >File:<input type=\"file\" name=\"file\" id=\"file\" /> <br/></br><input type=\"submit\" value=\"Upload\" name=\"upload\" id=\"upload\" /></form></body></html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// Create path components to save the file
final String path = "/path/";
final Part filePart = request.getPart("file");
final Collection<Part> fileParts = request.getParts();
final String fileName = getFileName(filePart);
OutputStream out = null;
InputStream filecontent = null;
final PrintWriter writer = response.getWriter();
try {
out = new FileOutputStream(new File(path + File.separator + fileName));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
System.out.println("File being uploaded to {1}");
} catch (FileNotFoundException fne) {
writer.println("You either did not specify a file to upload or are "
+ "trying to upload a file to a protected or nonexistent " + "location.");
writer.println("<br/> ERROR: " + fne.getMessage());
System.out.println("Problems during file upload");
fne.printStackTrace();
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
if (writer != null) {
writer.close();
}
}
}
private String getFileName(final Part part) {
final String partHeader = part.getHeader("content-disposition");
System.out.println("Part Header = " + partHeader);
for (String content : part.getHeader("content-disposition").split(";")) {
if (content.trim().startsWith("filename")) {
return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
}
I am not using Handler like many examples online. Can anyone help?
Below are the links I have seen (not all)
How to implement FileUpload in embedded Jetty?
https://github.com/eclipse/jetty.project/issues/240
Since you are using Embedded Jetty the bytecode scanning for annotations (such as #MultipartConfig) isn't enabled by default.
Enabling the bytecode scanning requires a lot of effort, it's actually easier to just specify in code what the annotations would actually do.
So, in your case, all you need to change is the initialization of your servlet.
Example:
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
ServletHolder uploadHolder = context.addServlet(RekognizeServlet.class,
"/tryAndRecognize");
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File locationDir = new File(tmpDir, "jetty-fileupload");
if (!locationDir.exists()) locationDir.mkdirs();
String location = locationDir.getAbsolutePath();
long maxFileSize = 1024 * 1024 * 50;
long maxRequestSize = -1L;
int fileSizeThreshold = 1024 * 1024;
MultipartConfigElement multipartConfig = new MultipartConfigElement(location,
maxFileSize, maxRequestSize, fileSizeThreshold);
uploadHolder.getRegistration().setMultipartConfig(multipartConfig);
server.setHandler(context);
server.start();
It's important to note that MultipartConfig needs at a location specified (as a bare minimum).
Also, MultipartConfig will not work without a ServletContext, which the ServletContextHandler gives you.

Upload a file to an HTTP Server Memory in Java without temporal files?

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...
}
}

dynamically generated zip downloading results corrupted files

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
}

Java Servlet: Pick files to download

I'm pretty new to Java Servlets/Apache Tomcat/etc but I was able to find some handy resources on how I can implement Download and Upload functionality.
When the user wants to upload a file, they click the button, and they are prompted to select a file. However, when they want to download a file, they only have the choice of just the one file (specified in the servlet).
So, my question is: Is there a way to list out the directory somehow that would let the user pick a particular file, and then download that file?
Below is my code if you need a point of reference:
NOTE: This code works, I just want to know how I can expand on it with the desired effect I want.
package testPackage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet
{
private static final String absFilePath = "/test/files/download/test.txt";
private static final String relFilePath = "/files/download/test.txt";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
//Quick switch to determine what type of path to user
boolean useAbsolute = false; //Defaults to relative
//Initialize a new File
File downloadFile = new File("");
//Check if we want to use the absolute file path
if(useAbsolute)
{
//Read the input file from the absolute path
downloadFile = new File(absFilePath);
}
//Otherwise, we are using relative
else
{
//Read the input file from the relative path
String relativePath = getServletContext().getRealPath(relFilePath);
downloadFile = new File(relativePath);
//System.out.println("Relative Path: " + relativePath);
}
//Open up the FileInputStream
FileInputStream inputStream = new FileInputStream(downloadFile);
//Obtain the Servlet Context
ServletContext context = getServletContext();
//Get the MIME type of the file
String mimeType = context.getMimeType(absFilePath);
//If we don't get a type, default to binary
if(mimeType == null)
{
//Set to binary type if the MIME mapping is not found
mimeType = "application/octet-stream";
}
//Just some logging
System.out.println("MIME Type: " + mimeType);
//Modify Servlet Response
response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
//Set the header key/value
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
//Obtain the response output stream
OutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead = -1;
//While there are bytes to write
while((bytesRead = inputStream.read(buffer)) != -1)
{
outputStream.write(buffer, 0, bytesRead);
}
//Close the streams
inputStream.close();
outputStream.close();
}
}

Servlet java, server side, send a string as a new txt file

I have a Java web app. The user is able to upload a file (via POST request), and then the servlet will execute some code on this file. The output of this code is a string.
How to return a file to the user, without create one on the server side? Is that possible?
yes,
you have to set content disposition header then write the stream to response.
Try to use that code
package com.hainasoft.web;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends javax.servlet.http.HttpServlet implements
javax.servlet.Servlet {
static final long serialVersionUID = 1L;
private static final int BUFSIZE = 4096;
private String filePath;
public void init() {
// the file data.xls is under web application folder
filePath = getServletContext().getRealPath("") + File.separator + "data.xls";
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
File file = new File(filePath);
int length = 0;
ServletOutputStream outStream = response.getOutputStream();
ServletContext context = getServletConfig().getServletContext();
String mimetype = context.getMimeType(filePath);
// sets response content type
if (mimetype == null) {
mimetype = "application/octet-stream";
}
response.setContentType(mimetype);
response.setContentLength((int)file.length());
String fileName = (new File(filePath)).getName();
// sets HTTP header
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
byte[] byteBuffer = new byte[BUFSIZE];
DataInputStream in = new DataInputStream(new FileInputStream(file));
// reads the file's bytes and writes them to the response stream
while ((in != null) && ((length = in.read(byteBuffer)) != -1))
{
outStream.write(byteBuffer,0,length);
}
in.close();
outStream.close();
}
}
it is important to set the myme type
mimetype = "application/octet-stream";
and with this you set a download dialog to the user
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
I have retrieved all that information from
http://www.java-forums.org/blogs/servlet/668-how-write-servlet-sends-file-user-download.html
so take a look in it for more accurate information.

Categories