Start class right after deployment, not at session start for JSF - java

For a web application I make use of JSF 1.2 and Facelets.
The problem is that we now do the initialisation via a singleton pattern and that takes about 5-15 seconds because it read in data files (we are not using a database). This happens when the first user browses to the corresponding web page (the 2nd and other users don't have this delay).
I would like to have this singleton initialised right after deployment. How can I do this? I've tried to add an application bean but it does not get called. I've also tried to add a servlet as followings:
<servlet>
<description>MyApplicationContextListener Servlet</description>
<display-name>MyApplicationContextListener Servlet</display-name>
<servlet-name>MyApplicationContextListener</servlet-name>
<servlet-class>mydomain.beans.MyApplicationContextListener</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>mydomain.beans.MyApplicationContextListener</listener-class>
</listener>
with the following code:
package mydomain.beans;
import javax.servlet.ServletContextEvent;
public class MyApplicationContextListener {
public void contextInitialized(ServletContextEvent event) {
System.out.println("MyApplicationContextListener.contextInitialized started");
}
public void contextDestroyed(ServletContextEvent event) {
System.out.println("MyApplicationContextListener.contextInitialized stopped");
}
}
An example including changes needed in web.xml and/or faces-config.xml would be nice!

How about using a ServletContextListener ? Its contextInitialized(..) method will be called at the moment the context is initialized. It's mapped in web.xml like this:
<listener>
<listener-class>com.example.MyServletContextListener</listener-class>
</listener>
Also, (not sure this would work), you can configure your faces-servlet to be loaded on startup.:
<load-on-startup>1</load-on-startup>
Clarification: For the listener approach, your listener must implement the ServletContextListener:
public class MyServletContextListener implements ServletContextListener { .. }

Related

How do I get config paramerters from my web.xml in Jersey?

I have been trying to get parameters from my web.xml file from within my Jakarta JAX-RS resource. My web.xml is as follows:
<web-app>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>terrible.package.name</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/api/v1/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>max-customers-size</param-name>
<param-value>10</param-value>
</context-param>
</web-app>
In my test setup, I am running my web app with Jetty:
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
WebAppContext ctx = new WebAppContext("target/the-finished-servlet.war", "/");
server.setHandler(ctx);
server.start();
}
And I have the following user resource defined using jakarta:
#Path("user")
public class UserResource {
ServletContext context;
#Context
public void setServletContext(ServletContext context) {
this.context = context;
System.out.println("setting to: " + context);
}
#GET
#Path("/list")
#Produces(MediaType.APPLICATION_JSON)
public Response getListOfAllUsers(final #Context HttpHeaders hdrs) throws SQLException {
System.out.println(context.getInitParameter("max-customers-size"));
return Response.ok("{}").build();
}
}
The context is always null, which makes absolutely no sense. The setServletContext method is called, and the parameter is null. I've tried using #Context on a constructor parameter, I've tried it on my context field, and I've tried it in the getListOfAllUsers method. None of them work.
I just want to configure my servlet (for MySQL database path and user, in this example I'm testing with max-customers-size, which doesn't matter though, because my context is null either way). Is there an easier way to get custom config data into my servlet? I want the user of my resulting war file to be able to supply things like the database port. Why isn't ServletContext working, and if there is an easier way to make my servlet configurable, how do I do that?
Typically a database (DataSource) for Servlet is configured via JNDI (the definition exists on the server JNDI context, and the webapp JNDI context contains a hardcoded reference to the server level location)
Your server level will typically have an XML that defines the DataSource as a org.eclipse.jetty.plus.jndi.Resource against the server level context.
And your webapp's WEB-INF/web.xml contains the <resource-ref> back to that server level location.
Your code then uses the InitialContext on JNDI to access this already defined DataSource.
This has the added bonus that the datasource can be any JDBC compatible implementation, and even include complex configurations like a Connection pool implementation (eg: c3p0) in front of your JDBC DataSource.
For unit testing, you'll set it up like this ...
JNDI Lookup Failing For Embedded Jetty Server
For standard webapp deployment in a standalone Jetty container, you'll set it up like this ...
Declaring JNDI Resources

How to specify LifeCycle Listener listener class in web.xml?

I want to get notified once the server got started successfully.. For that I have added the below in the web.xml
<listener> <listener-class>com.server.container.Listeners</listener-class> </listener>
Listeners is class which implements org.apache.catalina.LifecycleListener.
Is this correct? As of now i am not getting any notification during server startup end. Do i need to do anything extra?
In J2EE, Listener notifies whenever some action (context created, destroyed, request or session attribute added, removed, etc..) happens on the server.
Please find the below sample listener code below:
ApplicationListener Class (in your project):-
package com.myproject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ApplicationListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println(" Server Starting !!!!!! ");
//Any other code you can place here
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println(" Server Shutting down !!!!!! ");
}
}
web.xml changes:
Add below code to your web.xml
<listener>
<listener-class>
com.myproject.ApplicationListener
</listener-class>
</listener>
Also, please ensure that you have got "servlet-api.jar" file in your classpath.

Spring MVC Can't configure Dispatcher Servlet right

I'm having trouble configuring the Dispatcher for Spring. What I am trying to achieve is:
Build REST WebService to receive requests
Have HTML + Ajax pages consuming the data (Therefore, I don't have Views in my Spring project)
So far I have only 2 HTML pages: Login (using j_security_check) and Main page. Both very simple. I also have a simple controller:
MainController.java
#RestController //Or #Controller and #ResponseBody, no difference, right?
public class MainController {
#RequestMapping("rest/main/data")
public String getData () {
return "{data: \"DATA HUEHUE\"}"; // Yes, I'm brazilian
}
}
And I have tried the following configuration for web.xml and dispatcher-servlet.xml:
web.xml:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
dispatcher-servlet.xml
<context:component-scan base-package="com.example.controller"/>
This doesn't work. I get the message INFO: Mapped URL path [/rest/main/data] onto handler 'mainController' but when I try to access I get No mapping found for HTTP request with URI [/myapp/rest/main/data] in DispatcherServlet with name 'dispatcher'
I also have tried:
On web.xml: <url-pattern>/</url-pattern>
On dispatcher-servlet: The same
What happened: The controller DID work but the application also tried to map my login.html and couldnt find a match so I got 404 ;-;
I'm aware of that "standard" configuration using a prefix and a sufix, but since I dont have views here I dont think that's the right approach.
I'm kinda new at Spring (as you may have noticed), so please be gentle on the answers.
Any ideas?
Thanks in advance :)
My project tree:
-project
--src
---main
----webapp
-----WEB-INF
------web.xml
------weblogic.xml
------dispatcher-servlet.xml
-----www
------main.html
-----login.html
(Login is outside www)
With the first approach if you modify the controller code to have /rest/main/data It will work.
#RestController //Or #Controller and #ResponseBody, no difference, right?
public class MainController {
#RequestMapping("/rest/main/data")
public String getData () {
return "{data: \"DATA HUEHUE\"}"; // Yes, I'm brazilian
}
}
What is happening in happening in the second approach is that since you have Spring Security configured you need to be authenticated first but for that it finds the Login.html and can not find it. This may be because of incorrect configuration.

Want to know Restlet Routing basic concepts

I am using the restlet routing APIs like
http://localhost:8080/www.example.com/hello/ping
But I don't know how to use this type of method:
/{projectName}/{wallName}
that I have seen in
Restlet routing nightmare?
Could anyone tell me
1.What is the best practice of using Restlet Routing?
2.How to implement /{projectName}/{wallName} in java?
3.How to get the value of projectName from this API?
In fact, there are several part within a Restlet application. Classically, this application is accessible through a Restlet component that can be created as described below:
Standalone mode (outside an application server)
Component component = new Component();
component.setName("My component");
component.getServers().add(Protocol.HTTP, 8182);
MyApplication application = new MyApplication();
// To attach application on /www.example.com
component.getDefaultHost().attach("www.example.com", application);
// To attach application on /
component.getDefaultHost().attachDefault(application);
component.start();
Container mode (servlet support). You can use the extension ext.servlet for this use case. A front servlet is provided that automatically wraps a component. You only have to specify the class of your application implementation, as described below:
<!-- Application class name -->
<context-param>
<param-name>org.restlet.application</param-name>
<param-value>
packageName.MyApplication
</param-value>
</context-param>
<!– Restlet adapter –>
<servlet>
<servlet-name>RestletServlet</servlet-name>
<servlet-class>
org.restlet.ext.servlet.ServerServlet
</servlet-class>
</servlet>
<!– Catch all requests –>
<servlet-mapping>
<servlet-name>RestletServlet</servlet-name>
<url-pattern>/*</url-pattern>
<!-- or -->
<!-- url-pattern>/www.example.com/*</url-pattern -->
</servlet-mapping>
You can now implement the Restlet application. For this implement, a class that extends Application. The routing must be defined within its method createInboudRoot, as described below:
public MyApplication extends Application {
#Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/{projectName}/{wallName}", MyServerResource.class);
return router;
}
}
As you can see, a server resource is attached for the path /{projectName}/{wallName}. This server resource is responsible to handle the request. A sample of implementation is described below:
public class MyServerResource extends ServerResource {
#Get
public Representation handleGet() {
String projectName = getAttribute("projectName");
String wallName = getAttribute("wallName");
(...)
}
}
Hope it helps you,
Thierry

Starting the servlet when the application startup

I want to starting by fireing the servlet class before loading a jsp page, because i need to populate some data from the database in a jsp page.
Servlet mapping in web.xml
<servlet>
<servlet-name>Index</servlet-name>
<servlet-class>com.Teklabz.Servlets.IndexServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Index</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
but it didn't work, when tracing the code it's never reach the servlet class.
Also i was trying to use ServletContextListener like this link, but I faced the same problem.
listener code:
public class ServletListener implements ServletContextListener{
#Override
public void contextInitialized(ServletContextEvent sce) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
web.xml code:
<listener>
<listener-class>com.techlabz.listener.ServletListener</listener-class>
</listener>
I don't know what am doing wrong.
There are number of ways you can achieve this ..
Either you can populate the data in service method com.Teklabz.Servlets.IndexServlet and then set the data in request attribute and then forward to that jsp.
If you want to use loadonstartiup then you can populate the data from db in com.Teklabz.Servlets.IndexServlet servlet's init method and then set it in some accessible scope(request,session,context) and by direct accessing jsp get the data from that scope.
In listener also you can do this but in that case also you need to set the data in some scope.
your code is absolutely right.you need to Add annotation #WebListener
#WebListener
public class ServletListener implements ServletContextListener{
//your code
}

Categories

Resources