Posted by
arungupta on November 25, 2008 at 6:39 AM PST
cellspacing="2">
href="http://jersey.dev.java.net">
style="border: 0px solid ; width: 64px; height: 52px;" alt=""
src="https://jersey.dev.java.net/images/Jersey_yellow.png"> |
Jersey
is the open source, production quality,
href="https://jsr311.dev.java.net/nonav/releases/1.0/index.html">JAX-RS
(JSR 311) Reference Implementation for building RESTful Web services in
the GlassFish
community. It also provides an
href="https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0/api/jersey/index.html">API
that allows developers to extend Jersey to suite their requirements. |
This Tip
style="font-weight: bold;">Of
style="font-weight: bold;">The
style="font-weight: bold;">Day (TOTD) shows how
to create a simple RESTful Web service using Jersey and run it using
embeddable GlassFish (glassfish:run). Maven is used to create and run
the application. It also shows how the output format can be easily
coverted from Text to JSON.
Lets get started!
- Create a simple web app using Maven as:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
~/samples/jersey >
style="font-weight: bold;">mvn archetype:generate
-DarchetypeCatalog=http://download.java.net/maven/2
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO]
------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:generate]
(aggregator-style)
[INFO]
------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class =>
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound =>
'false'.
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> jersey-quickstart-grizzly (Archetype for creating a
RESTful web application with Jersey and Grizzly)
2: remote -> jersey-quickstart-webapp (Archetype for creating a
Jersey based RESTful web application WAR packaging)
Choose a number: (1/2): 2
[INFO]
snapshot
com.sun.jersey.archetypes:jersey-quickstart-webapp:1.0.1-SNAPSHOT:
checking for updates from jersey-quickstart-webapp-repo
Define value for groupId: : org.glassfish.samples
Define value for artifactId: : helloworld-webapp
Define value for version: 1.0-SNAPSHOT: :
Define value for package: : org.glassfish.samples
Confirm properties configuration:
groupId: org.glassfish.samples
artifactId: helloworld-webapp
version: 1.0-SNAPSHOT
package: org.glassfish.samples
Y: :
[INFO]
----------------------------------------------------------------------------
[INFO] Using following parameters for creating OldArchetype:
jersey-quickstart-webapp:1.0.1-SNAPSHOT
[INFO]
----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.glassfish.samples
[INFO] Parameter: packageName, Value: org.glassfish.samples
[INFO] Parameter: package, Value: org.glassfish.samples
[INFO] Parameter: artifactId, Value: helloworld-webapp
[INFO] Parameter: basedir, Value: /Users/arungupta/samples/jersey
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] ********************* End of debug info from resources from
generated POM ***********************
[INFO] OldArchetype created in dir:
/Users/arungupta/samples/jersey/helloworld-webapp
[INFO]
------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
------------------------------------------------------------------------
[INFO] Total time: 21 seconds
[INFO] Finished at: Mon Nov 24 14:09:27 PST 2008
[INFO] Final Memory: 12M/30M
[INFO]
------------------------------------------------------------------------ |
- Edit the generated "pom.xml" to add dependencies on
GlassFish plugin
- Add the following plugin in the "pom.xml" under
<build>/<plugins>:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
<plugin>
<groupId>org.glassfish</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
</plugin> |
- Add the following plugin repositories:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
<pluginRepositories>
<pluginRepository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</pluginRepository>
<pluginRepository>
<id>maven-repository.dev.java.net</id>
<name>Java.net Maven 1 Repository
(legacy)</name>
<url>http://download.java.net/maven/1</url>
<layout>legacy</layout>
</pluginRepository>
</pluginRepositories> |
- Optionally, if the generated dependencies in "pom.xml" as
shown below:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
<dependency>
<groupId>org.glassfish.distributions</groupId>
<artifactId>web-all</artifactId>
<version>10.0-build-20080430</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.embedded</groupId>
<artifactId>gf-embedded-api</artifactId>
<version>1.0-alpha-4</version>
<scope>test</scope>
</dependency> |
are changed to:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
<dependency>
<groupId>org.glassfish.distributions</groupId>
<artifactId>web-all</artifactId>
<version>10.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.embedded</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.0-Prelude-SNAPSHOT</version>
</dependency> |
then the latest version of
href="http://embedded-glassfish.dev.java.net/">Embedded
GlassFish APIs are used.
- Also optionally, if you want to run against Jersey 1.0
bits
then change the following property from "1.0.1-SNAPSHOT" to "1.0".
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
<properties>
<jersey-version>1.0</jersey-version>
</properties> |
- Run the application
- The generated source code is:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
package org.glassfish.samples;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
// The Java class will be hosted at the URI path "/helloworld"
@Path("/myresource")
public class MyResource {
// The Java method will process HTTP GET
requests
@GET
// The Java method will produce content
identified by the MIME Media
// type "text/plain"
@Produces("text/plain")
public String getIt() {
return "Hi there!";
}
} |
Invoking "mvn glassfish:run" starts the embedded GlassFish and shows
the following output:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
~/samples/jersey/helloworld-webapp >
style="font-weight: bold;">mvn glassfish:run
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'glassfish'.
[INFO]
------------------------------------------------------------------------
[INFO] Building helloworld-webapp Jersey Webapp
[INFO] task-segment: [glassfish:run]
[INFO]
------------------------------------------------------------------------
[INFO] Preparing glassfish:run
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to
/Users/arungupta/samples/jersey/helloworld-webapp/target/classes
[INFO] [glassfish:run]
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: HK2 initialized in 229 ms
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: com.sun.enterprise.naming.impl.ServicesHookup@2470b02c Init done
in 237 ms
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: com.sun.enterprise.v3.server.Globals@13b3d787 Init done in 239 ms
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: com.sun.enterprise.v3.server.SystemTasks@61bedd7d Init done in
244 ms
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: com.sun.enterprise.v3.services.impl.HouseKeeper@2b9f7952 Init
done in 245 ms
Nov 24, 2008 2:36:05 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO:
com.sun.enterprise.v3.services.impl.CmdLineParamProcessor@5249d560 Init
done in 248 ms
JMXMP connector server URL = service:jmx:jmxmp://localhost:8888
Nov 24, 2008 2:36:05 PM
com.sun.enterprise.v3.services.impl.GrizzlyProxy start
INFO: Listening on port 8080
Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: com.sun.enterprise.v3.services.impl.GrizzlyService@1baa56a2
startup done in 551 ms
Nov 24, 2008 2:36:06 PM
com.sun.enterprise.v3.services.impl.ApplicationLoaderService
postConstruct
INFO: loader service postConstruct started at 1227566166208
Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: Application Loader startup done in 740 ms
Nov 24, 2008 2:36:06 PM com.sun.enterprise.v3.server.AppServerStartup
run
INFO: Glassfish v3 started in 740 ms
Nov 24, 2008 2:36:07 PM com.sun.enterprise.web.WebModuleContextConfig
authenticatorConfig
SEVERE: webModuleContextConfig.missingRealm
Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig
init
INFO: Scanning for root resource and provider classes in the packages:
org.glassfish.samples
Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig
init
INFO: Root resource classes found:
class org.glassfish.samples.MyResource
Nov 24, 2008 2:36:07 PM com.sun.jersey.api.core.PackagesResourceConfig
init
INFO: Provider classes found:
Hit ENTER for redeploy |
Notice how GlassFish v3 starts up in sub-second (740 ms in this case).
- "http://localhost:8080/helloworld-webapp" shows the
following output:
alt=""
src="http://blogs.sun.com/arungupta/resource/images/jersey10-helloworld-webapp-default-output.png">
- Clicking on "Jersey resource" redirects to
"http://localhost:8080/helloworld-webapp/webresources/myresource" and
shows the following output:
alt=""
src="http://blogs.sun.com/arungupta/resource/images/jersey10-helloworld-webapp-text-output.png">
- Change the output representation to produce JSON
representation
- Add a new JAXB bean:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
package org.glassfish.samples;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author arungupta
*/
@XmlRootElement
public class Greeting {
public String greeting;
public Greeting() { }
public Greeting(String greeting) {
this.greeting = greeting;
}
} |
- Change the method implementation in MyResource as:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
//
@Produces("text/plain")
@Produces("application/json")
public Greeting getIt() {
return new Greeting("Hi there!");
} |
- And now
"http://localhost:8080/helloworld-webapp/webresources/myresource" shows
the following output:
src="http://blogs.sun.com/arungupta/resource/images/jersey10-helloworld-webapp-json-output.png">
Notice the output is now in JSON format.
- Optionally a WAR file can be created using the command:
style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
| mvn clean package |
and the WAR file is generated in "target/helloworld-webapp.war". If
Jersey is installed using
href="http://blogs.sun.com/japod/entry/jersey_1_0_available_on">GlassFish
v3 Update Center then you can use "maven-assembly-plugin" to
customize packaging of WAR and drastically reduce the size.
The JSON representation can be configured in multiple ways as explained
in
href="http://blogs.sun.com/enterprisetechtips/entry/configuring_json_for_restful_web">Configuring
JSON for RESTful Web Services in Jersey 1.0. This has
certainly come a long way from
href="http://blogs.sun.com/arungupta/entry/totd_8_generating_json_using">TOTD
#8 and is much more effecient now.
The Jersey
Wiki documents an extensive set of resources to get
started.
Send all your questions to
href="mailto:users@jersey.dev.java.net">users@jersey.dev.java.net.
Please leave suggestions on other TOTD (
style="font-weight: bold;">Tip
style="font-weight: bold;">Of
style="font-weight: bold;">The
style="font-weight: bold;">Day) that
you'd like to see.
An archive of all the tips is available
href="http://blogs.sun.com/arungupta/tags/totd">here.
Technorati: totd
glassfish
v3
href="http://technorati.com/tag/embeddable">embeddable
jersey
jsr311
rest
href="http://technorati.com/tag/json">json
href="http://technorati.com/tag/webservices">webservices