Uploading file with jetty and servlet - java

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.

Related

C# file upload to Java EE server

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().

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

No Class Def Found while using PDFParser in a servlet. but working in Java Application

I am trying to write a servlet that read a uploaded pdf file, and then read it from another servlet. I want to parse that pdf file and search a keyword in the parsed text.
First I did application like a normal java code then It worked fine. But when I did the same code as a servlet Its showing an unexpected error class definition not found error.
Here is the Error:
SEVERE: Servlet.service() for servlet [ex.sat.com.PDFTestServlet] in context with path [/ContentBasedFileRetrival] threw exception [Servlet execution threw an exception] with root cause
java.lang.ClassNotFoundException: org.apache.pdfbox.pdfparser.PDFParser
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
at ex.sat.com.PDFTestServlet.pdftoText(PDFTestServlet.java:67)
at ex.sat.com.PDFTestServlet.doPost(PDFTestServlet.java:48)
I added the pdf box jar file into library of my eclipse project. no compilation error.
But same code is working fine when I do the project as a java application.
here is my servlet:
package ex.sat.com;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
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;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;
#WebServlet("/PDFTestServlet")
public class PDFTestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String SAVE_DIR = "uploadFiles";
/**
* #see HttpServlet#HttpServlet()
*/
public PDFTestServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
ServletContext context = getServletContext();
PrintWriter writer = response.getWriter();
String appPath = request.getServletContext().getRealPath("");
String savePath = appPath + File.separator+"j2.pdf";
writer.println(savePath);
String pdf_text=pdftoText(savePath);
writer.println("SATYA");
writer.println(pdf_text);
}
static String pdftoText(String fileName) {
PDFParser parser;
String parsedText = null;;
PDFTextStripper pdfStripper = null;
PDDocument pdDoc = null;
COSDocument cosDoc = null;
File file = new File(fileName);
if (!file.isFile()) {
System.err.println("File " + fileName + " does not exist.");
return null;
}
try {
parser = new PDFParser(new FileInputStream(file));
} catch (IOException e) {
System.err.println("Unable to open PDF Parser. " + e.getMessage());
return null;
}
try {
parser.parse();
cosDoc = parser.getDocument();
pdfStripper = new PDFTextStripper();
pdDoc = new PDDocument(cosDoc);
pdfStripper.setStartPage(1);
pdfStripper.setEndPage(5);
parsedText = pdfStripper.getText(pdDoc);
} catch (Exception e) {
System.err
.println("An exception occured in parsing the PDF Document."
+ e.getMessage());
} finally {
try {
if (cosDoc != null)
cosDoc.close();
if (pdDoc != null)
pdDoc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return parsedText;
}
}
It seems to me your libraries are not being found by the servlet container, you can try putting the jar files on the libraries directory for your container and then restart it. (libraries don't get deployed with applications - normally).
Thank You guys. Just now fond the answer. and Problem Solved. I am doing the build path by adding external jars. Actually I has to add as a library. so in the build path I created a user library and added jar files to the user library, its working fine now.

getting HTTP Status 404 - 502.shtml The requested resource is not available.while uploading a file

I'm getting the above error while using servlet I've written. the war file is set on Tomcat ver 7.0.39 installed on cPanel. the servlet compiled and tested on local machine no problem. I've learnet that there is a problem that has something to do with the cPanel/PHP config. I tried to play with the cPanel configuration but no luck
I feel that it has nothing to do with the java code but I'll put the fileUploadServlet anyhow
EDIT: I was able to upload a very small-sized file so it has something to do with file size \ long procssing time
package servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
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 javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import convertor.TextAnalayzer;
import exception.ZoharException;
import beans.ParashaBean;
import beans.UserBean;
import jdbcHandler.JDBCZhoarHandler;
import util.ParashaName;
import util.XmlUrelParaser;
#WebServlet(urlPatterns = { "/upload" }, loadOnStartup = 1)
#MultipartConfig
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 8626646959046203428L;
private JDBCZhoarHandler appHandler = new JDBCZhoarHandler();
public static final String ERROR_PARAMETER = "error";
public static final String COMMAND_PARAMETER = "command";
public static final String USER_ATTRIBUTE = "user";
public static final String HANDLER_ATTRIBUTE = "handler";
#Override
public void init() throws ServletException {
super.init();
try {
getServletConfig().getServletContext().setAttribute("list",
appHandler.viewParashot());
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String command = request.getParameter(COMMAND_PARAMETER);
String nextPage = "/login.jsp";
if ("convert".equals(command)) {
nextPage = this.upload(request, response);
} else if ("login".equals(command)) {
nextPage = this.login(request, response);
} else {
}// do nothing!!
this.getServletConfig().getServletContext()
.getRequestDispatcher(nextPage).forward(request, response);
}
private String login(HttpServletRequest request,
HttpServletResponse response) {
String name = request.getParameter("userName");
String password = request.getParameter("password");
JDBCZhoarHandler handler = new JDBCZhoarHandler();
try {
UserBean user = handler.getUser(name, password);
HttpSession session = request.getSession(true);
session.setAttribute(HANDLER_ATTRIBUTE, handler);
session.setAttribute(USER_ATTRIBUTE, user.getId());
return "/uploadFile.jsp";
} catch (Exception e) {
request.setAttribute(ERROR_PARAMETER, e.getMessage());
return "/login.jsp";
}
}
private String upload(HttpServletRequest request,
HttpServletResponse response) {
// view artifacts
HttpSession session = request.getSession(false);
ParashaName parashaName = new ParashaName();
JDBCZhoarHandler handler = (JDBCZhoarHandler) session
.getAttribute(HANDLER_ATTRIBUTE);
List<ParashaBean> list = null;
try {
list = handler.viewParashot();
} catch (SQLException e1) {
request.setAttribute(ERROR_PARAMETER, e1.getMessage());
}
session.setAttribute("list", list);
// Processing file
if ("convert".equals(request.getParameter("command"))) {
OutputStream out = null;
InputStream filecontent = null;
try {
// Create path components to save the file
XmlUrelParaser xml = new XmlUrelParaser();
SimpleDateFormat format = new SimpleDateFormat(
"dd-MM-yy_HH-mm-ss");
final Part filePart = request.getPart("file");
if (filePart.getSize() == 0) {
throw new ZoharException("you must upload a file first");
}
final String fileName = xml.getUR("incomingFilesDir")
+ session.getAttribute(USER_ATTRIBUTE)
+ parashaName.convert(Integer.parseInt(request
.getParameter("parasha")))
+ format.format(new Date()) + ".docx";
out = new FileOutputStream(new File(fileName));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
TextAnalayzer ta = new TextAnalayzer();
Integer ID = (Integer)session.getAttribute("user");
ta.analayze(fileName,
Integer.parseInt(request.getParameter("parasha")),
Boolean.parseBoolean(request.getParameter("orginal")),
ID);
request.setAttribute(ERROR_PARAMETER, "Upload complete");
return "/uploadFile.jsp";
} catch (Exception e) {
request.setAttribute(ERROR_PARAMETER, e.getMessage());
} finally {
try {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
} catch (IOException e) {
request.setAttribute(ERROR_PARAMETER, e.getMessage());
}
}
}
return "/login.jsp";
}
}
This is a resault of memory lack. Better memory-managing code solved the problem.

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