1

I'm writing a web page using java servlets. When the user subscribes he will receive an email with the activation link. Currently the servlet redirects the user (using the request dispatcher) to the thank you page after it sends the email and this takes some time. I would like to redirect the user to the page before the email is created and sent and then have the email creation performed by another servlet without the user having to wait. Is this possible? How can I call a servlet from within another servlet after using the request dispatcher.forward method? Is that possible? If not, then what is the best way to do what I want? Thanks.

user3245747
  • 825
  • 2
  • 13
  • 26
  • 3
    A servlet is a component used to receive HTTP requests, handle them, and return an HTTP response. You want a class that is called by a servlet to send an email. Why would it be a servlet? If you want to execute code in the background, use an ExecutorService and post a task that sends an email. – JB Nizet Sep 15 '14 at 18:07
  • 1
    You may find http://stackoverflow.com/questions/3745905/what-is-recommended-way-for-spawning-threads-from-a-servlet-in-tomcat and http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html resources useful to achieve what JB said. – skuntsel Sep 15 '14 at 18:21
  • As @JBNizet said, spawn a thread that will send the email indendently so the servlet can return immediately. – markbernard Sep 15 '14 at 18:48
  • This method worked but I would like to know if its safe to use it with servlets. i read in several places that its not safe to spawn threads within a servlet. Thanks – user3245747 Sep 15 '14 at 20:13

3 Answers3

1

There are in fact 2 different problems in your question :

  • you want to redirect to another page
  • you want to continue processing after the redirection

It is simple to redirect to another URL from a servlet, just call :

response.sendRedirect("url?param=value");

For the second part, it seems that it is possible to continue processing in servlet after sending the response to the client. From my test on a Tomcat 7 servlet container, you can do so if ContentLength is set to 0 (as body is empty) and the output stream is closed. I could never have a confirmation from servlet specs, but as I wrote above it works on Tomcat :

response.sendRedirect("url?param=value");
response.setContentLength(0);
response.getOutputStream().close();
// continue after connection with client is closed
// generate and send email
Serge Ballesta
  • 121,548
  • 10
  • 94
  • 199
0

To call another servlet from a servlet, you donot use request.getRequestDispatcher("xxx").forward(req,res); but rather you use response.sendRedirect("servletname or path to the servlet");

You can also add parameters to the response.SendRedirect("xxx"); so that the recieving would use that parameters to sent the email. To add parameters to the response.sendRedirect response.sendRedirect("<servletname>?email="+email); this will expose the user's email address with the new url.

Based on your question, you can do something like this: request.getRequestDispatcher("page/to/display/user").forward(req,res); session.setAttribute("email","username of user"); response.sendRedirect("servlet/to/redirect");

EDIT: You can create a method with boolean which will redirect the user to the thank you page, when successful, then process the email:

public boolean redirect(HttpServlet request, HttpServlet){ response.sendRedirect("<servletname>"); return true; }

In the Servlet:

if(redirect){ processEmail(parameters); } END EDIT

Then in the servlet that you want to send the email, you use the session to get the email that was added to the response. String email = (String) session.getAttribute("email");

Hope this helps.

Hubert
  • 144
  • 6
  • i keep getting this error message: Cannot call sendRedirect() after the response has been committed – user3245747 Sep 15 '14 at 20:10
  • This worked but I have decided to go with the executor service because it made more sense to create a runnable object than to have have a servlet do the work. But thanks anyway, your method worked. – user3245747 Sep 16 '14 at 12:48
  • I would use forward. Difference between sendRedirect and forward: https://javarevisited.blogspot.com.es/2011/09/sendredirect-forward-jsp-servlet.html – user1156544 Sep 07 '16 at 13:25
0

Based on your description you would like to return message to the user and then process 'in the background' email request. It shouldn't be done via other servlet. If you have Java EE server with JMS support, that is typical task for JMS and MDB. Your servlet would just put the message email sending request to the queue and returning message to the user. MDB would pick up that message and process it, and send the email.

Method with spawning is doable as you tested and should work in most of servers, however it is discouraged. See some discussion here Why spawning threads in Java EE container is discouraged?

In Java EE 7 you will have support for it via concurrency utilities - Concurrency Utilities tutorial

Community
  • 1
  • 1
Gas
  • 16,202
  • 4
  • 36
  • 78