Is there any way to get access to the ServletContext from a method without passing the ServletContext as an argument?
I need to have a generic Configuration class that can work on several environments and load the config in a way depending on the environment.
For example, when in a web app, i need to get the configuration from either web.xml or a config file stored in WEB-INF.
But in order to know if the app is running in a web app i need to gain access to the ServletContext somehow.
Any ideas?
Have a class that holds servlet context as static field initilize it from ServletContextListener
Related
I'm trying to get ServletContext in the class which is implementing EnvironmentPostProcessor. ServletContext is required to get the war filename. Based on war file name I get properties from a database and will set to properties to user later in the applications.
I'm not using Embedded Container but WildFly Server
public class ClEnvironment implements EnvironmentPostProcessor, ServletContextAware, ServletContextInitializer
But it's not working.
You can’t get the ServletContext in an EnvironmentPostProcessor. The post-processors are loaded from spring.factories very early in the application’s lifecycle. With an embedded servlet container that happens long before the container has been started and the ServletContext is available.
This may be an XY problem. Perhaps you could ask another question that explains what you are trying to do. There may be another way to do it that does not require access to the ServletContext in an environment post-processor.
I have a tomcat server running a webapp. In the webapp's startup, I'm setting few context parameters using an implemented class for interface ServletContextListener. The parameter that I am initializing here are a couple of connection objects for a database running on a different machine.
The doubt that i have is whether the connection objects that I created here are one for each instance (since tomcat creates one instance per client request), or one for the entire webapp itself?.
If it is one per webapp, then can the server handle large simultaneous requests (in the order of thousand request per second) to perform the CRUD operations on the database?.
ServletContext is created one per webApp. The server reads the web.xml file from the web app and creates a ServletContext based on the configuration you provide on web.xml. Once created it is shared between the components of the web app. If you have multiple webapp installed on your server, you will have multiple ServletContext - each for the web app.
For reference please have a look here
A webapp has only one instance of ServletContext and the atributes in ServletContext are application scoped.
Regarding you database connection, it's better to use connection pooling (DataSource) instead of adding Connection objects as attributes in ServletContext.
Not sure if you mean this but the requests are handled by Servlets and not ServletContext.
If your setting an attribute on the ServletContext the attribute will be scoped for the entire application.
From the Java EE 7 Spec:
There is one instance object of the ServletContext interface
associated with each Web application deployed into a container.
only one ServletContext is loaded irrespective of the number of requests made.
This is even the advantage of servlets over CGI.
Hope it helps.
I'm far from an expert of the intricacies of Resource Injection, and of indeed DataSources in Java, but I generally understand the process of doing a lookup for a predefined JNDI resource to get a datasource from.
Using Resource Injection as an alternate method, the below syntax works:
#Resource(name="jdbc/Foo")
private javax.sql.DataSource con;
However, I am using this in a servlet and as such wondering, how long this injected connection object's value will exist? Presumably, as it's simply an object within the servlet, it will inject when the servlet is first instantiated and exist for the same duration as the servlet (assuming I don't manually change it). Is this correct? Or does the servlet re-inject the resource everytime the servlet is used?
Thanks
A servlet container only ever creates one instance of your servlet. The IoC container you're using will then instantiate and inject the DataSource, so the value in con will remain the same for the life of your servlet, ie. the life of the application.
As to the underlying connection the DataSource is trying to make will, that's up to your datasource.
it will inject when the servlet is first instantiated and exist for the same duration as the servlet
Correct.
Or does the servlet re-inject the resource everytime the servlet is used?
No, this couldn't be happening because each request is served by a different thread. It wouldn't be good if those threads would modify the fields of the servlet. Request processing methods of the servlet must not modify its fields.
Generally container managed resources are injected using #Resources annotation. And container managed resources live as long as the container is running ( unless your are not manually kill it or any exception happens). Several applications can use the same resource object, provided that they live in the same application server ecosystem (same application server or cluster or server domain). But servlets are managed by your applications and lives within the application's scope as long as your application is running! So in terms of life span, if you compare resources are longer living than servlets.
And yes you are right, if you inject resources to a servlet, the reference of the resource will remain from the creation of the servlet to the end of the servlet's life cycle. The injection is not related with, how you are using the servlet or the resource.
Hope, this answers your question, Thanks!
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.
I have a JSF session scope bean and I'm keeping current user(logged in) information in that bean. I also have a class which is neither servlet nor bean, its just a class. I want to access the jsf bean and get current user information in the class. I've found a solution for servlet to access jsf bean but i couldnt find a solution for this problem. Is there any way to do that?
Thank!
If the instance of the mentioned class is running in the same thread as the HTTP request thread which has invoked the FacesServlet, then you can just get it by the FacesContext and then Application#evaluateExpressionGet(). See also Get JSF managed bean by name in any Servlet related class
If the instance of the mentioned class is running in a different thread, then you'd need to pass the desired information beforehand to the class' constructor, method or to store the desired information in some shared datasource which both the JSF webapp and the standalone class have access to, such as a database, a local disk file system file or the JNDI context. Depending on the context and the environment, CDI's #Named+#Inject may also be the solution.
The "best way" depends on the concrete functional requirement which is not clear from the question, so I can't point out the right way nor give any kickoff examples.