Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Spring MVC

2,614 views

Published on

* JSP 1.0 a vývoj k moderním MVC frameworkům
* Vysvětlení MVC vzoru
* Zpracování požadavků Spring MVC
* Základní konfigurace a ovládání Spring MVC

Published in: Technology, Education
  • Be the first to comment

Spring MVC

  1. 1. Spring framework Motto: Musíte rozbít vejce když chcete udělat omeletu Spring framework training materials by Roman Pichlík is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.Sunday 13 May 2012 1
  2. 2. Spring MVCSunday 13 May 2012 2
  3. 3. Jak jsme se tam dostaliSunday 13 May 2012 3
  4. 4. Špagetový kód • JSP 1.0, skriplety <% Connection con = null; String sql = "select name from users"; PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = ps.executeQuery(); out.println("<table>"); while(rs.next()) { out.println("<tr>"); out.println("<td>"); out.println(rs.getString(1)); out.println("</td>"); out.println("</tr>"); } out.println("<table>"); %>Sunday 13 May 2012 4
  5. 5. Nevýhody • Znovupoužitelnost • Míchání odpovědností • prezentační a aplikační logika dohromady • nemožnost alternativní reprezentace • Špatná testovatelnostSunday 13 May 2012 5
  6. 6. MVC • Oddělení odpovědností • Aplikační chování • Data a jejich reprezentaci • Obecný návrhový vzor • Desktop, klientské frameworky • JavaScript - SproutCore • SwingSunday 13 May 2012 6
  7. 7. MVC • Model • Date • Controller • Aplikační chování • View • Prezentace ModeluSunday 13 May 2012 7
  8. 8. MVC v prostředí web framew.Sunday 13 May 2012 8
  9. 9. Web frameworkySunday 13 May 2012 9
  10. 10. Spring MVC • XML, Anotace • Dependency Injection • SPEL, Validace • Koncepty zůstavají zachovanéSunday 13 May 2012 10
  11. 11. Odbavení požadavkuSunday 13 May 2012 11
  12. 12. Aplikační contextSunday 13 May 2012 12
  13. 13. Základní anotace • @Controller • @RequestMapping • @PathVariable • @RequestParamSunday 13 May 2012 13
  14. 14. Controller • @Controller • Vstupní bod • Mapování na konkretní URL path • Bridge HTTP/Aplikační logika • Měl by být jednotkově testovatelnýSunday 13 May 2012 14
  15. 15. Controller ukázka @Controller public class UserController { @Autowired private UserStorageDao userStorageDao; @RequestMapping("/users.htm") public ModelMap usersHandler() { return new ModelMap("users", userStorageDao.getAll()); } }Sunday 13 May 2012 15
  16. 16. @RequestMapping • Používá se pro třídy i metody • Lze vhodně kombinovat • Může definovat path, HTTP metodu případně další podmínky, za kterých dojde k matchSunday 13 May 2012 16
  17. 17. @Controller @RequestMapping("/appointments") public class AppointmentsController { private final AppointmentBook appointmentBook; @Autowired public AppointmentsController(AppointmentBook appointmentBook) { this.appointmentBook = appointmentBook; } @RequestMapping(method = RequestMethod.GET) public Map<String, Appointment> get() { return appointmentBook.getAppointmentsForToday(); } @RequestMapping(value="/{day}", method = RequestMethod.GET) public Map<String, Appointment> getForDay(@PathVariable Date day, Model model) { return appointmentBook.getAppointmentsForDay(day); } @RequestMapping(value="/new", method = RequestMethod.GET) public AppointmentForm getNewForm() { return new AppointmentForm(); } @RequestMapping(method = RequestMethod.POST) public String add(@Valid AppointmentForm appointment, BindingResult result) { if (result.hasErrors()) { return "appointments/new"; } appointmentBook.addAppointment(appointment); return "redirect:/appointments"; } }Sunday 13 May 2012 17
  18. 18. Path mapping @Controller třída definuje první část cesty @RequestMapping("/appointments") public class AppointmentsController { private final AppointmentBook appointmentBook; @Autowired public AppointmentsController(AppointmentBook appointmentBook) { this.appointmentBook = appointmentBook; } metody definují zbytek @RequestMapping(method = RequestMethod.GET) public Map<String, Appointment> get() { return appointmentBook.getAppointmentsForToday(); } @RequestMapping(value="/{day}", method = RequestMethod.GET) public Map<String, Appointment> getForDay(@PathVariable Date day, Model model) { return appointmentBook.getAppointmentsForDay(day); } @RequestMapping(value="/new", method = RequestMethod.GET) public AppointmentForm getNewForm() { return new AppointmentForm(); } ...Sunday 13 May 2012 18
  19. 19. Path mapping http://myapp/appointments/2011-01-01 http://myapp/appointments/new @Controller @RequestMapping("/appointments") public class AppointmentsController { private final AppointmentBook appointmentBook; ... @RequestMapping(value="/{day}", method = RequestMethod.GET) public Map<String, Appointment> getForDay(@PathVariable Date day, Model model) { return appointmentBook.getAppointmentsForDay(day); } @RequestMapping(value="/new", method = RequestMethod.GET) public AppointmentForm getNewForm() { return new AppointmentForm(); } ...Sunday 13 May 2012 19
  20. 20. HTTP method mapping mapping na konkrétní HTTP metodu @Controller @RequestMapping("/appointments") public class AppointmentsController { @RequestMapping(method = RequestMethod.GET) public Map<String, Appointment> get() { return appointmentBook.getAppointmentsForToday(); } @RequestMapping(value="/{day}", method = RequestMethod.GET) public Map<String, Appointment> getForDay(@PathVariable Date day, Model model) { return appointmentBook.getAppointmentsForDay(day); } @RequestMapping(method = RequestMethod.POST) public String add(@Valid AppointmentForm appointment, BindingResult result) { if (result.hasErrors()) { return "appointments/new"; } appointmentBook.addAppointment(appointment); return "redirect:/appointments"; } }Sunday 13 May 2012 20
  21. 21. Podmínečný mapping HTTP hlavičkou @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping(value = "/pets", method = RequestMethod.POST, headers="content-type=text/*") public void addPet(Pet pet, @PathVariable String ownerId) { // implementation omitted } } Query parametrem @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping(value = "/pets/{petId}", params="myParam=myValue") public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } }Sunday 13 May 2012 21
  22. 22. Handler method argumenty •ServletRequest or HttpServletRequest, HttpSession. •org.springframework.web.context.request.WebRequest, org.springframework.web.context.request.NativeWebRequest. •java.util.Locale •java.io.InputStream / java.io.Reader •java.io.OutputStream / java.io.Writer •java.security.Principal •@PathVariable •@RequestParam •@RequestHeader •@RequestBody •HttpEntity<?> •java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap •org.springframework.validation.Errors / org.springframework.validation.BindingResult •org.springframework.web.bind.support.SessionStatusSunday 13 May 2012 22
  23. 23. @PathVariable @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET) public String findOwner(@PathVariable String ownerId, Model model) { Owner owner = ownerService.findOwner(ownerId); model.addAttribute("owner", owner); return "displayOwner"; }Sunday 13 May 2012 23
  24. 24. @PathVariable http://myapp/owners/1 @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET) public String findOwner(@PathVariable String ownerId, Model model) { Owner owner = ownerService.findOwner(ownerId); model.addAttribute("owner", owner); return "displayOwner"; }Sunday 13 May 2012 24
  25. 25. @PathVariable • @PathVariable typ může být pouze základní typ (long, String) • Pro další typy =>PropertyEditor @Controller public class MyFormController { @InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); } }Sunday 13 May 2012 25
  26. 26. @ModelAttribute • Přednahrání dat do formuláře • Propojení modelu do konverzačního schématu • obsluha formulářeSunday 13 May 2012 26
  27. 27. Přednahrání modelu •metoda se volá ještě před vlastní handler metodou •model atributy lze namapovat do handler metody public class EditPetForm { // ... @ModelAttribute("types") public Collection<PetType> populatePetTypes() { return this.clinic.getPetTypes(); } @RequestMapping public void handle(@ModelAttribute Collection<PetType> types)Sunday 13 May 2012 27
  28. 28. Konverzační použití @Controller @RequestMapping("/editUser.htm") @SessionAttributes("user") public class UserEditFormController { @Autowired private UserStorageDao userStorageDao; @RequestMapping(method = RequestMethod.GET) public String setupForm(ModelMap model) { model.addAttribute("user", new User()); return "editUser"; //viewname } @RequestMapping(method = RequestMethod.POST) public String processSubmit( @ModelAttribute("user") User user, BindingResult result, SessionStatus status) { userStorageDao.save(user); status.setComplete(); return "redirect:users.htm"; } }Sunday 13 May 2012 28
  29. 29. Návratové typy návratový typ @RequestMapping(method = RequestMethod.POST) public XXX processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { … }Sunday 13 May 2012 29
  30. 30. Možné návratové typy •org.springframework.web.servlet.ModelAndView •org.springframework.ui.Model •java.util.Map •org.springframework.ui.View •java.lang.String •void •@ResponseBody •A HttpEntity<?> or ResponseEntity<?> •Jiný typSunday 13 May 2012 30
  31. 31. Automatická validace • integrace JSR-303 • BindingResult objekt s výsledkem validace @RequestMapping(method = RequestMethod.POST) public String processSubmit( @ModelAttribute("user") @Valid User user, BindingResult result, SessionStatus status) { if (result.hasErrors()) { return "editUser"; } userStorageDao.save(user); status.setComplete(); return "redirect:users.htm"; }Sunday 13 May 2012 31
  32. 32. Exception handling • Vytvoření beany implementující • HandlerExceptionResolver • Vrací ModelAndView • Ošetření všech výjímek • Zobrazení error stránky • Zalogovaní kontextu • REST (správný HTTP status)Sunday 13 May 2012 32
  33. 33. Interceptors • Možnost reagovat před a po zpracování HTTP požadavku • pre, post, after • Vytvoření beany implementující • HandlerInterceptor • HandlerInterceptorAdapterSunday 13 May 2012 33
  34. 34. Spring MVC zavedení <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc classpath:/org/springframework/web/servlet/config/spring-mvc-3.0.xsd"> <mvc:annotation-driven/> </beans>Sunday 13 May 2012 34
  35. 35. Spring MVC zavedení s view r. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc classpath:/org/springframework/web/servlet/config/spring-mvc-3.0.xsd"> <mvc:annotation-driven/> <bean id="viewResolver" 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> </beans>Sunday 13 May 2012 35
  36. 36. Praktické cvičeníSunday 13 May 2012 36
  37. 37. • Vytvořte beany pro • ReservationServiceImp • InMemoryBookStoreDao • inicializujte s několika knihami viz setter pro bookHolder • Vytvořte controller • vrátí seznam rezervací • použijte @RequestParam pro její vyfiltrování • vrátí konkrétní rezervaci • umožní vytvořit novou rezervaci (inspiraci hledejte v již naimplementovaných uživatelích) • použijte @PathVariable • validace vstupu • přidejte interceptor, ktery vypíše čas obsluhy • přidejte ErrorHandler, ktery bude logovat vyjímkySunday 13 May 2012 37

×