I am trying to get working a simple JAX RS example, but I am failing to do so.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>PLAYGROUND</display-name>
<servlet-mapping>
<servlet-name>playground.Rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
Rest.java
package playground;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
public class Rest extends Application {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
Accessing http://localhost/{warcontext}/api/hello with the browser (GET) gives me 404 error status
It is probably something very silly but I can't figure out.
Using:
JBoss EAP 6.1.0 (Java EE 6)
web.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>javax.ws.rs.core.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Rest.java
public class Rest {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
If you need, you can add
YourApplication.java
package playground;
import javax.ws.rs.core.Application;
...
public class YourApplication extends Application {
#Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> yourResources = new HashSet<Class<?>>();
yourResources.add(InvoiceResource.class);
return yourResources;
}
}
Then
web.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>playground.YourApplication</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
If you add #ApplicationPath("/api") for YouApplication, then web.xml shouldn't have servlet-mapping.
You need to extend javax.ws.rs.core.Application (it can remain empty) and annotate it with #ApplicationPath("/ide"), then create a JAX-RS resource, ie, a class with an #Path("/hello") annotation. In this class, you'll just need to have your JAX-RS Resource Method annotated with #GET.
#ApplicationPath("/ide")
public class Rest extends Application { }
#Path("/hello")
public class HelloResource {
#GET
#Path("hello")
public String helloworld() {
return "Hello World!";
}
}
You can also take a look at this example: https://github.com/resteasy/Resteasy/tree/master/jaxrs/examples/oreilly-workbook/ex03_1
You need to declare servlet-class in web.xml (servlet name is not the same):
<servlet>
<servlet-name>Playground REST services</servlet-name>
<servlet-class>your.package.playground.Rest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Playground REST services</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Use the full name of your class (including package path name) in servlet-class.
I also had issues getting this to work, so I'm posting a more complete how-to for posterity:
If you're using a standard Tomcat install (or some other servlet container), AFAIK you can't avoid explicitly telling it what servlets to start in the web.xml file*. Since you have to use web.xml anyway, the simplest way to get restful web services working is to forget extending javax.ws.rs.core.Application entirely and just specify the context path there. You can still use standard jax-rs annotations to declare the actual web services.
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
>
<servlet>
<servlet-name>rest-test</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.domain.mypackage</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> rest-test</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Two noteworthy points:
You will need to bundle a REST implementation in your WAR file, since servlet containers don't usually contain one. Since Jersey is the reference implementation for JAX-RS, that's the one I'm using in the servlet-class element above. You can replace this with Apache CXF implementation if you want.
The init-param element tells Jersey which of your packages to search for Java files with web service annotations. Edit this to point to your web services. Note that if you opt to use apache CXF instead of Jersey, the stuff needed in any init-param elements will be different. Someone who knows CXF please post what they would be.
If you're using Maven, just add a dependency to jersey-servlet in the dependencies section of your pom.xml file:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.2</version>
</dependency>
...
</dependencies>
After this, declaring your web services is straight forward using the standard JAX-RS annotations in your Java classes:
package com.domain.mypackage;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
// It's good practice to include a version number in the path so you can have
// multiple versions deployed at once. That way consumers don't need to upgrade
// right away if things are working for them.
#Path("calc/1.0")
public class CalculatorV1_0 {
#GET
#Consumes("text/plain")
#Produces("text/plain")
#Path("addTwoNumbers")
public String add(#MatrixParam("firstNumber") int n1, #MatrixParam("secondNumber") int n2) {
return String.valueOf(n1 + n2);
}
}
This should be all you need. If your Tomcat install is running locally on port 8080 and you deploy your WAR file to the context myContext, going to
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
...should produce the expected result (5).
Cheers!
* Someone please correct me if you know of a way to a add the Jersey servlet to the context in Tomcat without using web.xml--maybe by using a context or life cycle listener?
Related
I have a maven project that has no code, it just imports 3 projects. Two of them define their servlets in a web.xml, so in this project, I import all classes and define only the servlets I need this way
<web-app>
<servlet>...</servlet>
<servlet-mapping>...</servlet-mapping>
</web-app>
And this works. The third project to import works when run standalone, but I fail to import it and I ask for your help. Its source code is anotated with JAX-RS like:
package org.acme.rest;
#Path("search")
public class MySearch {
#GET
#Path("/{type}/{text}")
#Produces("application/json; charset=UTF-8")
public MyResponse typedSearch(#PathParam("type") String type, #PathParam("text") String text) {
/**/
}
}
This class MySearch has a method that defines an endpoint with parameters. The class is registered in the app class like:
package org.acme.util;
import org.acme.rest;
#ApplicationPath("")
public class SearchApp extends ResourceConfig {
public SearchApp (#Context ServletContext servletContext) {
try {
/* ... */
register(MySearch.class);
/* ... */
} catch (/* ... */){/* ... */}
}
Because of logging, I know that the SearchApp servlet is initiated, and that register() is called. However, the endpoint is not loaded, as I receive only a 404. I don't see any hint on why the endpoint may be ignored.
See my web.xml for reference:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="4.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns="https://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee
https://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">
<display-name>Archetype Created Web Application</display-name>
<!-- some servlet from project 1 -->
<servlet>...</servlet>
<servlet-mapping>...</servlet-mapping>
<!-- some servlet from project 2 -->
<servlet>...</servlet>
<servlet-mapping>...</servlet-mapping>
<!-- special servlet for project 3 -->
<servlet>
<servlet-name>Suggest</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.acme.util</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Search</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
I expect to receive a response from typedSearch method by querying /api/search/sometype/sometext. But it's not working.
I am using
Tomcat 9
Java 1.8
Jersey 2.14. I've tried also 2.38 with same result.
Eclipse 2022-03 (4.23.0)
Can you think of something that can be going wrong? Or how to debug it?
I suspect that register() is silently ignoring the endpoint class for some reason, but I can't tell why.
Thank you!
I'm trying to create and deploy a RESTful Web Service using JAX-RS and deploy it to tomcat. I don't want to use any IDE.
In Tomcat I have the following directory structure inside webapps\
notifire\WEB-INF\
|
---> web.xml
|
---> \classes/Notifier.class
|
---> \lib\javax.ws.rs-api-2.0
my web.xml contains:
<servlet>
<servlet-name>Web Service Servlet</servlet-name>
<servlet-class>javax.ws.rs.core.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Web Service Servlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
and the class file Notifier.class was compiled from the file Notifier.java.
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
#Path("notifier")
public class Notifier {
#Context
private UriInfo context;
#GET
#Produces("text/html")
public String getHTML() {
return "<p></p>";
}
}
When I try to access the Web Service at http://localhost:8080/notifire/webservice/notifier I get the following error:
--type Exception report
--message Class javax.ws.rs.core.Application is not a Servlet
--description The server encountered an internal error that prevented it from fulfilling this request.
Any help is appreciated.
You have the wrong class for your Servlet. Not sure why you are not wanting to use an IDE, but there is a maven archetype that will layout your project structure for you using the appropriate classes that the Jersey developers have defined. My web.xml looks like this:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.pluralsight</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
I cover all of this in this course here.
I had trouble getting this to work as well. Since you have to use web.xml anyway, the simplest way to get restful web services working is to forget extending javax.ws.rs.core.Application entirely and just specify the context path there. You can still use standard jax-rs annotations to declare the actual web services.
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
>
<servlet>
<servlet-name>rest-test</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.domain.mypackage</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> rest-test</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Two noteworthy points:
You will need to bundle a REST implementation in your WAR file, since servlet containers don't usually contain one. Since Jersey is the reference implementation for JAX-RS, that's the one I'm using in the servlet-class element above. You can replace this with Apache CXF implementation if you want.
The init-param element tells Jersey which of your packages to search for Java files with web service annotations. Edit this to point to your web services. Note that if you opt to use apache CXF instead of Jersey, the stuff needed in any init-param elements will be different. Someone who knows CXF please post what they would be.
If you're using Maven, just add a dependency to jersey-servlet in the dependencies section of your pom.xml file:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.2</version>
</dependency>
...
</dependencies>
After this, declaring your web services is straight forward using the standard JAX-RS annotations in your Java classes:
package com.domain.mypackage;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
// It's good practice to include a version number in the path so you can have
// multiple versions deployed at once. That way consumers don't need to upgrade
// right away if things are working for them.
#Path("calc/1.0")
public class CalculatorV1_0 {
#GET
#Consumes("text/plain")
#Produces("text/plain")
#Path("addTwoNumbers")
public String add(#MatrixParam("firstNumber") int n1, #MatrixParam("secondNumber") int n2) {
return String.valueOf(n1 + n2);
}
}
This should be all you need. If your Tomcat install is running locally on port 8080 and you deploy your WAR file to the context myContext, going to
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
...should produce the expected result (5).
Cheers!
* Someone please correct me if you know of a way to a add the Jersey servlet to the context in Tomcat without using web.xml--maybe by using a context or life cycle listener?
I wrote a very simple example using Jersey.
I downloaded the latest jar files from the jersey website into lib folder in WEB-INF.
My class and web.xml are below.
When I provide URL localhost:8080/SimpleJersey/rest/test I get 404 error (not found).
However when I use Maven, it works.
I use Eclipse Kepler, Glassfish 4 server and Java 7.
What am I doing wrong in the non-Maven version?
Thanks.
Class:
package com.simplejersey;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/test")
public class MyResources
{
#GET
#Produces("text/plain")
public String getIt()
{
return "Hello there!";
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SimpleJersey</display-name>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.simplejersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
I found the solution in this post by Michal Gajdos: Jersey REST Web Service, Tomcat, Eclipse and 404's
The issue is (quoting from the abovementioned post):
Jersey 2.0 does not recognize init-param with name com.sun.jersey.config.property.packages (web.xml). Try to change it to jersey.config.server.provider.packages as described in ServerProperties.PROVIDER_PACKAGES (link)."
Be carefeul when you copy web.xml from websites that show older solutions or versions (like I did). Jersey is being updated too...
I am testing a very simple REST server with Jersey and Servlet 3.0 implementation on Tomcat 7.0. I have programmed a simple PoJo:
package toplevel;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/pojo")
public class PoJo {
#GET
#Produces("text/plain")
public String hello() {
return "Hello, World";
}
}
I have put the following in the WEB-INF/web.xml file (running on Servlet 3.0):
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>RestTest</display-name>
<servlet>
<servlet-name>toplevel.PoJo</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>toplevel.PoJo</servlet-name>
<url-pattern>/pojo</url-pattern>
</servlet-mapping>
</web-app>
When I deploy, I get a HTTP Status 500 response. This seems to me that the webserver is recognizing that something should be served from /pojo, but that the corresponding class PoJo is not found. The jersey specific jars (version 1.17) are in the WEB-INF/lib dir:
activation-1.1.1.jar jersey-client-1.17.jar junit-4.9.jar
asm-3.3.1.jar jersey-core-1.17.jar persistence-api-1.0.2.jar
jaxb-api-2.2.4.jar jersey-server-1.17.jar stax-api-1.0-2.jar
jaxb-impl-2.2.4-1.jar jsr311-api-1.1.1.jar
Does anyone recognize this ?
You need to tell Jersey where to find your REST resource. Your web.xml should look something like this:
<servlet>
<servlet-name>Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>toplevel</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Adding jersey-servlet:1.17.jar took care of that problem for me.
I am working on project to upgrade my existing web application which is developed in JAX-RS 1.12 and running in tomcat 7. Now I am upgrading it to JAX-RS2.0. During tomcat server startup my resources are not getting loaded ?
Below are the details.
Added below jars for JAX-RS 2.0
jersey-client-2.0-m07-1
jersey-common-2.0-m07-1
jersey-container-servlet-2.0-m07-1
jersey-container-servlet-core-2.0-m07-1
jersey-server-2.0-m07-1
javax.ws.rs-api-2.0-m10
osgi-resource-locator-1.0.1
javax.inject-2.1.28
javax.inject-1
hk2-utils-2.1.28
hk2-locator-2.1.28
hk2-api-2.1.28
guava-13.0
cglib-2.1.28
asm-all-repackaged-2.1.28
In Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>ConfigLiteJersey2</display-name>
<!-- Jersey Servlet to Support JAXRS Services -->
<servlet>
<servlet-name>ConfigLiteServices</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.core.Application</param-name>
<param-value>com.cisco.config.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ConfigLiteServices</servlet-name>
<url-pattern>/config/*</url-pattern>
</servlet-mapping>
My Resource File
#Path("/configset")
public class ConfigSetResource {
#POST
#Path("/id{configsetid: (/[^/]+?)?}")
#Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public ConfigSetResponse getConfigSet(#PathParam("configsetid") String sConfigSetId) throws Exception {
//Code
}
}
Trying to access my resource API using below URL
ipaddress:8080/ConfigLiteJersey2/config/configset/id
Getting HTTP status 404 Not found.
Looks like I am not giving right servletclass mapping in web.xml. Please share your thoughts on this
If you want Jersey to scan your package for resources, change your param-name to:
<param-name>jersey.config.server.provider.packages</param-name>
I am using Jersey 2.15, and below is working configuration:
<servlet>
<servlet-name>emper</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.le.config.ResourceConfiguration</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.le.exceptions</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>emper</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet>
Great thing that I came to know was, we can register provider class like Global Exception handler. hence com.le.exceptions contain my provider class which implements ExceptionMapper provided by Jersey.
Another thing, We need to create a subclass of org.glassfish.jersey.server.ResourceConfig and register it as our jax-rs application.
If you are using Servlet version 3.0 I would suggest following the example in the jersey manual here: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.3.descriptor
Create a class that implements javax.ws.rs.core.Application, say org.foo.rest.ConfigLiteApplication. Then make your web.xml like the following (adapted from the jersey page slightly to match your example):
<web-app>
<servlet>
<servlet-name>org.foo.rest.ConfigLiteApplication</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>org.foo.rest.ConfigLiteApplication</servlet-name>
<url-pattern>/config/*</url-pattern>
</servlet-mapping>
</web-app>
This should work on both JAX-RS 1.1 and JAX-RS 2.0, and should be neutral to the jersey version as you never need to name any jersey classes. The ConfigLiteApplication class should load the resources you want to include, for example adapted from http://tomee.apache.org/examples-trunk/rest-example-with-application/README.html:
#ApplicationPath("/config")
public class ConfigLiteApplication extends Application {
public Set<Class<?>> getClasses() {
return new HashSet<Class<?>>(Arrays.asList(ConfigSetResource.class));
}
}
A modern IDE will likely be able to manage this class for you.
Also, if I were you I would be careful to check this regular expression match if you are hoping to match on /id
#Path("/id{configsetid: (/[^/]+?)?}")
I would consider splitting this up into multiple functions or otherwise working to try and avoid this kind of regex. For example
#POST
#Path("/id")
public ConfigSetResponse getConfigSet() {
return this.getConfigSet(null);
}
#POST
#Path("/id/{configsetid}")
public ConfigSetResponse getConfigSet(#PathParam("configsetid") String sConfigSetId) {
//Code
}
After long Google search, I Configured mine this way and it worked perfectly
build.gradle should be something like this
compile 'log4j:log4j:1.2.7'
compile 'org.slf4j:slf4j-log4j12:1.6.6'
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.6'
ApplicationConfig.java file should be something like this
#ApplicationPath("/app")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
packages("com.flexisaf.resources");
}
}
Your web.xml file should be something like this
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<!-- Default page to serve -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<display-name>SAFHRMS</display-name>
<servlet>
<servlet-name>com.flexisaf.safhrms.client.config.ApplicationConfig</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>com.flexisaf.safhrms.client.config.ApplicationConfig</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>safhrms.jsp</welcome-file>
</welcome-file-list>
</web-app>
This solves my problems..Thanks