Difference between javax.servlet.ServletContext and javax.naming.Context - java

As I knew, Java ServletContext and Context Objects are common used inside Java EE program development. However, I'm not quite sure about what are the differences between them, especially the Context Class usages.
From what I understood, ServletContext is the Object which contains all initializations read from Web.xml so that all servlets in the web application can share those global configurations.
On the other hand, I usually only used Context Object when I needed to dynamically establish database connection with JNDI lookup. Beside that, I'm not clear about other possible usages of this class.
My main concern is does the "context" word of both ServletContext and Context classes represent the same thing or component inside web application?

From the ServletContext javadoc
Defines a set of methods that a servlet uses to communicate with its
servlet container, for example, to get the MIME type of a file,
dispatch requests, or write to a log file.
Basically it's an accessor to the servlet environment. Anything that is relevant to the servlet, you can get it from there. It's really only useful with a Servlet Container.
The JNDI Context javadoc
This interface represents a naming context, which consists of a set of
name-to-object bindings. It contains methods for examining and
updating these bindings.
This is an interface to a resource. You configure a resource with a some identifier which you can retrieve through this interface. You are not limited to using this only in a Servlet Container. For example, you might store a list of connected devices on your network in an LDAP repository. To access this repository, you could write custom code implementing the protocol and interacting with an LDAP server or you could use the LdapContext class, which implements the Context class. Or, you could use it to lookup a JDBC DataSource.
Don't let the fact that they have the same name bother you. They have different goals.
This answer might be of help for when you see Context in a different context.

Related

WebApp. Java EE. Where I should initialize my business logic?

I recently started learning java EE (jsp, servlets and some patterns for working with database like a DAO) and I dont understand where I should initialize my bussines logic? I think that create instances of it in body of do*** servlet methods is a bad practice. P.S. my app use DataSource and ConnectionPool for connection with db.
You need to specify your requirement somehow, what initialization you are looking for. Is it a EJB solution? Pure Servlet/JSP solution? etc.
Normally when deploying your application, after an invocation the application will load the required logic.
Of course you can do initialize to speed up the load, to make required code run before users enter the application etc.
In EJB we are talking about #Singleton and #Startup annotations.
For servlet you can use the annotation #WebServlet(name="startup", loadOnStartup="0"). Or put it in your web.xml. Depends how you code.
A more recommended way is to create you own listener, and override the contextInitialized and contextDestoryed methods. E.g. create db connection etc in initialized method and deregister the driver in contextdestory method. Use annotation #WebServletContextListener or add the listener to your web.xml
Also Java web server specific solutions exists, you need to check your vendor.

How to get a global object which has been set in a Java Servlet Context

I am working on a Tomcat application which populates a HashMap on startup. I set it in the ServletContext using ServletContext.setAttribute. However, I have some non Java EE classes also in this application (basically my webservice calls call those methods). I want to access this HashMap in those Methods. What is the best way to do it?
Your web service should have access to HTTP Request and Response where you can get ServletContext. When web services call these non J2EE methods, you can pass the map as a argument parameter.
Fetch the HashMap in your web service class and pass on the same as method argument to your non Java EE classes.
You can make your map available to all classes of your application:
Using a Singleton
See What is an efficient way to implement a singleton pattern in Java?
Using Tomcat global JNDI tree (not recommended, but you can do it).
See How do you save name-value pairs in Tomcat environment? and Apache Tomcat 7 - JNDI Resources HOW-TO
Thank you all for the suggestions. However what I was trying to achieve was achieved by the following example:
http://www.xinotes.net/notes/note/1772/
It gave me a method to retrieve the context in non-Tomcat handled classes.

EJB properties file

In my project I have 2 modules, a ejb and a war module. In the war module i have a properties file that is processed when I start the web application (by a listener). For each property in this properties file, i add it to the servlet context.
So, my question is: is it possible to access this properties, in the servlet context, from a enterprise java bean in the ejb module? I want to do something like this, but in a ejb:
ServletContext sc = myservlet.getServletContext();
String xpto = sc.getAttribute("my-attr");
If this is not possible, what is the alternative?
Thanks!
P.S I'm using netbeans and glassfish.
ServletContext is always loaded ahead in the Servlet lifecycle loading. Ref to this link. As you see the Listeners are loaded after the ServletContext is loaded when application starts. You can have your code in the listener class that extends ServletContextListener. Ensure you are extending correct Listener as given in the link.
In your situation, One of the alternative is to have a Singleton class load all the properties from the properties file. for ex: ApplicationPropertiesLoader class can have a Properties map attribute to store the key value pairs of that property file. This class can have a getProperty method that always refer to its internal Properties.
In your servlet class refer to this singleton class to load the properties as required.
Speaking of alternatives, it might be worth a thought to use configuration stored in database, at least if you already have a database connection in your application and have control over the database schema.
We use this technique in all our web applications, mainly for two reasons:
Changes to a property can be done during runtime without monitoring file changes, they can be done by the application itself and one does not need to know a path outside of the deployed application.
Properties can have additional information, such as a type (e.g. number, date, string), a default value, a comment or a user who changed it.
For implementing it, you'll create an application-scoped component which accesses the database properties for the rest of the application.

Get properties files from multiple servlet contexts

I'm working on a web application that is spread over multiple contexts running inside one instance of tomcat. The contexts are marked with crossContext="true" so that we can share some of the jsp between the different contexts. There is also a set of common classes that are part of the common.loader for tomcat. We are to far away into the project to change this structure so please be sensitive to this structure when answering the question.
What I would like to do is get all the resources, say com.something.messages, that are present in all the different contexts. Is this at all possible? Should I record the class loader for each context created and use it to load the resources? What do you recommend?
If you're already on Servlet 3.0, then you could use ServletContext#getClassLoader() to obtain the servlet context's own class loader:
ServletContext otherContext = servletContext.getContext("/other");
ClassLoader otherClassLoader = otherContext.getClassLoader();
// ...
(if this throws a security exception, edit the policy file accordingly)
You could then pass this class loader into for example ResourceBundle#getBundle():
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, otherClassLoader);
// ...
If that's not possible due to various reasons (e.g. not using Servlet 3.0 yet, or not willing to fiddle with policy files (very reasonable...), etc), then your best bet is to give each web application its own ServletContextListener which loads the desired bundle and stores it as an attribute of the ServletContext during the contextInitialized() method. This way you can just get it as an attribute the usual way.

Initializing Memcached/JDBC Resources for a JAX-RS servlet

I have a service where I want to maintain data persistence in a mysql db using jdbc. While i have experience building jdbc apps and jax-rs apps in isolation, I've never combined the two. The question is, where does the build up and tear down required for the jdbc-type stuff go? Ordinarily i'd put the build up in a static block, or in a constructor, and id have have a cleanup method that gets called in a finally. this doesnt seem to work in the jax-rs framework- the constructor gets called at every invocation, and there is no place to my knowledge to put any clean up methods. unfortunately, there are sparse examples for combining the two technologies online, something i find surprising. Can you guys help me out?
As a general rule, to do things at the startup and shutdown of your web application, you should create custom ServletContextListeners and list them in your web.xml.
With JDBC resources in a WAR, often times you have your container (e.g. Tomcat, Websphere, etc.) create and manage a connection pool which can be shared with a number of web applications. You would define a resource-ref for a javax.sql.DataSource in your web.xml. Then there is a container specific method for defining and binding the JDBC DataSource to the resource-ref of your application.
I'm not familiar with Memchached and what is needed on startup/shutdown so this is only a guess. If you need to register/unregister with a Memcache server you might try having one or more env-entry tags defined in your web.xml which could be used by a custom ServletContextListener to do your bidding.

Categories

Resources