В предыдущем посте я сделал краткий обзор настройки среды для проекта Spring MVC REST с CNVR. В этой части я могу сосредоточиться непосредственно на контроллере и демонстрации службы REST. Как обычно, я собираюсь сделать краткое введение, и после этого я рассмотрю методы контроллера и объясню все важные моменты.
Поскольку в дальнейшем я расскажу о службе REST, мне нужно сказать несколько предложений об основных понятиях REST. Вы, наверное, слышали раньше о сайтах, которые предоставляют API для использования их функциональности. Это становится возможным с помощью REST или SOAP, но в этой статье я расскажу о REST.
Например, вы хотите разработать приложение для университетской библиотеки, которое будет работать со студентами и книгами. Вы можете реализовать все контроллеры, используя REST. Это решение сделает ваше приложение открытым для совместной работы с другими приложениями, которые могут использовать API приложения. Для получения дополнительной информации о функциях REST вам необходимо посетить специальные сайты .
Spring MVC REST контроллер
Приложение для смартфона ориентировано на HTTP-клиентов, таких как браузеры и JSON-клиенты. Формат JSON может использоваться различными типами клиентов, но теперь это не имеет значения.
Давайте рассмотрим весь код контроллера:
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
@Controller @RequestMapping (value= "/smartphones" ) public class SmartphoneController { @Autowired private SmartphoneService smartphoneService; @RequestMapping (value= "/create" , method=RequestMethod.GET) public ModelAndView createSmartphonePage() { ModelAndView mav = new ModelAndView( "phones/new-phone" ); mav.addObject( "sPhone" , new Smartphone()); return mav; } @RequestMapping (value= "/create" , method=RequestMethod.POST) public ModelAndView createSmartphone( @ModelAttribute Smartphone smartphone, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); createSmartphone(smartphone); attributes.addFlashAttribute( "msg" , "New Smartphone " +smartphone+ " was successfully created." ); return mav; } @RequestMapping (value= "/create" , method=RequestMethod.POST, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone createSmartphone( @RequestBody Smartphone smartphone) { return smartphoneService.create(smartphone); } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.GET) public ModelAndView editSmartphonePage( @PathVariable int id) { ModelAndView mav = new ModelAndView( "phones/edit-phone" ); Smartphone smartphone = smartphoneService.get(id); mav.addObject( "sPhone" , smartphone); return mav; } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.PUT, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone editSmartphone( @PathVariable int id, @RequestBody Smartphone smartphone) { smartphone.setId(id); return smartphoneService.update(smartphone); } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.PUT) public ModelAndView editSmartphone( @PathVariable int id, @ModelAttribute Smartphone smartphone, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); editSmartphone(id, smartphone); attributes.addFlashAttribute( "msg" , "The Smartphone " +smartphone+ " was successfully updated." ); return mav; } @RequestMapping (value= "/delete/{id}" , method=RequestMethod.DELETE, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone deleteSmartphone( @PathVariable int id) { return smartphoneService.delete(id); } @RequestMapping (value= "/delete/{id}" , method=RequestMethod.GET) public ModelAndView deleteSmartphone( @PathVariable int id, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); Smartphone deletedSphone = deleteSmartphone(id); attributes.addFlashAttribute( "msg" , "The Smartphone " +deletedSphone+ " was successfully deleted." ); return mav; } @RequestMapping (value= "" , method=RequestMethod.GET, produces = "application/json" , consumes = "application/json" ) @ResponseBody public List< Smartphone > allPhones() { return smartphoneService.getAll(); } @RequestMapping (value= "" , method=RequestMethod.GET) public ModelAndView allPhonesPage() { ModelAndView mav = new ModelAndView( "phones/all-phones" ); List< Smartphone > smartphones = new ArrayList< Smartphone >(); smartphones.addAll(allPhones()); mav.addObject( "smartphones" , smartphones); return mav; } } |
Контроллер смартфона действительно многословен и имеет множество методов. В пуске контроллера вы можете увидеть автосервисный смартфон- сервис. В свою очередь, смартфон-сервис имеет пять способов:
- создание общедоступного смартфона (Smartphone sp);
- общедоступный смартфон get (Integer id);
- общедоступный список <Smartphone> getAll ();
- общедоступное обновление смартфона (Smartphone sp) выдает SmartphoneNotFoundException;
- общедоступное удаление смартфона (целочисленный идентификатор) создает исключение SmartphoneNotFoundException;
Каждый метод в контроллере соответствует определенному методу службы. Итак, давайте рассмотрим это соответствие в следующих разделах.
ОТДЫХ: СОЗДАТЬ
Следующий фрагмент кода отвечает за создание новой сущности смартфона:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
... @RequestMapping (value= "/create" , method=RequestMethod.POST) public ModelAndView createSmartphone( @ModelAttribute Smartphone smartphone, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); createSmartphone(smartphone); attributes.addFlashAttribute( "msg" , "New Smartphone " +smartphone+ " was successfully created." ); return mav; } @RequestMapping (value= "/create" , method=RequestMethod.POST, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone createSmartphone( @RequestBody Smartphone smartphone) { return smartphoneService.create(smartphone); } ... |
Первый способ — это простой контроллер Spring MVC. В предыдущих постах я несколько раз объяснял, как работать с контроллерами Spring MVC. Но вы можете заметить, что метод необычен, потому что он содержит вызов второго метода. Второй метод — это метод REST со стандартными аннотациями REST: @ResponseBody и @RequestBody .
Когда вы отправляете форму с данными о новом смартфоне на «../smartphones/create.html» для обработки, распознаватель просмотра согласования содержимого определяет, что вам нужно получить HTML-страницу. В случае, если вы позвоните по URL «../smartphones/create.json», вы получите обратно документ JSON. Потому что я указал в WebAppConfig, что CNVR нужно принимать решение на основе URL-суффикса.
Вы можете спросить: Так в чем же причина использования CNVR, если нам все еще нужно создать несколько методов для одной и той же операции? Предположим, что приложение для смартфона должно поддерживать 2 дополнительных типа контента: XML и PDF. В этом случае CNVR сделает нашу жизнь проще, и мы не будем разрабатывать дополнительные методы, просто добавим соответствующие средства разрешения представления в WebAppConfig . Ситуация станет идеальной, если мы начнем использовать AJAX в приложении. Это означает, что мы можем исключить методы, которые возвращают объекты ModelAndView .
ОТДЫХ: ПОЛУЧИТЬ ВСЕ ЗАПИСИ
В предыдущем параграфе я сделал подробный обзор принципов CNVR на практике. Поэтому сейчас я просто опубликую конкретные фрагменты кода, которые соответствуют соответствующей операции.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
... @RequestMapping (value= "" , method=RequestMethod.GET, produces = "application/json" , consumes = "application/json" ) @ResponseBody public List< Smartphone > allPhones() { return smartphoneService.getAll(); } @RequestMapping (value= "" , method=RequestMethod.GET) public ModelAndView allPhonesPage() { ModelAndView mav = new ModelAndView( "phones/all-phones" ); List< Smartphone > smartphones = new ArrayList< Smartphone >(); smartphones.addAll(allPhones()); mav.addObject( "smartphones" , smartphones); return mav; } ... |
Эти методы отвечают за получение списка смартфонов.
ОТДЫХ: ОБНОВЛЕНИЕ
Вот методы, которые выполняют обновление существующего смартфона.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
... @RequestMapping (value= "/edit/{id}" , method=RequestMethod.PUT, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone editSmartphone( @PathVariable int id, @RequestBody Smartphone smartphone) { smartphone.setId(id); return smartphoneService.update(smartphone); } @RequestMapping (value= "/edit/{id}" , method=RequestMethod.PUT) public ModelAndView editSmartphone( @PathVariable int id, @ModelAttribute Smartphone smartphone, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); editSmartphone(id, smartphone); attributes.addFlashAttribute( "msg" , "The Smartphone " +smartphone+ " was successfully updated." ); return mav; } ... |
ОТДЫХ: УДАЛИТЬ
Вот методы, которые выполняют удаление существующего смартфона.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
... @RequestMapping (value= "/delete/{id}" , method=RequestMethod.DELETE, produces = "application/json" , consumes = "application/json" ) @ResponseBody public Smartphone deleteSmartphone( @PathVariable int id) { return smartphoneService.delete(id); } @RequestMapping (value= "/delete/{id}" , method=RequestMethod.GET) public ModelAndView deleteSmartphone( @PathVariable int id, final RedirectAttributes attributes) { ModelAndView mav = new ModelAndView( "redirect:/index.html" ); Smartphone deletedSphone = deleteSmartphone(id); attributes.addFlashAttribute( "msg" , "The Smartphone " +deletedSphone+ " was successfully deleted." ); return mav; } ... |
Резюме
Я надеюсь, что эта часть была ясна для вас. Определенно, вам нужно иметь базовые знания о Spring и REST, чтобы полностью понять эту статью. Не игнорируйте ссылки, которые я поместил в статье для получения дополнительной информации. В третьей части я собираюсь продемонстрировать, как работает это приложение.