Статьи

Spring MVC — простые JSON-сервисы на основе REST с @ResponseBody

Spring 3 делает сервисы JSON REST действительно легкими. Этот урок покажет вам, как всего за несколько шагов. Вы можете получить код на GitHub .

Предпосылки

У вас должно быть рабочее Spring MVC Application. Если у вас еще нет настроенного рабочего приложения Spring MVC, следуйте этому руководству . Мы определим три службы REST: 1) для поиска случайного человека, 2) для поиска человека по идентификатору и 3) для сохранения нового человека. Услуги будут использоваться с помощью jQuery на образце страницы, который мы настроим. Сначала я покажу Spring Controller для наших REST-сервисов, а затем мы рассмотрим, как они работают:

PersonController.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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, but is mapped to
     * /api/person?id= rather than /api/person/{id}
     */
    @RequestMapping(value="person", params="id")
    @ResponseBody
    public Person getByIdFromParam(@RequestParam Long id) {
        return personService.getById(id);
    }
 
    /**
     * Saves new person. Spring automatically binds the name
     * and age parameters in the request to the person argument
     * @param person
     * @return String indicating success or failure of save
     */
    @RequestMapping(value="person", method=RequestMethod.POST)
    @ResponseBody
    public String savePerson(Person person) {
        personService.save(person);
        return "Saved person: " + person.toString();
    }
}

Итак, как вы можете видеть, у нас есть 4 обработчика запросов в этом контроллере. Первый метод возвращает случайного человека. Следующие два извлекают человека по идентификатору — только два разных подхода к сопоставлению URL. Последний метод спасает человека.

Вспомните, как контроллеры Spring обычно возвращают тип String (чтобы указать получающееся имя представления). Вместо этого здесь мы используем аннотацию Spring @ResponseBody и возвращаем объект, который мы хотим отправить клиенту. Аннотация @ResponseBody сообщает Spring, что мы будем возвращать данные в теле ответа, а не отображать JSP.

Когда @ResponseBody аннотация @ResponseBody , Spring возвращает данные в формате, приемлемом для клиента. То есть, если клиентский запрос имеет заголовок для принятия json и Jackson-Mapper присутствует в пути к классам, то Spring попытается сериализовать возвращаемое значение в JSON. Если в заголовке запроса указан XML как приемлемый (accept = application / xml), а Jaxb находится в пути к классам, а тип возвращаемого значения помечен аннотацией Jaxb, Spring попытается маршалировать возвращаемое значение в XML.

Как я уже упоминал, если вы хотите, чтобы ваши службы возвращали JSON, вы должны включить Джексона в путь к классам. Вот единственная зависимость, которую нужно добавить в ваш проект:

Gradle

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

Или, если вы используете Maven:

1
2
3
4
5
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.12</version>
</dependency>

В качестве альтернативы, если вы хотите, чтобы ваши сервисы возвращали XML, включите вашу любимую реализацию Jaxb, например. com.sun.xml.bind:jaxb:2.1.9 .

Через минуту мы создадим интерфейс для вызова этих сервисов с помощью AJAX, но если вы развернете свое приложение сейчас, вы можете опробовать свои сервисы с помощью клиента REST (или просто набрав URL в вашем браузере). Например:

случайный человек

Вы можете перестать следовать, если вы довольны этим. Сейчас я просто соединю все части, кодируя клиентский jQuery:

home.jsp

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<%@ 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
      $('#randomPerson').click(function() {
        $.getJSON('${pageContext.request.contextPath}/api/person/random', function(person) {
          $('#personResponse').text(person.name + ', age ' + person.age);
        });
      });
       
      $('#newPersonForm').submit(function(e) {
        // will pass the form date 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>

Как только у вас все на месте, у вас должна появиться страница, которая выглядит следующим образом:

Spring MVC JQuery Ajax Пример

Полный источник:

ZIP , GitHub
Чтобы запустить код из этого руководства: необходимо установить Gradle . Загрузите ZIP. Extract. Откройте командную строку для извлеченного местоположения. Запустите gradle jettyRunWar. Перейдите в браузере по адресу http: // localhost: 8080.

использованная литература

Ссылка: Spring MVC — простые JSON-сервисы на основе REST с @ResponseBody от нашего партнера по JCG Стива Хэнсона в блоге CodeTutr .