Create RESTful Web Services with Spring
In Java™, you can create RESTful Web Service by using JSR 311 (311) and its references to implement Jersey, use the Restlet framework, and develop from scratch. Spring is a popular Java EE application Development Framework, and now its MVC layer also supports REST. This article describes methods for developing RESTful Web Services using Spring. Readers will learn how to use spring APIs and annotations to develop RESTful Web Services, and how spring integrates this new feature into its framework.
5 Reviews:
Yi Ming Huang, software engineer, IBM
Dong Fei Wu, software engineer, IBM
May 23, 2011
Introduction
Roy Fielding is one of the main authors of the HTTP 1.0 and 1.1 standards, and in 2000 he first proposed REST in his doctoral dissertation.
With the REST-style architecture, requests and responses are built on the transport of resource representations. Resources are identified by the global ID, which typically uses a Uniform Resource Identifier (URI). The client app uses an HTTP method (such as GET, POST, PUT, or DELETE) to manipulate one or more resources. Typically, get is used to get or list one or more resources, POST is used to create, PUT is used for updates or replacements, and delete is used to delete resources.
For example, a representation of an GET http://host/context/employees/12345
employee with an ID of 12345 will be obtained. This response can be either XML or ATOM that contains detailed employee information, or a jsp/html page with a better UI. Which representation you see depends on the server-side implementation and the MIME type of your client request.
RESTful Web Service is a Web service implemented using HTTP and REST principles. Typically, a RESTful Web Service defines the base resource URI, the representation/response MIME it supports, and the operations it supports.
This article describes how to use Spring to create a Java-implemented server-side RESTful Web Services. This example will use the browser, curl, and Firefox plugin restclient as the client making the request. You can download the source code used in this article.
This article assumes that you are familiar with REST basics. More information about REST is available in the Resources section.
Back to top of page
REST Support for Spring 3
Before the Spring framework supports rest, several other implementation techniques are used to create restful Web Services for Java, such as Restlet, Resteasy, and Jersey. Jersey is one of the most notable of these, and it is the reference implementation of the JAX-RS (JSR 311). More information on JSR 311 and Jersey is available in the Resources section.
Spring is a widely used Java EE framework that adds support for RESTful Web Services Development after version 3. While support for REST is not an implementation of JAX-RS, it has more features than the standard definition. REST support is seamlessly integrated into the spring MVC layer, which can be easily applied to applications built using spring.
Key features supported by Spring REST include:
- Annotations, such as
@RequestMapping
and @PathVariable
, support for resource identification and URL mapping
ContentNegotiatingViewResolver
Support for different representations of different mime/content types
- Seamlessly integrate into the original MVC layer using a similar programming model
Back to top of page
Create a sample RESTful Web Service
The examples in this section demonstrate the creation of the Spring 3 environment and create a "Hello World" app that can be deployed to Tomcat. We then complete a more complex application to understand the important concepts of Spring 3 REST support, such as multiple MIME types representing support and JAXB support. In addition, this article uses some code snippets to help understand these concepts. You can download all the sample code for this article.
This article assumes that you are already familiar with spring framework and spring MVC.
Hello World: Using Spring 3 REST support
To create the development environment used for this example, you need to:
- Ide:eclipse IDE for JEE (v3.4+)
- Java SE5 above
- Web Container: Apache Tomcat 6.0 (Jetty or other containers also available)
- Spring 3 Framework (v3.0.3 is the latest version when this article is written)
- Other libraries: JAXB 2, JSTL, commons-logging
Create a Web app in Eclipse, and then set up Tomcat 6 as its operating environment. Then you need to set up the Web. xml file to activate Spring Webapplicationcontext. This example divides the Spring bean configuration into two files: Rest-servlet.xml contains mvc/rest-related configuration, Rest-context.xml contains service-level configurations such as data source beans. Listing 1 shows the part of the Spring configuration in Web. Xml.
Listing 1. Activating Spring Webapplicationcontext in Web. xml
<context-param><param-name>contextconfiglocation</param-name><param-value>/web-inf/ rest-context.xml</param-value></context-param><!--This listener would load other application context File in addition to Rest-servlet.xml--><listener><listener-class> Org.springframework.web.context.contextloaderlistener</listener-class></listener><servlet> <servlet-name>rest</servlet-name><servlet-class> org.springframework.web.servlet.dispatcherservlet</servlet-class><load-on-startup>1</ load-on-startup></servlet><servlet-mapping><servlet-name>rest</servlet-name>< Url-pattern>/service/*</url-pattern></servlet-mapping>
Create the associated configuration of Spring MVC (Controller, view, view Resolver) in the Rest-servlet.xml file. Listing 2 shows the most important of these sections.
Listing 2. Create a Spring MVC configuration in the Rest-servlet.xml file
<context:component-scan base-package="Dw.spring3.rest.controller"/><!--to enable @RequestMapping process on type level and method Level--><bean class="Org.springframework.web.servlet.mvc.annotation. Defaultannotationhandlermapping "/><bean class="Org.springframework.web.servlet.mvc.annotation. Annotationmethodhandleradapter "/><!--use JAXB OXM marshaller to Marshall/unmarshall following Class--><bean id="Jaxbmarshaller"class="Org.springframework.oxm.jaxb.Jaxb2Marshaller"><property name="Classestobebound"><list> <value>dw.spring3.rest.bean.Employee</value> <value> Dw.spring3.rest.bean.employeelist</value></list></property></bean><bean id="Employees"class="Org.springframework.web.servlet.view.xml.MarshallingView"><constructor-arg ref="Jaxbmarshaller"/></bean><bean id="Viewresolver"class="Org.springframework.web.servlet.view.BeanNameViewResolver"/>
In the code above:
-
Component-scan
-
Enable automatic scanning of classes with Spring annotations
In practice, it examines the annotations defined in the Controller class
@Controller
.
-
DefaultAnnotationHanlderMappings
AndAnnotationMethodHandlerAdapter
-
The
@ReqeustMapping
beans of a class or function that uses annotations is handled by Spring
This comment will be described in more detail in the next section.
-
Jaxb2Mashaller
-
Defines a group (marshaller) and OXM (Unmarshaller) that uses JAXB 2 for object XML mapping (
-
MashallingView
-
Defines an XML representation that uses Jaxb2mashaller
view
-
BeanNameViewResolver
-
Defines a view resolver with a user-specified bean name
This example will use the name "Employees"
MarshallingView
.
This completes the relevant configuration of Spring. The next step is to write a controller to handle user requests. Listing 3 shows the controller class.
Listing 3. Dw.spring3.rest.controller.EmployeeController
@ControllerPublicclass Employeecontroller {@RequestMapping (method=requestmethod. GET, value= "/employee/{id}") public Modelandview getemployee (@PathVariable String ID) {Employee e = Employeeds.get (Long. Parselong(id)); return New Modelandview (xml_view_name, "Object", E);}}
@RequestMapping
Annotations are key to the Spring REST feature. It specifies which HTTP method ( RequestMethod.GET
) and which URI () The annotated method will handle /employee/{id}
. Attention:
- For
{id}
placeholders, use annotations to @PathVariable
inject values from {} into the parameters of the function.
- Xml_view_name
employees
, which is the name of the view defined in Rest-servlet.xml.
employeeDS
is a memory-based data source that has been implemented beyond the scope of this article.
Publish the Web app to your Tomcat. At this point, you can open the browser and enter http:// . The browser displays an XML view of employee information with ID 1.
Please read on to learn more about the features of Spring REST support.
MethodResource operations are implemented through the HTTP method, such as GET, POST, PUT, and DELETE. You have previously learned how to use GET
methods to query employee information. Now we'll cover POST, PUT, and DELETE.
By using @RequestMapping
the functionality of annotations, the code that handles different methods is very similar. Listing 4 shows EmployeeController
the code snippet.
Listing 4. Dw.spring3.rest.controller.EmployeeController@RequestMapping (Method=requestmethod.POST, value= "/employee") PublicModelandview AddEmployee (@RequestBody String body) {Source Source =NewStreamsource (NewStringReader (body)); Employee E = (employee) jaxb2mashaller.unmarshal (source); Employeeds.add (e);returnNewModelandview (Xml_view_name, "Object", e);} @RequestMapping (Method=requestmethod.PUT, value= "/employee/{id}") PublicModelandview UpdateEmployee (@RequestBody String body) {Source Source =NewStreamsource (NewStringReader (body)); Employee E = (employee) jaxb2mashaller.unmarshal (source); Employeeds.update (e);returnNewModelandview (Xml_view_name, "Object", e);} @RequestMapping (Method=requestmethod.DELETE, value= "/employee/{id}") PublicModelandview Removeemployee (@PathVariable String id) {employeeds.remove (Long).Parselong(ID)); List<employee> employees = Employeeds.getall (); EmployeeList list =NewEmployeeList (employees);returnNewModelandview (Xml_view_name, "Employees", list);}
In the code above:
RequestMethod.<Method>
Value determines which HTTP method the commented function should handle.
- Through
@RequestBody
, the principal content of the HTTP request can be injected as a parameter.In this case, the principal content is the XML data that represents the employee information. We use JAXB to group the XML into a Java Bean and then store it. A sample request body can be:
<employee><id>3</id><name>guest</name></employee>
- Other useful comments that can be injected into the function parameters are
@PathVariable
, and @RequestParm
so on. The Spring documentation has a full list of comments (see Resources).
Resource CollectionTypically, you also need to manipulate bulk resources. For example, you might want to get information about all employees, not just one employee. You can implement a method similar to the previous one, and all you need to do is modify the URI from/employee to/employees. The plural form of the employee can correctly reflect the semantics of the batch. Listing 5 shows how this is implemented.
Listing 5. Employeecontroller's GetAllEmployees@RequestMapping (Method=requestmethod. GET, value= "/employees")publicnew employeelist (employees); return New Modelandview (xml_view_name, "Employees", list);}
You need to declare a wrapper class for the Employee collection. This wrapper class is required by JAXB 2 because it does not properly group the Java.util.List class. Listing 6 shows the EmployeeList
class.
Listing 6. Dw.spring3.rest.bean.EmployeeList@XmlRootElement (name= "Employees")publicclass employeelist {privateint count; Private list<employee> employees; Public EmployeeList () {} public employeelist (list<employee> employees) {this. Employees = employees; this. Count = Employees.size ();} Public int GetCount () {return count;} Public void setcount (int count) {this. Count = Count;} @XmlElement (name= "employee") public list<employee> getemployees () {return employees;} Public void setemployees (list<employee> employees) {this. Employees = Employees;}}
Content negotiationAnother common feature of REST services is that they can produce different representations based on the request. For example, if the client requests the Html/text representation of all employees, then the server should produce an HTML page that conforms to the syntax rules for the user. If the client is requesting an employee's Application/xml representation, the server should produce an XML result. Other popular representations are ATOM and PDF.
Spring 3 introduces a ContentNegotiatingViewResolver
new view parser named. It can switch the view resolver based on the requested content type (the attribute in the request header Accept
) or the URI suffix. The following example is used ContentNegotiatingViewResolver
to implement multiple representations of support.
In the Rest-servlet.xml file, remove the original definition with a comment viewResolver
. Instead ContentNegotiatingViewResolver
, use it to replace it, as shown in Listing 7.
Listing 7. Define content Negotiation<bean class= "Org.springframework.web.servlet.view . Contentnegotiatingviewresolver " ><property name= " mediatypes " ><map><entry key= "xml" value= "Application/xml" /><entry key= "html" value= "text/html" />< /map></property><property name= "viewresolvers" ><list><bean class= " Org.springframework.web.servlet.view . Beannameviewresolver "/><bean class= " Org.springframework.web.servlet.view . Urlbasedviewresolver " ><property name= " Viewclass " value= " Org.springframework.web.servlet.view.JstlView "/><property name= " prefix " value= "/web-inf/ jsp/"/><property name= " suffix " value= ". jsp "/></bean></list></ Property></bean>
This definition shows support for handling two kinds of request content: application/xml
and text/html
. This code also defines two view parsers BeanNameViewResolver
, which are responsible for handling application/xml, while the other is UrlBasedViewResolver
responsible for handling text/html.
In practice, when you type in a browser http:// , it requests text/html
all employee information in the form. It will then UrlBasedViewResolver
parse, and Spring will select/web-inf/jsp/employees.jsp as the returned view. When you add a request header Accept:application/xml
and then initiate the request, it is BeanNameViewResolver
parsed. As the code in Listing 5, it will be represented by a employees
view named, which is the JAXB 2 marshalling view defined.
getAllEmployees()
The controller code does not need to be modified. The employees.jsp will be rendered using employees
a model object named. Listing 8 shows the code snippet for employees.jsp.
Listing 8. The employees.jsp in/web-inf/jsp<table border=1><thead><tr><th>id</th><th>name</th><th >email</th></tr></thead><c:foreach var="employee" items= "${employees.employees} "><tr><td>${employee.id}</td><td>${employee.name}</td><td>${ Employee.email}</td></tr></c:foreach></table>
Back to top of page
Clients communicating with the REST serviceSo far, you have developed a simple RESTful Web Service that supports CRUD (adding and deleting) operations on employee information. The next section describes how to communicate with this service. You will use Curl to test the REST service.
You can also use the Firefox plugin named Restclient to test the REST service. It is easy to use and has a good UI. The reference material has information about its download.
Using CurlCurl is a popular command-line tool that can send requests to the server with HTTP and HTTPS protocols. Curl is a built-in tool on Linux® and Mac®. For the Windows® platform, you can download this tool separately (see Resources).
To initialize the first Curl command that queries all employee information, you can enter:
Curl–haccept:application/xml http://localhost:8080/rest/service/employees
Its response will be in XML format and contains all the employee information, as shown in 1.
Figure 1. All employee information represented in XML modeYou can also try to access the same URL on the browser. At this point, the Accept in the header message is text/html, so the browser displays a table defined in employees.jsp. This is shown in Figure 2.
Figure 2. All employee information represented in HTML modeTo POST a new employee information to the server, we can use the following code. The code in Listing 4 will addEmployee()
use the request body and unpack it as an Employee
object.
Curl-x post-hcontent-type:application/xml--data "<employee><id>3</id><name>guest</ Name><email>[email protected]</employee> "Http://localhost:8080/rest/service/employee
This adds a new employee information. You can use the first example to verify the list of employees.
The PUT method is similar to POST.
Curl-x put-hcontent-type:application/xml--data "<employee><id>3</id><name>guest3</ Name><email>[email protected]</employee> "Http://localhost:8080/rest/service/employee/3
The above code modifies the employee data with ID 3.
Back to top of page
ConclusionNow that Spring 3 has supported REST on its MVC layer, you can use spring APIs and annotations to develop restful Web Services. The examples in this article show you how to use the new features of Spring 3 that can help you simplify the development of Java server-side RESTful Web Services.
Create a RESTful Web service (GO) with Spring