Error on Part.getSubmittedFileName - servlets

I am uploading a file, and I use javax.servlet.http.Part in the Servlet. It seems to behave strangely, since part.getSubmittedFileName() is returning an error (it seems a POST http://localhost:8080/.... 500 (Internal Server Error) ) so I have to use the old JEE 6 method to obtain the name. What could be happening? I tried to capture the error with a try-catch but when the sentence is executed, it just leaves the Servlet method entirely without entering into the catch block.
#MultipartConfig
#WebServlet(name = "UploadServlet", urlPatterns = {"/uploadServlet"})
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part partFile = request.getPart("file");
....
try {
System.out.println("submName " + partFile.getSubmittedFileName()); // never prints
String fileName = partFile.getSubmittedFileName();
} catch (Exception e) {
System.out.println("EX: " + e); // never executes
}
....
}
}

Related

Can I write code after RequestDispatcher?

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//some code here
}
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//performTask(req, resp);
//some code here
}
private void insertRequestTemplate() {
HttpSession session = req.getSession();
responsePage = req.getParameter("ResponsePage");
ServletContext ctx = getServletConfig().getServletContext();
ctx.getRequestDispatcher(responsePage).forward(req,resp);
readMessage();
public void readMessage()
{
System.out.println("calling MessageTrigger_ABean");
MessageTrigger_ABean msg = new MessageTrigger_ABean();
msg.read();
}
msg.read() has the code to read messages from MQ. Inside insertRequestTemplate method, I am calling readMessage method after ctx.getRequestDispatcher(responsePage).forward(req,resp);is this the correct way of calling this?
But inside insertRequestTemplate method, the page is not getting forwarded to the next page untill readMessage() is executed because of which the page keeps on loading for a long time until message is read from MQ. Could you please help me on this.
Most examples I have seen of a servlet forwarding the request to another servlet have the dispatcher forward invocation at the end of the method. ie. there is no more code, other than closing braces at the end of the method.
I am guessing that the forwarding doesn't happen until the invoking method completes. So where you have your msg.read() will stop the insertRequestTemplate method from completing. This will more than likely be because the code inside msg.read is being performed synchronously. Leading to http timeouts on the http request.
How you solve this will depend on what you want to do with the messages you obtain from msg.read().

Multiple Asynchronous context in servlet not working

I'm trying to practice multiple asynchronous request chain in servlets and I'm bumping into a weird behavior. Not sure if it has anything to do with tomcat.
So here's the scenario. I have a simple J2EE maven web application.
I have two servlets and a filter. I have marked all of them with asyncSupported=true. When I click on a link in a JSP, the first servlet does indeed take the request and spawns a new worker thread using AsyncContext. The worker thread then writes something to the response, commits it (as I learned it's legal for asynchronous processing in servlets) and then dispatches the request to another servlet. It works fine till this point.
The second servlet is supposed to spawn a second worker thread and then the plan was to make the second worker thread call dispatch (As I was also trying to practice the parameter-less call to dispatch()) to go back to the Second servlet that called it. However, I get the below error when calling startAsync() on the second servlet
06-Apr-2018 19:04:48.128 WARNING [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina.startup.ContextConfig.validateSecurityRoles Security role name [authSupervisor] used in an <auth-constraint> without being defined in a <security-role>
06-Apr-2018 19:04:48.261 INFO [RMI TCP Connection(5)-127.0.0.1] com.kingshuk.listeners.MyServletContextListener.contextInitialized The servlet class com.kingshuk.servlets.MyAppDynamicServlet is now being registered
06-Apr-2018 19:05:09.025 WARNING [http-nio-8080-exec-8] org.apache.catalina.connector.Request.startAsync Unable to start async because the following classes in the processing chain do not support async []
java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations.
at org.apache.catalina.connector.Request.startAsync(Request.java:1636)
at org.apache.catalina.connector.Request.startAsync(Request.java:1628)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1043)
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:378)
at com.kingshuk.servlets.BiggestAsyncSecondServlet.doGet(BiggestAsyncSecondServlet.java:23)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.kingshuk.filters.AsyncRequestLoggingFilter.doFilter(AsyncRequestLoggingFilter.java:25)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:633)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:601)
at org.apache.catalina.core.AsyncContextImpl$AsyncRunnable.run(AsyncContextImpl.java:566)
at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:352)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:235)
at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:228)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Below are all the related files
The Filter
#WebFilter(filterName = "AsyncRequestLoggingFilter",
urlPatterns = {"/asyncServlet", "/biggestAsyncRequestTest", "/biggestAsyncRequestTest2"},
asyncSupported = true,
dispatcherTypes = {DispatcherType.ASYNC, DispatcherType.REQUEST})
public class AsyncRequestLoggingFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
System.out.println("<<AsyncRequestLoggingFilter>> Initializing the Filter");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws ServletException, IOException {
if (DispatcherType.ASYNC.equals(req.getDispatcherType())) {
System.out.println("<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter during the ASYNC dispatching");
} else {
System.out.println("<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter");
}
chain.doFilter(req, resp);
if (DispatcherType.ASYNC.equals(req.getDispatcherType())) {
System.out.println("<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call after the ASYNC dispatching");
} else {
System.out.println("<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call");
}
}
public void destroy() {
System.out.println("<<AsyncRequestLoggingFilter>> Destroying the Filter");
}
}
The First Servlet
#WebServlet(name = "BiggestAsyncFirstServlet",
urlPatterns = "/biggestAsyncRequestTest",
asyncSupported = true)
public class BiggestAsyncFirstServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(10000);
asyncContext.addListener(asyncContext.createListener(BiggestAsyncContextListener.class));
//asyncContext.start(new BiggestAsyncFirstWorkerThread());
/*
Step 5.Get the reference to the thread pool that was created in the context listener class
when the app was deployed
*/
ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext().getAttribute("executor");
/*
Step 6.Actually creating the worker thread
and kick starting the thread by calling the run method of the class implementing the runnable interface.
*/
executor.execute(new BiggestAsyncFirstWorkerThread(asyncContext));
System.out.println("Hi I'm the servlet " + getServletName() + " and my job is done");
}
}
The Second servlet
#WebServlet(name = "BiggestAsyncSecondServlet",
urlPatterns = "/biggestAsyncRequestTest2",
asyncSupported = true)
public class BiggestAsyncSecondServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
//asyncContext.setTimeout(10000);
//asyncContext.createListener(BiggestAsyncContextListener.class);
//asyncContext.start(new BiggestAsyncFirstWorkerThread());
/*
Step 5.Get the reference to the thread pool that was created in the context listener class
when the app was deployed
*/
ThreadPoolExecutor executor = (ThreadPoolExecutor) request.getServletContext().getAttribute("executor");
/*
Step 6.Actually creating the worker thread
and kick starting the thread by calling the run method of the class implementing the runnable interface.
*/
executor.execute(new BiggestAsyncSecondWorkerThread(asyncContext));
System.out.println("Hi I'm the servlet " + getServletName() + " and my job is done");
}
}
The first worker thread
public class BiggestAsyncFirstWorkerThread implements Runnable {
private AsyncContext context;
public BiggestAsyncFirstWorkerThread(AsyncContext context) {
this.context = context;
}
#Override
public void run() {
//The idea is to write something to the response and then dispatch.
try {
AsyncRequestProcessor.waitingTime(6000);
PrintWriter writer = context.getResponse().getWriter();
writer.print("<html>\n" +
"<head>\n" +
" <title>User login</title>\n" +
"\n" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"/" +
context.getRequest().getServletContext().getServletContextName() + "/style/master_css.css\">\n" +
"\n" +
"\n" +
"</head>");
writer.print("<body>\n" +
"<div id=\"allcontent\">");
context.getRequest().getRequestDispatcher("pages/common/header.jsp").
include(context.getRequest(), context.getResponse());
writer.print(" <div id=\"actual_content\">");
context.getResponse().flushBuffer();
context.dispatch("/biggestAsyncRequestTest2");
} catch (IOException | ServletException e) {
e.printStackTrace();
}
}
}
The second worker thread
public class BiggestAsyncSecondWorkerThread implements Runnable {
private AsyncContext context;
public BiggestAsyncSecondWorkerThread(AsyncContext context) {
this.context = context;
}
#Override
public void run() {
//The idea is to write something to the response and then dispatch.
try {
AsyncRequestProcessor.waitingTime(6000);
PrintWriter writer = context.getResponse().getWriter();
context.getRequest().getRequestDispatcher("pages/common/cr_leftnav.jsp").
include(context.getRequest(), context.getResponse());
writer.print(" <div id=\"content-body\">\n" +
" <h3>The external app</h3>");
writer.print("<p>This is the page you have been waiting so patiently for. After one round of asynchronous processing" +
"here you are. I love you..!!</p>");
writer.print(" </div>\n" +
" </div>\n" +
"</div>\n" +
"</body>\n" +
"</html>");
context.getResponse().flushBuffer();
//context.complete();
context.dispatch();
} catch (IOException | ServletException e) {
e.printStackTrace();
}
}
}
And finally the initial call from the jsp that triggered this request in the first place
<div id="sidebar">
<ul id="parent_nav">
<li>Checking everything async does</li>
</ul>
</div>
Note: I have an async listener too. But the error seems to have nothing to do with it, so leaving it
Some additional info
Before the error I have mentioned at the top prints, the following lines are printed in the logs, suggesting that it's going wrong on line 23 of the Second Servlet.
<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter
Hi I'm the servlet BiggestAsyncFirstServlet and my job is done
<<AsyncRequestLoggingFilter>> This is AFTER returning from the doFilter call
<<AsyncRequestLoggingFilter>> This is BEFORE calling the doFilter during the ASYNC dispatching
My apologies for such a long question. Any help I can get to understand why it's saying "A filter or servlet of the current chain does not support asynchronous operations." despite all the components being marked with asyncSupported=true, is deeply appreciated.
Thanks,
Kingshuk

java.lang.NullPointerException in servlet error 500

When I run my Servlet I get this error:
java.lang.NullPointerException please i tried many solutions but it didn't work it's simple code
public LoginServlett() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String name = request.getParameter("UserName");
String pass = request.getParameter("Password");
RequestDispatcher d=null;
if (name.contentEquals("Gestionnaire") && pass.contentEquals("1234")) {
HttpSession session;
session =request.getSession(true );
d =request.getRequestDispatcher("/EspaceGestionnaire.html");
session. setAttribute("NomSauvegardé" ,name);
}
else {
d = request.getRequestDispatcher("/Authentification.html");
d.forward(request, response);
}
}
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
}
}
A NPE will be thrown from the code if the Username and Password parameters are not set. If they are not set then the user and pass variables will be null, and when the contentEquals methods are called on them a NPE will be thrown as a result.
A way to do this would be to reverse the equality checks so the operation is called on string you want to check:
if ("Gestionnaire".contentEquals(name) && "1234".contentEquals(pass)) {
which will do what your code intends without throwing a NPE.
Although if you are sending passwords over the internet it is better to use POST than GET. For Java EE security there is also the new security API (https://javaee.github.io/security-spec/)

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!

Servlet shows blank page when using println in method other than doGet or doPost

My dynamic web app is showing a blank page when using println in a method other than doGet or doPost. The default page loads fine. On it is a form that has an input that's passed to the startup servlet's doPost, and then it's request, response gets passed to a second servlet's doPost. Then the same request, response gets passed to an output method than uses println to display the output. But I'm getting a blank page instead of the output. I know that the output method gets called because I was getting an error with it when I initially tried using a BufferedWriter to write to an output file, but that wasn't working. This is my first attempt at a Java EE dynamic web app and using println, although I have intermediate experience with PHP, ASP.Net and several languages in desktop apps.
The second servlet's doPost method calls the methods of readnums, sort, and outputSort. The readnums method reads a text file for the program to use. I'm having problems with relative paths (that's why I couldn't get the BufferedWriter to work in outputSort, I suppose). The path I'm using for the input text file is "/WebContent/WEB-INFO/myfile.txt". Will I have a problem with this once the web app is deployed with a hosting site? At the risk of asking 2 questions in one, how do you correctly specify relative paths to the app? I've Googled and Googled but can't seem to find a working solution. When I try to use getServletContext().getRealPath() I get an error in the outputSort method at that line. I didn't try to use it in the readnums method yet. I've got a website that I can hotlink to for the input files if that is a viable alternative. How would you do that?
Any help with this would be greatly appreciated. Thanks in advance.
Initial servlet called from the default jsp:
package com.LAEWeb;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Startup extends HttpServlet {
private static final long serialVersionUID = 1L;
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.getRequestDispatcher("/WEB-INF/Startup.jsp").forward(req,resp);
}
#Override
public void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
String sorts = req.getParameter("sorts");
String action = req.getParameter("action");
if ("Powerball".equals(action)) {
Powerball p = new Powerball();
p.sortInputText = sorts;
p.doPost (req, resp);
}
else if ("Mega Millions".equals(action)) {
// Invoke SecondServlet's job here.
}
}
}
The second servlet's methods (I didn't list readnums and sort for brevity):
#Override
public void doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
if (PB_operation == "sorts") {
readnums();
if (!errorMessage.isEmpty()) {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
try {
out.println("<html>");
out.println("<body>");
out.println("<h2>Input file not found</h2>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
return;
}
else {
sort();
outputSort(req, resp);
}
}
}
void outputSort (HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
String Temp;
int i;
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
try {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println ("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
out.println("<title>LAEWeb</title>");
out.println("</head>");
out.println("<body>");
out.println("Return to previous page ");
out.println("<h2>The Powerball sorted totals for the range selected</h2>");
out.println("<pre>");
out.println("Rank Numbers Totals Power ball Totals");
out.println ("");
out.println ("");
for (i = 1; i <= NUMLIMIT; i++) {
Temp = "<p>" + Integer.toString(i) + " ";
if (i < 10)
Temp += " ";
Temp += Integer.toString(sortnums[i][1]) + " ";
Temp += Integer.toString(sortnums[i][2]) + " ";
if (i <= XLIMIT) {
Temp += Integer.toString(sortxball[i][1]) + " ";
Temp += Integer.toString(sortxball[i][2]) + " ";
}
out.println (Temp);
}
out.println("</pre>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
If you want to get real path of a relative path you can use getRealPath() method, for example:
String realPath = getServletContext().getRealPath("/WEB-INFO/myfile.txt");
If you're using this code in init() method of your servlet, use:
config.getServletContext().getRealPath("/WEB-INFO/myfile.txt");
To answer first part of your question, I need more information about it. I'll edit this answer after getting information.
I used getServletContext().getRealPath() in the first servlet and passed the path to the second servlet through a class variable in the second servlet. That worked. Thanks for your help Ali for pointing me in the right direction. I guess since the second servlet is not actually initializing normally (I'm just calling it's doPost from the first servlet) the context for it is null. Thanks again for the help!

Resources