Академический Документы
Профессиональный Документы
Культура Документы
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&w
eight=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.
<init-param>
<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>
http://localhost:8080/1.2BootStrapUsingPackageNames/rest/courier?source=hyd&d
est=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 if we write our application class extending from Application class then we need
to override the methods but if we write our ResourceConfig class extending from
ResourceConfig then easily bootstrap the Runtime and we can control the scope of our
classes easily.
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>
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>
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
@ApplicationPath("/rest/*")
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
ResourceConfig constructor and it will calls the packages(-,-) with method param
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
ResourceConfig
resourceConfig=ResourceConfig.add(getContextParams(servletContext));
}
Configuring the JAX-RS Runtime which will works agnostic to the
Implementation:
(Or)
The Best Bootstrapping is 5-a) without web.xml Using @ApplicationPath with Custom
Application class which can works with Agnostic to the Implementation vendor and its
diagram is shown in below figure.
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.
If it primitive data types then it automatically converts into that corresponding 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:
1 POST req:
Open the ARC Cleint
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: