Starting the servlet when the application startup - java

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
}

Related

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.

Java GWT server programming handling GET/POST requests

I am new to java programming in the web environment and am having trouble understanding the flow.
For an assignment coming up I need to build a web application accessible with an API via get/post requests. For the tutorials that I have followed here is the flow I understand.
User visits top domain->
Per configuration user is directed to a jsp page->
Jsp contains javascrip and html. To access server code (for database, computations and other processes) the jsp page can use RCP to make async requests to a java servlet->
Java servlet does server handling and returns response to jsp page
Is this the required flow or can a user directly acess a servlet, and can that servlet handle get/post, or do I have to handle at the jsp and foward to the servlet?
Servlets can be accessed directly. You just need to extend HttpServlet and implement doGet and/or doPost. For example:
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
Integer param = null;
try {
param = Integer.parseInt(req.getParameter("param"));
}
catch(NumberFormatException e) {
}
}
}
You also need to map your servlet to url in web.xml:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.adam.test.server.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/my_servlet</url-pattern>
</servlet-mapping>
Now you can access your servlet using url like this:
http://domain.com/my_servlet?param=123

Jersey ContainerRequestFilter: Getting 404 after throwing 'abortWith' with status forbidden (403)

Jersey 2.22 API with token authentication + role based authorization (the way I secured the API is based on the accepted answer from this post: Best practice for REST token-based authentication with JAX-RS and Jersey . It might be better to read it before trying to understand my question) :
here is my web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- LISTENERS -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>JerseySpringServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ca.toto.api.filters</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ca.toto.api.restapi</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>ca.toto.api.filters.AuthenticationFilter;ca.toto.api.filters.AuthorizationFilter;com.toto.api.restapi.TaskRestService</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseySpringServlet</servlet-name>
<url-pattern>/filters/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JerseySpringServlet</servlet-name>
<url-pattern>/restapi/*</url-pattern>
</servlet-mapping>
When I make a call to my tasks web service, the flow goes in the first filter (AuthenticationFilter) without any problem (#Priority(Priorities.AUTHENTICATION)), validates my token, gets the user from the decoded token then registers it as the Principal then passes in the second filter, AuthorizationFilter (#Priority(Priorities.AUTHORIZATION)) where I get the user from the security context, get his role then check if he has permission to make the call. If yes, exit the filter normally if no, use javax.ws.rs.container.ContainerRequestContext.abortWith method to send a response with status 403:
#Secured
#Provider
#Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {
...
try {
boolean isAllowed = false;
// Check if the user is allowed to execute the method
// The method annotations override the class annotations
if (methodRoles.isEmpty()) {
logger.info("Checking permissions on CLASS level");
isAllowed = checkPermissions(classRoles);
} else {
logger.info("Checking permissions on METHOD level");
isAllowed = checkPermissions(methodRoles);
}
// Throw an Exception if the user has not permission to execute the method
if(isAllowed == false) {
logger.warn("USER IS NOT ALLOWED TO COMPLETE THE REQUEST. ABORT.");
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
} catch (Exception e) {
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
When the user has the right role, the service is called and I get the correct response with correct info.
My problem is that when my variable isAllowed equals to false, I get a 404 instead of a 403 and I can't figure out why...
here is my TaskRestService service definition:
#Path("/tasks")
#Secured({RoleEnum.admin})
public class TaskRestService {
...
#GET
#Produces(MediaType.APPLICATION_JSON)
#Transactional(readOnly = true)
public List<Task> getTasks(#QueryParam("code") String code) {
... }
You should set this Jersey init-param jersey.config.server.response.setStatusOverSendError to true. Here's what it states in the Javadoc
Whenever response status is 4xx or 5xx it is possible to choose between sendError or setStatus on container specific Response implementation. E.g. on servlet container Jersey can call HttpServletResponse.setStatus(...) or HttpServletResponse.sendError(...).
Calling sendError(...) method usually resets entity, response headers and provide error page for specified status code (e.g. servlet error-page configuration). However if you want to post-process response (e.g. by servlet filter) the only way to do it is calling setStatus(...) on container Response object.
If property value is true the method Response.setStatus(...) is used over default Response.sendError(...).
Type of the property value is boolean. The default value is false.
So what happens is the error cause the container to try and send you to an error page, and when there is non configured, you get a 404. So when you set the property to true, it cause the use of setStatus rather then sendError
NOTE: If you are not using a web.xml, for a ResourceConfig, you can use the property(property, value) method. For an Application subclass, you can override Map<String, Object> getProperties()
public class MyApp extends ResourceConfig {
public MyApp() {
property(ServletProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, true);
}
}
public class MyApp extends Application {
#Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<>();
props.put("jersey.config.server.response.setStatusOverSendError", true);
return props;
}
}

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.

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

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 { .. }

Categories

Resources