Error in ServletFileUpload#parseRequest(request) with tomcat 10 - servlets

Working on a simple file upload program. I had to use jakarta.servlet.* classes as I am using Tomcat v10. I am getting compile time error on parseRequest(request) line.
Code :
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
ServletFileUpload sf = new ServletFileUpload(new DiskFileItemFactory());
try {
List<FileItem> multifiles = sf.parseRequest(request);
for(FileItem i : multifiles) {
i.write(new File("C:/Users/Luffy/Documents/FileUploadDemo/"+i.getName()));
}
response.getWriter().print("The file is uploaded");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.getWriter().print("The file is uploaded");
}
The error is as below:
The method parseRequest(javax.servlet.http.HttpServletRequest) in the type ServletFileUpload is not applicable for the arguments (jakarta.servlet.http.HttpServletRequest)
I searched a lot on google but couldn't find a solution.
Please suggest a workaround or possible solution. Thanks in advance.
This is my first post in Stack overflow. So ignore my mistakes if any :)

You are trying to use the ServletFileUpload class from commons-fileupload, which doesn't work with a jakarta.servlet.http.HttpServletRequest. The library must be adapted to work with Servlet 5.0 classes.
Fortunately since Servlet 3.0 (Tomcat 8.0) multipart/form-data requests can be parsed by the servlet. You just need to:
Add a #MultipartConfig annotation to your servlet,
Use HttpServletRequest#getParts():
try {
final Collection<Part> parts = request.getParts();
for (final Part part : parts) {
part.write("C:/Users/Luffy/Documents/FileUploadDemo/"+part.getSubmittedFileName());
}
response.getWriter().print("The file has been uploaded successfully.");
} catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Upload failed.");
}

Related

How can I accept multiple multipart files in my Spring MVC REST controller

I have a Spring MVC REST controller that accepts a multipart file, as follows:
#Consumes(MediaType.MULTIPART_FORM_DATA)
#RequestMapping(value = "/save-comment", method = RequestMethod.POST)
public String addComment(#FormDataParam("jsonData") String jsonData, #FormDataParam("file") MultipartFile file, ModelMap model)
{
//My Logic to save file and data
}
I use Jersey REST client in my application. The above code works fine for me. Now I am trying to POST multiple files to my REST controller.
I tried to change #FormDataParam("file") MultipartFile file to #FormDataParam("file") MultipartFile[] file but it is not working for me. How can I pass multiple files at a time to a REST controller?
The exception I get is: nested exception is
org.springframework.beans.BeanInstantiationException: Failed to instantiate [[Lorg.springframework.web.multipart.MultipartFile;]: No default constructor found; nested exception is java.lang.NoSuchMethodException: [Lorg.springframework.web.multipart.MultipartFile;.<init>()] with root cause
java.lang.NoSuchMethodException: [Lorg.springframework.web.multipart.MultipartFile;.<init>()
Multiple File Upload concept , we can handle by using MultipartFile Interface.
Package:
org.springframework.web.mutipart
public interface MutipartFile
MutipartFile is an interface, Commonly Client will send or upload a file , it will be sent to server as in the form of mutipart request.
We will catch that mutipart request by using MutipartFile Concept. This MutipartFile Interface have number of method , those methods are used to get information of that file and if you want to do any copy or moving of a file also we can perform by one of the method called transferTo(“destinationPath”) ;
for better understanding purpose just visit https://walkintoknow.blogspot.com/2018/05/multiple-files-upload-concept-handling.html
#RequestMapping(value="/multipleFilesUpload" , method=RequestMethod.POST,
consumes="multipart/form-data", produces="application/json")
public ResponseEntity<?> mutipleFileUpload(HttpServletRequest req,
#RequestParam(value="file" , required = false) MultipartFile[] files) throws IOException{
for (MultipartFile file : files) {
File f= new File(getPath()+createFolderInDesc("/appFiles /GSTC/mutipleUpload/"),file.getOriginalFilename());
try {
file.transferTo(f); //Transfer or Saving in local memory
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
if it helps please promote.
Just typecast normal http request to multipart request like below :
try {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) httpServletRequest;
List<MultipartFile> multipartFileList = multipartRequest
.getFiles("images");
if (null != multipartFileList && !multipartFileList.isEmpty()) {
for (MultipartFile file : multipartFileList) {
String fileName = file.getOriginalFilename().trim();
if (file.getBytes().length > 0) {
// logic goes gere
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}

Stop servlet forcefully

What should be done to manually stop Servlet as calling destroy doesn't help unless all threads exited from service.
Say, If I have n number of Servlets and I want to stop only one of them.
That behavior is very important when dealing with Servlets. Instances can be created after the multi-thread model and are thus not thread-safe.
The container does not allow a thread to invoke the service method after destroy has been called.
This gives you the means to close all resources that your Servlet is using (db, file, memory, etc).
#WebServlet
public class OncePerApplicationServlet extends HttpServlet {
private Connection connection;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if(req.getParameter("closeServlet").equals("true"))
this.destroy();
else
this.service(req, resp); // normal flow
}
// this method will never be called by the container after the destroy method has been invoked
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.
try {
connection = DriverManager.getConnection("someDbUrl");
Statement stm = connection.createStatement();
stm.execute("select * from someTable");
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void destroy() {
// the point is that when this method is called you should be able to
// clean up and close all resources, you can rest assured that there are no "loose"
// threads that need the connection-instance
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Here is a quote from the API-docs:
This interface defines methods to initialize a servlet, to service
requests, and to remove a servlet from the server. These are known as
life-cycle methods and are called in the following sequence:
The servlet is constructed, then initialized with the init method. Any
calls from clients to the service method are handled. The servlet is
taken out of service, then destroyed with the destroy method, then
garbage collected and finalized.
|
Link to the documentation
Good luck!

<error-page> tag in web.xml doesn't catch java.lang.Throwable Exceptions

I have a web-app developed with servlet & JSP. I configured my app to throw an IllegalArgumentException if I insert bad parameters.
Then I configured my web.xml file in this way:
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
When I rise a 404 error, then it works and calls error.jsp, but when I rise a java.lang.IllegalArgumentException, then it does not work and I've a blank page instead of error.jsp. Why?
The server is Glassfish, and logs show really IllegalArgumentException rised.
You should not catch and suppress it, but just let it go.
I.e. do not do:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (IllegalArgumentException e) {
e.printStackTrace(); // Or something else which totally suppresses the exception.
}
}
But rather just let it go:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doSomethingWhichMayThrowException();
}
Or, if you actually intented to catch it for logging or so (I'd rather use a filter for that, but ala), then rethrow it:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw e;
}
}
Or, if it's not an runtime exception, then rethrow it wrapped in ServletException, it will be automatically unwrapped by the container:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (NotARuntimeException e) {
throw new ServletException(e);
}
}
See also:
How does server prioritize which type of web.xml error page to use?
Submitting form to Servlet which interacts with database results in blank page
Another (simplified) approach is not to declare multiple handlers for various <error-code> and <exception-type> situations but rather have one, sort of catch-all sink, e.g.
<error-page>
<location>/error-page.jsp</location>
</error-page>
Inside your error-page.jsp you can determine the cause, be it a return status code or an exception as described here: https://www.tutorialspoint.com/servlets/servlets-exception-handling.htm These constants are a part of the standard Servlet 3.0 API.
For instance a primitive error-page.jsp response handler placed into the root of your webapp can look like this:
Server encountered a situation
Status code: <%=(Integer) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_STATUS_CODE)%>
<br>
Exception: <%=(Throwable) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_EXCEPTION)%>
For security reasons I wouldn't recommend sending the exact exception type to the client; this is just an example of how to handle different types of errors and response statuses inside a JSP handler; a servlet can be used instead of JSP.
One common catch-all handler vs one per status code is certainly dependent on the situation and requirements.
I have today the same issue. (JavaEE 7 and Glassfish 4.0)
The problem seems that the framework check it as String instead with the Class.
String based check (the hypothesis)
When a Exception is twrown, e.getClass() is compared with <exception-type> as string.
So you can't use inheritance.
Note that nested classes must be pointed as '$' instead '.' (same as getClass() method).
Class based check
The framework create an instance of the class, and <exception-type> text refer to it, and the class.isInstance() is used to check.
This will need reflection and policy file could break it.
I hope that this response solves future issues.

How pass HttpServletResponse to other Threads

I have a tomcat6 servlet that manages incoming HttpPosts this way:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (request.getParameter("cmd") != null) {
eventPool.addEvent(new CommandEvent(new String[] { request.getParameter("cmd"),
request.getParameter("json") }, response));
}
}
The request will now be processed. When this is done, I want to write the result to the requesting client this way:
protected void sendResponse(HttpServletResponse httpResponse, String content){
try {
httpResponse.getWriter().println(CMD + "#" + content);
httpResponse.getWriter().close();
} catch (IOException e) {
e.printStackTrace();
}
}
But it fails to flush and I get a NullPointerException because the HttpResponse was already closed.
How can I prevent the HttpResponse from flushing before I want it to?
You'll need to use Tomcat 7 (or any other container that supports Servlet 3.0 onwards) to use that style of programming. Look at the asynchronous request processing parts of the Servlet 3.0 specification.
Prior to Servlet 3.0, request/response processing is synchronous. i.e. you cannot 'park' a request/response pair and then handle them later in a different thread. Pretty much as soon as your doPost() method exits, Tomcat will recycle the request and response objects ready to use them to handle a new request.

Track completed downloads from glassfish

I want to be able to track completed downloads served by my glassfish server. I couldn't find a 100% correct solution using servlet life cycle listeners.
Does anyone have a better idea?
Put a try-catch on IOException while serving the file download. If it's thrown, then serving the file download has failed.
E.g. in a custom file servlet:
try {
response.getOutputStream().write(...);
// Success!
} catch (IOException e) {
// Fail!
throw e;
}
Or in a servlet filter which is mapped on the appropriate URL pattern matching file downloads:
try {
chain.doFilter(request, response);
// Success!
} catch (IOException e) {
// Fail!
throw e;
}

Resources