1

New to java, and this question is different from typical java workflows out there and will need some help from very experienced architect, coming from node.js background, trying to implement an architecture based on some design patterns that I already implemented in node.js and PHP and some frontend languages (including Java Swing) and I look forward to implement the same for Java Servlets.

I understand that within Servlets doGet, doPost etc. are the entry points of a request and a single instance of a servlet is instantiated and re-used concurrently for all incoming requests via multithreading.

for these design patterns (another topic, requires it's own thread) to work I need to have an uber level access to get hold of these servlet instances and set my actors on top of them as delegates/listeners.

I've read that servlets are either instantiated after the first request or loaded right with the container, so for this to be implemented I'll need them loaded at the startup so I can perform the operations on them.

Again this question is different and may require some discussion for a deep understanding, to help us to exchange things about each other worlds.

In short I need the following two things to make it work.

  1. A way to define my own class (let's say Uber) to have it loaded as container gets loaded.
  2. The Uber class then is able to get reference to loaded servlets or servlets can reach out to Uber

1 Answers1

5

Solving point 1 is easy. Create a class that implements ServletContextListener and in method contextInitialized create your instance of Uber.

Point 2 is impossible. The server is not allowed to provide you info about the instances of Servlet it has created. The method to obtain these, ServletContext#getServlet, is deprecated. Also, the application server may use a single instance or multiple instances of a Servlet, the server will decide the behavior at runtime.

Since we don't exactly know your purposes on knowing the instances of Servlets and what to do with them, we cannot provide more help.

Still, in point 1, since you create the instance of Uber, you can store it as an attribute in ServletContext, and then retrieve it in each servlet using HttpServletRequest#getServletContext.


From your comment, it looks like you want/need to implement Front Controller. For that, it will be better to use a single servlet that does this work and create the classes that will do the real job of handling the request. Instead of reinventing the wheel, I suggest you to use a framework that already implements this like JSF or Spring MVC. If you still want/need to implement the pattern by yourself, please check here.

This is how your (odd and not recommendable) design will look like (based on Jozef's comment:

@WebListener
public class AppListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent e) {
        Uber uber = new Uber();
        /* configure uber */
        //store it in ServletContext
        e.getServletContext().setAttribute("uber", uber);
    }
    @Override
    public void contextDestroyed(ServletContextEvent e) {
        //...
    }
}

Then in a servlet, register it into the instance of Uber:

@WebServlet(value="/myServlet", name="myServlet")
public class MyServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) {
        Uber uber = (Uber)config.getServletContext().getAttribute("uber");
        uber.registerServlet("myServlet", this);
    }
    //more code...
}

Still, I don't like the idea of another class needing to know about your Servlet.

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Thanks for solving #1, For #2, the point is to use servlets basically as routers, with them intercepting the requests and then delegating `request` and `response` to `Uber` (set of design pattern classes actually), put simply servlets need to know the `Uber` and `Uber` needs to know servlets to be able to talk to each other, and I understand application server may use single instance or multiple instances which is actually blocking me. –  Jul 02 '15 at 15:54
  • If you have control over the source code of those servlets, I'd consider using the Observer pattern - i.e. store the `Uber` class into servlet context (as described by Luiggi), and then each servlet will register itself to your `Uber` class. Anyway, your design seems to me a bit overcomplicated. – Jozef Chocholacek Jul 02 '15 at 16:00
  • @JozefChocholacek your idea is interesting, yes I've the control over the source code of those servlets, so now my question is how do I reach out from a constructor of a servlet to my `Uber` (which as per the suggestion of Luiggi Mendoza is a ServletContextListener), that will solve the problem... (with the exception that I'll have to consider multiple instances of the servlet). –  Jul 02 '15 at 16:29
  • 1
    @user3610227 you can't do it in the constructor of the serlvet. Use the [`init`](http://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#init-javax.servlet.ServletConfig-) method instead. Still, I agree with Jozef, this design is very odd and should be avoided, it will be better to have a single controller for all the non-resource (js, css, images or any other) requests rather than having your `Uber` class. It will be like moving the relevant code from `Uber` to this servlet. – Luiggi Mendoza Jul 02 '15 at 16:31
  • I'm studying FrontController pattern, and the idea is very prospective. Can you please add a code line to your answer, reaching out to `Uber` from `init` method, just in case for weighing another approach. –  Jul 02 '15 at 16:34
  • @LuiggiMendoza Thanks, I know you didn't like it and it's because behind the scenes work is not clear in the question and requires a long discussion, but I liked your solution. `Uber` is basically `Facade` along with some other GoF patterns, I think I can handle multiple servlet instances (or Router) as well, I'll ping you with another question down the road in case. Thanks again and regards. –  Jul 02 '15 at 16:54
  • @user3610227 JSF and Spring MVC do this in the servlet, applying GoF Patterns and such. After all, a Servlet is just a mere Java class :) – Luiggi Mendoza Jul 02 '15 at 16:56
  • @NathanHughes yes I understand that, I did an implementation in node.js which is not only stateless but runs in a single process/thread. –  Jul 02 '15 at 17:01
  • @LuiggiMendoza yes JSF and Spring MVC are perfect for that, but it's for another reason, especially when it comes to multi modular connected via unix style pipes (decoupled), I'm not sure if other frameworks provide solution like that, it kinda requires me to work outside from them but I do need to know about their domain knowledge and how they work for some help. –  Jul 02 '15 at 17:07
  • Thanks @JozefChocholacek for your observer pattern idea –  Jul 02 '15 at 18:01
  • @LuiggiMendoza you mentioned JSF and Spring MVC do this in the servlet, I'd like to see how they hookup servlets with their internal code, appreciate if you can send a direct link to that part of the code especially for Spring MVC. –  Jul 03 '15 at 15:58
  • @user3610227 do the research yourself here: https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc/src – Luiggi Mendoza Jul 03 '15 at 16:13
  • @user3610227 by the way, you should start by reviewing [`DispatchServlet`](https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java) and its ancestors to see how all this works. – Luiggi Mendoza Jul 03 '15 at 16:17