I've been in the world of software development for 14+ years working with most mainstream programming languages at some point. Chad is a DZone MVB and is not an employee of DZone and has posted 38 posts at DZone. You can read more from them at their website. View Full User Profile

Build a REST service with Netbeans 7, Java, and Jersey that returns JSON

12.05.2011
| 10456 views |
  • submit to reddit

One of the great things about Jersey is that it makes working with REST really easy. If your new to Jersey and REST then you can check out my previous article that shows you to easily build a simple REST service. Today I’m going to use Netbeans 7 (with its built-in Maven support) to build another simple REST service that can easily return JSON (with the help of JAXB).

With Netbeans 7 create a new Maven Web Application called: RestJson

You can remove the default index.jsp file that gets created. Right-click on the Dependencies and add jersey-server-linking as well as jersey-json.

Here is my complete POM file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.giantflyingsaucer</groupId>
    <artifactId>RestJson</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
 
    <name>RestJson</name>
 
    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server-linking</artifactId>
            <version>1.10</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.10</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
 
</project>

The next thing to do is to create a class that extends PackagesResourceConfig which in a nutshell will make it so we won’t need a web.xml for this particular project.

Create a new class called RestJsonApplication with a namespace like: com.giantflyingsaucer.restjson

Here are the contents for the RestJsonApplication.java file:

package com.giantflyingsaucer.restjson;
 
import com.sun.jersey.api.core.PackagesResourceConfig;
import javax.ws.rs.ApplicationPath;
 
@ApplicationPath("/")
public class RestJsonApplication extends PackagesResourceConfig {
 
    public RestJsonApplication() {
        super("com.giantflyingsaucer.restjson.v1.resources.impl");
    }
}

Now you will create a new class called Item with the namespace of: com.giantflyingsaucer.restjson.v1.resources

What is with the “v1″? Simply put I have that in there for versioning – this is version one of this API.

Here are the contents for the Item.java file:

package com.giantflyingsaucer.restjson.v1.resources;
 
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement
public class Item {
 
    private int id;
    private String name;
    private String description;
 
    public Item() {}
 
    public Item(int id, String name, String description) {
        this.id = id;
        this.name  = name;
        this.description = description;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}

As you can see this is a simple Java POJO with a sprinkle of JAXB. In the same package add another new class called: ItemResource

package com.giantflyingsaucer.restjson.v1.resources;
 
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
public interface ItemResource {
    // Example: Returning more than one Item
    @GET
    @Produces({MediaType.APPLICATION_JSON})
    List<Item> getItems();
}

This is the interface to the service in which we define what it will do. In this case it will return item objects in JSON format.

Go ahead and create the new implementation class now called: ItemResourceImpl which implements the ItemResource interface. The namespace for the new class is: com.giantflyingsaucer.restjson.v1.resources.impl

Here is the code for the ItemResourceImpl.java file:

package com.giantflyingsaucer.restjson.v1.resources.impl;
 
import com.giantflyingsaucer.restjson.v1.resources.Item;
import com.giantflyingsaucer.restjson.v1.resources.ItemResource;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.Path;
 
// Set the path, version 1 of API
@Path("/v1/item")
public class ItemResourceImpl implements ItemResource{
 
    @Override
    public List<Item> getItems() {
        List<Item> items = new ArrayList<Item>();
        items.add(new Item(100, "Widget", "A basic widget"));
        items.add(new Item(200, "SuperWidget", "A super widget"));
        items.add(new Item(300, "UberSuperWidget", "A uber super widget"));
 
        return items;
    }
}

For simplicity I add a few items and then simply return them. The conversion to JSON is handled for me.

Using the Maven support in Netbeans 7 do a Clean and Build command (right-click on the project) and deploy the resulting WAR file to something like Tomcat 7 (I’m using Tomcat 7 but feel free to use what you want as long as it supports Servlet 3.0 since we are not using a web.xml file for this project). Once the WAR has been extracted and deployed by Tomcat go ahead and hit the URL and you should see JSON coming back.

http://localhost:8080/RestJson-1.0-SNAPSHOT/v1/item

Results:

{ "item" : [ { "description" : "A basic widget",
        "id" : "100",
        "name" : "Widget"
      },
      { "description" : "A super widget",
        "id" : "200",
        "name" : "SuperWidget"
      },
      { "description" : "A uber super widget",
        "id" : "300",
        "name" : "UberSuperWidget"
      }
    ] }

You can get the full source code from here.

 

From http://www.giantflyingsaucer.com/blog/?p=3458

Published at DZone with permission of Chad Lung, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Christoph Beck replied on Mon, 2011/12/05 - 3:19am

You may allso want to try StAXON (JSON via StAX) for a jersey-json/jettison replacement (JAX-RS sample).

Sa Su replied on Fri, 2011/12/09 - 6:42pm

Question: Is just the media type enough to return the results in JSON format ? If not, which caused the JSON conversion - in spite of the item class is annotated with @XmlRootElement. If I have a complex POJO ( nested collection as instance variables), do I need to do more other than just media type is JSON. thanks

Ash Mughal replied on Wed, 2012/01/25 - 7:14pm

As per my experience, I think media type is enough if you have complex POJO and you do not need to do with @XMLRootElement.

new java

Santa Claus replied on Tue, 2012/01/03 - 4:50pm

Hi, Thank you for a precise example. How do you suggest securing this? I am new to Maven and REST. I was thinking to provide https basic auth. But not sure how to add that in this sort of project. Even something like Apache Shiro. Any suggestions or guidance. Cheers, Santa (You know it's funny when you sign off as Santa, just sayin', try it ;) )

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.