Spring MVC

37
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 . 1 Sunday 13 May 2012

description

* 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

Transcript of Spring MVC

Page 1: Spring MVC

Spring frameworkMotto: 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.

1Sunday 13 May 2012

Page 2: Spring MVC

Spring MVC

2Sunday 13 May 2012

Page 3: Spring MVC

Jak jsme se tam dostali

3Sunday 13 May 2012

Page 4: Spring MVC

Š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>");%>

4Sunday 13 May 2012

Page 5: Spring MVC

Nevýhody

• Znovupoužitelnost

• Míchání odpovědností

• prezentační a aplikační logika dohromady

• nemožnost alternativní reprezentace

• Špatná testovatelnost5Sunday 13 May 2012

Page 6: Spring MVC

MVC• Oddělení odpovědností

• Aplikační chování

• Data a jejich reprezentaci

• Obecný návrhový vzor

• Desktop, klientské frameworky

• JavaScript - SproutCore

• Swing6Sunday 13 May 2012

Page 7: Spring MVC

MVC• Model

• Date

• Controller

• Aplikační chování

• View

• Prezentace Modelu

7Sunday 13 May 2012

Page 8: Spring MVC

MVC v prostředí web framew.

8Sunday 13 May 2012

Page 9: Spring MVC

Web frameworky

9Sunday 13 May 2012

Page 10: Spring MVC

Spring MVC

• XML, Anotace

• Dependency Injection

• SPEL, Validace

• Koncepty zůstavají zachované

10Sunday 13 May 2012

Page 11: Spring MVC

Odbavení požadavku

11Sunday 13 May 2012

Page 12: Spring MVC

Aplikační context

12Sunday 13 May 2012

Page 13: Spring MVC

Základní anotace

• @Controller

• @RequestMapping

• @PathVariable

• @RequestParam

13Sunday 13 May 2012

Page 14: Spring MVC

Controller

• @Controller

• Vstupní bod

• Mapování na konkretní URL path

• Bridge HTTP/Aplikační logika

• Měl by být jednotkově testovatelný

14Sunday 13 May 2012

Page 15: Spring MVC

Controller ukázka

@Controllerpublic class UserController {

@Autowired private UserStorageDao userStorageDao;

@RequestMapping("/users.htm") public ModelMap usersHandler() { return new ModelMap("users", userStorageDao.getAll()); }

}

15Sunday 13 May 2012

Page 16: Spring MVC

@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 match

16Sunday 13 May 2012

Page 17: Spring MVC

@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"; }}

17Sunday 13 May 2012

Page 18: Spring MVC

Path mapping@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(); } ...

třída definuje první část cesty

metody definují zbytek

18Sunday 13 May 2012

Page 19: Spring MVC

Path mapping

@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(); } ...

http://myapp/appointments/2011-01-01

http://myapp/appointments/new

19Sunday 13 May 2012

Page 20: Spring MVC

@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"; }}

HTTP method mappingmapping na konkrétní HTTP metodu

20Sunday 13 May 2012

Page 21: Spring MVC

Podmínečný mapping

@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 }}

@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 }}

HTTP hlavičkou

Query parametrem

21Sunday 13 May 2012

Page 22: Spring MVC

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.SessionStatus

22Sunday 13 May 2012

Page 23: Spring MVC

@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"; }

23Sunday 13 May 2012

Page 24: Spring MVC

@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"; }

http://myapp/owners/1

24Sunday 13 May 2012

Page 25: Spring MVC

@PathVariable• @PathVariable typ může být pouze

základní typ (long, String)

• Pro další typy =>PropertyEditor

@Controllerpublic 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)); }}

25Sunday 13 May 2012

Page 26: Spring MVC

@ModelAttribute

• Přednahrání dat do formuláře

• Propojení modelu do konverzačního schématu

• obsluha formuláře

26Sunday 13 May 2012

Page 27: Spring MVC

Přednahrání modelu

public class EditPetForm {

// ...

@ModelAttribute("types") public Collection<PetType> populatePetTypes() { return this.clinic.getPetTypes(); }

@RequestMapping public void handle(@ModelAttribute Collection<PetType> types)

•metoda se volá ještě před vlastní handler metodou•model atributy lze namapovat do handler metody

27Sunday 13 May 2012

Page 28: Spring MVC

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"; }}

28Sunday 13 May 2012

Page 29: Spring MVC

Návratové typy

@RequestMapping(method = RequestMethod.POST)public XXX processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { … }

návratový typ

29Sunday 13 May 2012

Page 30: Spring MVC

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ý typ

30Sunday 13 May 2012

Page 31: Spring MVC

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";}

31Sunday 13 May 2012

Page 32: Spring MVC

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)32Sunday 13 May 2012

Page 33: Spring MVC

Interceptors

• Možnost reagovat před a po zpracování HTTP požadavku

• pre, post, after

• Vytvoření beany implementující• HandlerInterceptor

• HandlerInterceptorAdapter

33Sunday 13 May 2012

Page 34: Spring MVC

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>

34Sunday 13 May 2012

Page 35: Spring MVC

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>

35Sunday 13 May 2012

Page 36: Spring MVC

Praktické cvičení

36Sunday 13 May 2012

Page 37: Spring MVC

• 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ímky

37Sunday 13 May 2012