Technologies used
The following technologies were used.- Tomcat (version 7.0.26 was used with this project)
- Maven (version 3.0.3 was used with this project)
- An IDE of your choice - I'm using IntelliJ ( community edition)
- Jersey - but we will get it using Maven.
Create the maven project
Create a new maven web-app archetype project either through your IDE (if it supports Maven integration) or via the command line. If you are using the command line, the command will be:mvn archetype:generate -DgroupId=foo.bar -DartifactId=hello -DarchetypeArtifactId=maven-archetype-webapp
After creating the project you should see a directory structure like the following:
Add the Jersey dependencies
Next modify the pom.xml file to include the jersey dependencies.Note: In the latest release of jersey the com.sun.jersey.spi.container.servlet.ServletContainer class has been moved, so the jersey-servlet dependency is now required. If you do not include the dependency you will get a nasty "java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer" error in your tomcat log file.
The decencies section of the pom.xml file should look like this:
<dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.12</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId> <version>1.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies>
Create the web-service
Next create the java web-service class. This is known as the "Root Resource Class" and is a POJO that is annotated with a @Path or has a method annotated with the @Path or a request type (i.e. @GET).Here is the HelloWorld class I created:
package foo.bar; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/world") public class HelloWorld { @GET @Produces(MediaType.TEXT_HTML) public String sayHtmlHello() { return "Hello! Hello, hello! "; } }
The "Path" annotation indicates the URI this class will be available at relative to your base URL. For example, if this web-app is launched at localhost using a context of "hello" and no URL pattern is defined in the web.xml servlet mapping section, then the web service will be available at http://localhost:8080/hello/world.
The "GET" annotation indicates this method will respond to HTTP Get requests.
The "Produces" annotation indicates the MIME response the method will return.
Setup the web.xml file
Next, the web.xml file needs to be setup. Here is mine:
<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" > <servlet > <servlet-name >HelloWorld Jersey 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 >foo.bar </param-value > </init-param > <load-on-startup >1 </load-on-startup > </servlet > <servlet-mapping > <servlet-name >HelloWorld Jersey Service </servlet-name > <url-pattern >/* </url-pattern > </servlet-mapping > </web-app >The web.xml file does the following:
- The init-param tells the jersey ServletContainer to look for our Root Resource Class (i.e. our HelloWorld class) in the foo.bar package. There are other ways to register this; see the jersey documentation for more details
- Loads the ServletContainer at startup. A value of 1 indicates the ServletContainer is a high priority servlet to load
- The url-pattern can be used to define your URL. For example, running local host with a context of "hello" and path annotation of "world" on the HelloWorld class:
- <url-pattern>/*</url-pattern>
- The web service will be available at: http://localhost:8080/hello/world
- <url-pattern>/jersey/*</url-pattern>
- The web service will be available at http://localhost:8080/hello/jersey/world
Build the project
If you use maven from the command line then use the following to build the project:mvn package
Otherwise, use your IDE to do the maven package phase. Either way, the result should be a hello.war file created in the target directory.
Deploy to Tomcat
There are several ways to deploy the hello.war file to Tomcat. See the Tomcat Documentation for the option best for you.For myself, I just dropped the hello.war file into the CATALINA_HOME/webapps directory and started tomcat up.
View the web service
Point a browser to http://localhost:8080/hello/world and you should see the output of "Hello, hello!"References
Help documents and tutorials for jersey:http://docs.oracle.com/cd/E19776-01/820-4867/index.html
http://jersey.java.net/nonav/documentation/latest/user-guide.html
http://www.vogella.de/articles/REST/article.html
Overview of what a Restful web service is:
http://www.ibm.com/developerworks/webservices/library/ws-restful/
Technologies used:
http://jersey.java.net/
http://maven.apache.org/
http://tomcat.apache.org/
Appreciate this info. Made my life easier.
ReplyDeleteI must have missed something someplace because when I try to create the war it fails. Any ideas?
ReplyDeletemvn package
[INFO] Scanning for projects...
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project foo.bar:hello:1.0-SNAPSHOT (/Users/eddie/Documents/workspace/hello/pom.xml) has 3 errors
[ERROR] Malformed POM /Users/eddie/Documents/workspace/hello/pom.xml: Unrecognised tag: 'groupid' (position: START_TAG seen ...\n ... @12:22) @ /Users/eddie/Documents/workspace/hello/pom.xml, line 12, column 22 -> [Help 2]
[ERROR] 'dependencies.dependency.artifactId' for null:null:jar is missing. @ line 21, column 21
[ERROR] 'dependencies.dependency.groupId' for null:null:jar is missing. @ line 21, column 21
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/ModelParseException
Sorry, got it. I am running on a Mac and it is case sensitive.
ReplyDeletegroupid needs to be groupId
ReplyDeleteartifactid needs to be artifactId
(see upper case versus lower case i)
Ah yes, good catch. I've updated the post. The code checked into github did have correct case. Thanks.
Delete