Spring MVC – Easy REST-Based JSON Services with @ResponseBody

Spring 3 makes JSON REST services really easy. This tutorial will show you how in just a few steps.

You can grab the code on GitHub.

Prerequisites
You should have a working Spring MVC Application. If you do not already have a working Spring MVC application set up, follow this tutorial.

We will define three REST services: 1) to retrieve a random Person, 2) to retrieve a Person by ID, and 3) to save a new Person. The services will be consumed using jQuery on a sample page we will set up.

First, I will show the Spring Controller for our REST services, and then we will walk through how they work:

PersonController.java

package com.codetutr.controller;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.codetutr.domain.Person;
import com.codetutr.service.PersonService;
 
@Controller
@RequestMapping ( "api" )
public class PersonController {
     
     PersonService personService;
     
     @Autowired
     public PersonController(PersonService personService) {
         this .personService = personService;
     }
 
     @RequestMapping ( "person/random" )
     @ResponseBody
     public Person randomPerson() {
         return personService.getRandom();
     }
 
     @RequestMapping ( "person/{id}" )
     @ResponseBody
     public Person getById( @PathVariable Long id) {
         return personService.getById(id);
     }
     
     // same as above method, just showing different URL mapping
     @RequestMapping (value= "person" , params= "id" )
     @ResponseBody
     public Person getByIdFromParam( @RequestParam Long id) {
         return personService.getById(id);
     }
     
     // handles person form submit
     @RequestMapping (value= "person" , method=RequestMethod.POST)
     @ResponseBody
     public String savePerson(Person person) {
         personService.save(person);
         return "Saved person: " + person.toString();
     }
}

OK, so, as you can see, we have 4 request handlers in this controller. The first method returns a random person. The next two retrieve a person by ID – just two different approaches to the URL mapping. The last method saves a person.

Remember how Spring controllers usually return a type String (to indicate the resulting view name). Instead, here we are using Spring’s @ResponseBody annotation and returning the object that we want to send to the client. The @ResponseBody annotation tells Spring that we will be returning data in the response body rather than rendering a JSP.

When the @ResponseBody annotation is used, Spring will return the data in a format that is acceptable to the client. That is, if the client request has a header to accept json and Jackson-Mapper is present in the classpath, then Spring will try to serialize the return value to JSON. If the request header indicates XML as acceptable (accept=application/xml) and Jaxb is in the classpath and the return type is annotated with Jaxb annotation, Spring will try to marshall the return value to XML.

As I mentioned, if you want your services to return JSON, you have to have Jackson in the classpath. Here is the only dependency you need to add to your project:

Gradle

compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.12'

Or, if you’re using Maven:

< dependency >
     < groupId >org.codehaus.jackson</ groupId >
     < artifactId >jackson-mapper-asl</ artifactId >
     < version >1.9.12</ version >
</ dependency >

Alternatively, if you want your services to return XML, include your favorite Jaxb implementation, eg.com.sun.xml.bind:jaxb:2.1.9.

In a minute, we’ll build a front end to call these services using AJAX, but if you deploy your application now, you can try out your services using a REST client (or just typing the URL into your browser). Eg:

random-person

You can stop following along if you’re content with that. I will just connect all the pieces now by coding the client-side jQuery:

home.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
 
<! DOCTYPE HTML>
< html >
   < head >
     < title >Spring MVC - Ajax</ title >
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script>
     < style >
       body { background-color: #eee; font: helvetica; }
       #container { width: 500px; background-color: #fff; margin: 30px auto; padding: 30px; border-radius: 5px; box-shadow: 5px; }
       .green { font-weight: bold; color: green; }
       .message { margin-bottom: 10px; }
       label { width:70px; display:inline-block;}
       .hide { display: none; }
       .error { color: red; font-size: 0.8em; }
     </ style >
   </ head >
   < body >
   
   < div id = "container" >
   
     < h1 >Person Page</ h1 >
     < p >This page demonstrates Spring MVC's powerful Ajax functionality. Retrieve a
     random person, retrieve a person by ID, or save a new person, all without page reload.
     </ p >
     
     < h2 >Random Person Generator</ h2 >
     < input type = "submit" id = "randomPerson" value = "Get Random Person" />< br />< br />
     < div id = "personResponse" > </ div >
     
     < hr />
     
     < h2 >Get By ID</ h2 >
     < form id = "idForm" >
       < div class = "error hide" id = "idError" >Please enter a valid ID in range 0-3</ div >
       < label for = "personId" >ID (0-3): </ label >< input name = "id" id = "personId" value = "0" type = "number" />
       < input type = "submit" value = "Get Person By ID" /> < br />< br />
       < div id = "personIdResponse" > </ div >
     </ form >
     
     < hr />
     
     < h2 >Submit new Person</ h2 >
     < form id = "newPersonForm" >
       < label for = "nameInput" >Name: </ label >
       < input type = "text" name = "name" id = "nameInput" />
       < br />
       
       < label for = "ageInput" >Age: </ label >
       < input type = "text" name = "age" id = "ageInput" />
       < br />
       < input type = "submit" value = "Save Person" />< br />< br />
       < div id = "personFormResponse" class = "green" > </ div >
     </ form >
   </ div >
   
   
   <script type="text/javascript">
   
     $(document).ready( function () {
       
       // Random Person AJAX Request
       $( '#randomPerson' ).click( function () {
         $.getJSON( '${pageContext.request.contextPath}/api/person/random' , function (person) {
           $( '#personResponse' ).text(person.name + ', age ' + person.age);
         });
       });
       
       // Request Person by ID AJAX
       $( '#idForm' ).submit( function (e) {
         var personId = +$( '#personId' ).val();
         if (!validatePersonId(personId))
           return false ;
         $.get( '${pageContext.request.contextPath}/api/person/' + personId, function (person) {
           $( '#personIdResponse' ).text(person.name + ', age ' + person.age);
         });
         e.preventDefault(); // prevent actual form submit
       });
       
       // Save Person AJAX Form Submit
       $( '#newPersonForm' ).submit( function (e) {
         // will pass the form data using the jQuery serialize function
         $.post( '${pageContext.request.contextPath}/api/person' , $( this ).serialize(), function (response) {
           $( '#personFormResponse' ).text(response);
         });
         
         e.preventDefault(); // prevent actual form submit and page reload
       });
       
     });
     
     function validatePersonId(personId) {
       console.log(personId);
       if (personId === undefined || personId < 0 || personId > 3) {
         $( '#idError' ).show();
         return false ;
       }
       else {
         $( '#idError' ).hide();
         return true ;
       }
     }
     
   
   </script>
   
   </ body >
</ html >

Once you have everything in place, you should have a page that looks like this:

Spring MVC jQuery Ajax Example

That’s all. Did I miss anything? Let me know in the comments.

Full Source: ZIPGitHub
To run the code from this tutorial: Must have Gradle installed. Clone the GitHub repo or download the ZIP and extract. Open command prompt to code location. Run gradle jettyRunWar. Navigate in browser to http://localhost:8080.

猜你喜欢

转载自nethub2.iteye.com/blog/2329387
今日推荐