Professional Documents
Culture Documents
3 JERSEY Implementaion
3 JERSEY Implementaion
1. Auto scan
5. without web.xml
|-Internal Code for without web.xml Using @ApplicationPath with Custom Application
or Custom ResourceConfig
|-Configuring the JAX-RS Runtime which will works agnostic to the Implementation
(Or)
When we are working with Glassfish Server we no need to download the JERSEY
binary distribution bcz Glass fish server by default contains all the jars.
But when we are working with other containers we need to Download JERSEY
Implementation Binary Distribution which jaxrs-ri-2.4.1 (RI means reference
Implementation also called as JERSEY Implementation) which can deployed with any
container that means agnostic to the containers.
Say Extract Here the jaxrs-ri-2.4.1.zip file then it will shows as follows.
jaxrs-ri
Copy all the jars that are there from api, ext, lib and paste in the lib directory then
start working the application.
In order to configure the JAX-RS Runtime the Sun Ms. has provided JERSEY Runtime
which is called as org.glassfish.jersey.servlet.ServletContainer which will acts
as Runtime for the RESTful services.
1. Auto scan:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
The URL that we have configured "/*" is an suspecious URL bcz if we have one more
servlet hence we need to configure "prefix" in case of RESTEasy but in case of
JERSEY we can automatically configure URL as "/rest/*" without any prefix so it
mapps and prefixes "/rest" for each and every Resource class
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
In case of RESTEasy if we configure prefix as "rest" then also it starts matching URL
from "ContextRoot" then "rest" then extra path URL (like ContextRoot/rest/courier).
But in case of JERSEY it starts matching URL direclty form the /rest but not from the
"ContextRoot" hence it quickly forwards the req to the Resource class (like
/rest/courier).
That means JERSEY Runtime (ServletContainer) will uses only extra path URI only to
map the req but
http://localhost:8080/1DTDCIntraCourierWeb/rest/courier?
source=hyd&dest=blr&weight=65
then it will not works bcz auto-scan of Resources classes cannot done automatically
hence we need to configure the auto scan of the Resources.
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.dtdc.jersey.resource.DTDCCourierResource</param-value>
</init-param>
http://localhost:8080/1.1BootStrapUsingClassNames/rest/courier?
source=hyd&dest=blr&weight=65
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.dtdc.jersey.resource</param-value>
</init-param>
It will Scans only the Resources that are there in that package only but not the sub
packages that are there in that package. SO in order to read the Resource classes
that are there in sub-packages also we need to configure using
"jersey.config.server.provider.scanning.recursive" as true
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.dtdc.jersey.resource</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.scanning.recursive</param-name>
<param-value>true</param-value>
</init-param>
The subpackages "jersey.config.server.provider.scanning.recursive" in not
mandatory it optional.
http://localhost:8080/1.2BootStrapUsingPackageNames/rest/courier?
source=hyd&dest=blr&weight=65
That means by default RESTEasy and JERSEY Runtimes makes our Resource classes
as non-singleton (prototype) hence thread safe.
@Override
return singletons;
@Override
return classes;
web.xml:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.dtdc.jersey.common.DtdcCourierApplicationConfig</param-
value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
So now we no need to override the methods rather we need to tell which classes we
wanted to make singletons and which classes wants to be non-singleton, that means
we can use ResourceConfig class to configure ServletContainer easily and we can
control the scopes in easier manner as compared to the Application class.
public DtdcCourierResourceConfig() {
packages(true, "com.dtdc.jersey.resource");
register(new DTDCCourierResource());
}
web.xml:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.dtdc.jersey.common.DtdcCourierResourceConfig</param-
value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Internal code:
//It will gegisters the classes which are singleton and which are prototypes
http://localhost:8080/3BootStrapUsingControlScopesUsingResourceConfig/
rest/courier?source=hyd&dest=blr&weight=65
The purpose this mechanism is without knowing the Implementation Runtime class
we can configure the Runtime
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
http://localhost:8080/4.1BootStrapUsingServletPluggabilityMechanism/
rest/courier?source=hyd&dest=blr&weight=65
Here we are creating our class using Resource but we are configuring in web.xml as
Application class only rather than bcz ResourceConfig is sub class of Application
hence it can detected by JAX-RS JERSEY easily. But if we configure ResourceConfig
it will not detects.
public DtdcCourierApplication() {
singletons.add(new DTDCCourierResource());
@Override
return singletons;
<servlet>
<servlet-name>com.dtdc.jersey.common.DtdcCourierApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.dtdc.jersey.common.DtdcCourierApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
http://localhost:8080/4.2.1BootStrapUsingServletPluggabilityUsingCustomApplicatio
n/rest/courier?source=hyd&dest=blr&weight=65
public DtdcCourierResourceConfig() {
packages(true, "com.dtdc.jersey.resource");
register(new DTDCCourierResource());
<servlet>
<servlet-name>com.dtdc.jersey.common.DtdcCourierResourceConfig</servlet-
name>
</servlet>
<servlet-mapping>
<servlet-name>com.dtdc.jersey.common.DtdcCourierResourceConfig</servlet-
name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Access the application with multiple req's as
http://localhost:8080/4.2.2BootStrapUsingServletPluggabilityUsingCustomResourceC
onfig/rest/courier?source=hyd&dest=blr&weight=65
5. without web.xml:
@ApplicationPath("/rest/*")
public DtdcCourierApplication() {
singletons.add(new DTDCCourierResource());
@Override
return singletons;
http://localhost:8080/5.1BootStrapWithoutWebXmlUsingCustomApplication/
rest/courier?source=hyd&dest=blr&weight=65
public DtdcCourierResourceConfig() {
packages("com.dtdc.jersey.resource");
register(new DTDCCourierResource());
http://localhost:8080/5.2BootStrapWithoutWebXmlUsingCustomResourceConfig/
rest/courier?source=hyd&dest=blr&weight=65
ServletContainerInitializer {
ServletContext servletContext) {
// It looks for the Application class so control goes to our Custom Application
ServletContainer(JERSEY Runtime)
// Then gets all this data from the Custom Application class and
@ApplicationPath
and creates the ResourceConfig obj and places with in the resourceConfig and
then gets the servletContext obj and places with in the resourceConfig now all
ResourceConfig resourceConfig=
ResourceConfig.add(getContextParams(servletContext));
} else {
// It looks for the Application class but it is absract hence it looks for the
Custom Application class but it is not there hence it will looks for the default
class constructor will be called (bcz we extends from the ResourceConfig) and
inputs that we passed and then it gets the URL from the
obj will be created with all the requied data and it passes servletContext obj to
the ResourceConfig obj so that now all the meta data is available with
}
Configuring the JAX-RS Runtime which will works agnostic to the
Implementation:
(Or)
Runtime will takes the req identifies the incoming URL with Resource class URL
which is annotated with @Path and forwards the req to that Resource class.
For every req it will not goes to the application classes rather it will reads all the
Resource classes at one single shot and places as Resource Meta data. Every
Runtime will maintains not only Resource Meta data in addition to this it maintains
Once req comes to the Runtime then it goes to the meta data and identifies the
corresponding Resource class using URL and calls the corresponding method based
on the incoming req method type and calls the method with input data and then
business method performs the logic and returns the res based on the
@Produces("text/palin") now Runtime will dispatches the resp by using
res.getWriter();
Instead of paying the money through the credit card by every time providing the
credit card details to the every e-commerce site we can use Oxygen Wallet which
hides the credit card details to the other web sites bcz initially we add the money to
the Oxygen Wallet so that we can order any items from any web sites bcz Oxygen
ECash Wallet will provides the business through the web services or RESTful services
to the e-commerce web sites so that credit card details will be hidden from the e-
commerce web sites bcz transaction will done from the Oxygen Wallet to the e-
commerce sites so that confidential data will be hidden from the each and every web
site and advantage is with one Oxygen Wallet we contribute to any web site.
Jbong, Snapdeal, flipkart, paytm etc will talks to the OxygenWallet that has provided
by the Oxygen via web services or RESTful services (without giving the DB details of
the end-users) so that end-user can order the items without giving the confidential
to eacha and every site bcz end-user will maintains the cash in the OxygenWallet so
that end-user will pays via OxygenWallet irrespective of the e-commerce.
@Path("/oxygen-ecash")
public OxygenECashAgent() {
}
@GET
@Produces(MediaType.TEXT_PLAIN)
@POST
return wallet;
@PUT
@DELETE
Note:
We cannot send the obj of data through the query Params hence will pass the data
in the req body but if we send the data in the form Serializable bits then it not
becomes interoperable hence we will send the data in the xml format which makes
interoperable and here we can send any data format but in case of Web services we
cannot send any format apart from the xml.
Hence we cannot send directly xml hence we need to use DOM/SAX parsing to
convert into obj.
@Path("/oxygen-ecash")
public OxygenECashAgent() {
@GET
@Produces(MediaType.TEXT_PLAIN)
return 0.0f;
@POST
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
user = buildUser(in);
/*
/*
* We can return sub class ref for super class type that means
* are returning obj of sub class so it takes this returned obj and on
*/
return walletStreamingOutput;
@PUT
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
addMoney = buildAddMoney(in);
/*
*/
@DELETE
@Produces(MediaType.APPLICATION_XML)
/*
*/
/*
Helper or Parsing methods which are used to build business obj for
Resource methods
*/
return user;
return addMoney;
/*
*/
// converting User obj to xml
return buffer.toString();
return buffer.toString();
/*
Making the contract with JAX-RS Runtime so that output will be displayed
JAX-RS in-turn gives data to the JEE-Container which will displays the
*/
this.data = data;
// This method will be called by the JAX-RS Runtime after receiving the
@Override
writer.print(data);
writer.close();
out.close();
No, Bcz @Consume is used to recive the data by the Resource class in which format
the end-user has over the req. In case of GET will cannot send the data over the
body bcz for GET req req body will not be there hence we can send the data through
the Query param or req headers but we cannot send the xml format data over the
body for the GET hence we will not write the @Consume("application/xml") or
@Consume("text/palin") for GET req bcz we not sending the over the body hence
our Resource class cannot consumes the data in the form of xml or text rather it will
accepts in the form of Query params or using headers hence we should not write
@Consume on top of the GET req.
Note:
For DELETE we send the data over req body as well but here in this use case not
required that is the reason we didn't written @Consume, if we want we send xml
data over the req body then we can write for that also @Consume.
InputStream:
The JAX-RS Runtime wraps the req data and populates into the InputStream as
String data if it is not a primitive data types.
StreamingOutput:
The JAX-RS runtime will takes the resonse in the form of StreamingOutput hence we
need to return in the form of StreamingOutput obj. So now JAX-RS will takes the
StreamingOutput obj whichis in the form String now it displays in the proper way as
xml format bcz we specified as @Produces(“application/xml”) or
@Produces(MediaType.APPLICATION_XML). If we didn’t specify the @Produces then
it will displays as String xml but in the formatted xml.
AutomicInteger:
Step: 1
http://localhost:8080/7OxygenWeb/resources/oxygen-ecash
Step: 2
Select POST then click on the Form and in the Form give as follows
Content-Type as = application/xml
Step: 3
Then below this one more option is there to send the data as xml so click on Raw
then write the xml as follows without any spaces
Response:
<wallet><walletID>2</walletID><user><username>db</username><mobile>223
2665</mobile><email>dbr@</email></user><balance>0.0</balance><status>A
ctive</status></wallet>
Note:
JAX-RS will takes the StreamingOutput obj which is in the form String now it
displays in the proper way as xml format bcz we specified as
@Produces(“application/xml”) or @Produces(MediaType.APPLICATION_XML). If we
didn’t specify the @Produces then it will displays as String xml but in the formatted
xml.
2 PUT:
Send the req with same Wallet Id that we have created so that we can add the
amount to that wallet.
</fromAccount><amount>9000</amount></addMoney>
Response:
<wallet><walletID>2</walletID><user><username>DB Reddy
</username><mobile>2232</mobile><email>dbr@</email></user><balance>90
00.0</balance><status>Active</status></wallet>
3 GET:
Send the req with GET req and walletID as same as we added the money
http://localhost:8080/7OxygenWeb/resources/oxygen-ecash?walletID=2
Response:
9000.0
4 DELETE:
http://localhost:8080/7OxygenWeb/resources/oxygen-ecash?walletID=2
Response:
<settlement><walletID>2</walletID><username>DB
Reddy</username><balance>9000.0</balance><status>Your Wallet has been
successfully De-Acivated</status></settlement>
5 GET:
Try to send again the req to check whether the account has been de-activated or not
http://localhost:8080/7OxygenWeb/resources/oxygen-ecash?walletID=2
Reponse: