How to approach shifting a Java Swing app to a Servlet? - java

I want to use the Model-View-Controller template while writing my Web App. The problem is, the Model part of the code has already been written in Swing. The Model code also must require the container to call its main method before any interaction with its servlets. So is there a way for me to specify the location of the main method in the Deployment Descriptor so that the container calls the main method and compiles the code, and then, keeps it running for the entire duration the server is running without in any way restarting or recompiling the model class in between.

Try looking into load-on-startup parameter of servlet in Deployment Descriptor (DD). Precisely, it will load that particular servlet on server start-up.
Moreover, you should read about request lifecycle, request/session/application context. And you must look into JSP (or any other popular technology) for creating V of MVC. How URL mapping works.
Main method is basically work as an entry point in our application. Whereas in web application there is no particular entry point. Or if there is you can think of a welcome page. You might also want to look into welcome-file-list parameter of DD.
Cheers.

To run initialization when a web app is loaded, you can either use the servlet's init method or a ServletContextListener. You can call the main method from either of those yourself.

Related

Jersey 2.5: How can a resource access external classes instances

I have embedded Jetty container inside my main server and I also use Jersey 2.5 for handling REST resources.
everything seems to work well and now I would like to pass my server's context class into each of my REST resources.
I'm having hard time understanding how to do that...
If someone can provide full code example - it could be awesome!
Many thanks
What exactly do you mean when you say you have a Jetty container inside your "main server"? Are you programmatically executing Jetty within the application? Also, when you say "context" are you referring to the ServletContext?

Changing servlet location on Init()

Is it possible to change the init parameters so that the servlet is created at a different path? I need to create a servlet at a certain path. Furthermore, would it be possible to artificially pass the path inside the init parameters?
As already shown in other answers, the servlet mapping is not controlled by the servlet, therefore you can't change that from within a servlet instance.
However, you can work around this by introducing a level of indirection (something like a "dispatcher" servlet): map your servlet to a wildcard pattern (like /app/*) and inside your servlet decide the actual action based on the request url path: /app/X will trigger some X action, while /app/Y will trigger Y.
Lots of web frameworks will provide the full functionality out of the box: you can have a look at Spring MVC's DispatcherServlet and its HandlerMapping concept, for instance.
Servlets aren't created at a certain path. They are Java objects that the servlet container Java application creates. If you are running Tomcat, for example, your application will run from the /webapps directory. The most you can do is change the Tomcat configuration to run it from some other path, but you'll have to do this before actually starting the application.
Short answer - you can't change anything related to servlet path mapping in init, since servlet container has already read mapping from web.xml.
Longer answer - you may want to look at servlet loader in Tomcat for example, perhaps it's possible to either invoke it's methods through JMX or do something else.
If you just want to have several mappings and choose which one to serve depending on configuration - use Servlet Filter

Running code post container load - Ressource loading

I'm trying to add the following behaviour to my jersey service:
Load/Parse some files from the WEB-INF folder
Store it in a singleton for quick access through the application's life.
Right now the solution that I have working is:
Get the ServletContext for a ressource request
For each request which needs to access the files, call this method getSomething(criteria, servletContext)
I have to pass the servletContext around so that I may use it to load the ressource using method getRessourceAsStream() as otherwise, I cant get the right path. This is my main pain point.
I'd like to be able to make the server automatically do this once the server is ready in the application server but I'm unable to find where exactly this could be done. This would eliminate the need for me to always pass the servletContext around and would allow me to use that singleton in some of my custom deserializers and would make the code that uses this singleton cleaner.
Any time you find yourself wanting to do some work on startup in a Servlet application, use a ServletContextListener, specifically the contextInitialized(ServletContextEvent) method.

What acts in the role of the 'main method' in a servlet?

Servlet is also java program but there is no main method in servlet.Who will take role of main method on servet.
Servlets are designed to run inside a servlet container (eg. Apache Tomcat). Execution of a servlet happens in the following manner: The servlet container calls the GenericServlet.service() method on a servlet which typically calls the appropriate doXxx() method, eg. doGet(), doPost(), etc. The doXxx() method is responsible for interpreting the HTTP request and serving an appropriate response. GenericServlet.service() is roughly analagous to main() in a plain old java class.
Servlet runs inside a container(eg:tomcat). This container perform its work under jvm.
Here container takes "the absence of main method". In simlple java program main method tells
the starting control flow of the execution. But in case of servlet base web application jvm dose not need to search the main method. Servlet container tells jvm about the starting
control flow.
Servlet are deployed on Java application server (servlet container). They are kind of 'passive'. When you write servlet, your servlet code is called by the container whenever there's request or need. So you don't see 'main' in your servlet (the whole thing is not started from servlet), which is inside application server (you could imagine the startup of application server starts from some kind of main).
If you're looking for an area in a servlet to place code that's run on startup (similar to main()), take a look at implementing the ServletContextListener interface.
Its two methods are called on application startup and shutdown.
There is no main method in a Java servlet any more than than an ActionListener on a Swing JButton has a main method. What they both do have are methods that you can hook into when a certain event happens (a click on the JButton for example, or an HTTP PUT request on a HttpServlet). And in both cases, you are provided information about the event that triggered the call - the ActionEvent for the JButton and the ServletRequest for a servlet.
Thinking of servlets in terms of event handlers is probably more useful than trying to think of them like a standalone Java application where you are responsible for the entire control flow.

Clean up after servlet if init() failed

I have an Initializer class that implements the ServletContextListener interface. In its contextInitialized() method, I initialize some global classes that have to be destroyed, otherwise the servlet cannot be unloaded.
However, when the servlet's init() method throws a ServletException, the contextDestroyed() method never gets called --> resources are not release --> servlet does not get unloaded by Tomcat (it remains in "running" state even though its init method never finished).
My question is this - how do I cleanup the resources in this case?
Bonus: why does the servlet even get to "running" state? I understand from the documentation that it's not supposed to be running unless the init() method finishes successfully.
Edit - I think this is because each status line displayed in Tomcat Manager represents an entire war, and not a servlet. A war may contain several servlets, with some succeeding to start and others not. The Initializer is called when the container starts, and its destroy is called only when the entire container is dropped. This leads to a related question - is there a similar built-in way to monitor the state of individual servlets?
(I'm aware I can write custom code to monitor the servlet, either via JMX, or not, but that's out of the scope of
this question).
As far as I can tell there's absolutely no way to do so without an external request. ServletContextListener gives you the correct signal (when all servlets have been initialized - successfully or not), but you can't enumerate all servlets in the context to test their status because the relevant ServletContext methods were deprecated and now return an empty enumerator.
In short, the only way to do this is via a nonstandard API; in particular, it's almost trivial to do this with Tomcat's JMX API, which is the course I'd recommend.
In real world the init() should never fail. If it fails, then it is a programming error which the developer is supposed to fix. The appserver webcontainer has nothing to do with it. The servlet will simply be kept unavailable.
What container are you running?
Tomcat for example does support JMX. You can always write your own JMX-beans.

Categories