104
Spring Web MVC

Spring Web MVC

Embed Size (px)

DESCRIPTION

Spring Web MVC. Ievads. T īmekļa lietojumprogrammas ir iespējams programmēt pa tiešo izmantojot Java Servlet un JSP tehnoloģijas Eksistē vairāki tīmekļa lietojumprogrammu izstrādes ietvari (web application frameworks), kuri atbalsta dinamisko tīmekļa lietojumprogrammu izstrādi - PowerPoint PPT Presentation

Citation preview

Page 1: Spring Web MVC

Spring Web MVC

Page 2: Spring Web MVC

Ievads

• Tīmekļa lietojumprogrammas ir iespējams programmēt pa tiešo izmantojot Java Servlet un JSP tehnoloģijas

• Eksistē vairāki tīmekļa lietojumprogrammu izstrādes ietvari (web application frameworks), kuri atbalsta dinamisko tīmekļa lietojumprogrammu izstrādi

• Piemēri: Spring MVC , Play!, JSF, Struts, Tapestry, Stripes, Wicket un daudzi citi

Page 3: Spring Web MVC

Spring

• Spring ir atklāta koda Java/JavaEE lietojumprogrammu izstrādes ietvars

• Viens no interesantākiem

komponentiem ir

Spring Web MVC

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/overview.html

Page 4: Spring Web MVC

Tīmekļa lietojumprogrammu uzdevumi

• Tipiskie un svarīgie uzdevumi, kuri ir jāatrisina izstrādājot tīmekļa lietojumprogrammu :• Stāvokļu pārvaldība (state management)• Darba plūsma (workflow)• Validācija

• Spring MVC ietvars ir uzprojektēts, lai palīdzēt izstrādātājiem risināt šīs problēmas

Page 5: Spring Web MVC

Model-View-Controller Pattern

• Model-View-Controller (MVC) ir arhitektūras paraugs (aprakstīts 1979. gadā, Smalltalk valodā)

• Pamata mērķis: atdalīt datus (Model) no

lietotāja interfeisa (View)

• MVC atrisina

problēmu ieviešot

starpnieka komponenti - kontrolieri (Controller)

Page 6: Spring Web MVC

Model-View-Controller Pattern

• Model - Represents enterprise data and the business rules.

• View - Renders the contents of a model. Accesses enterprise data through the model and specifies how that data should be presented.

• Controller - Translates interactions with the view (button clicks, menu selections) into actions to be performed by the model (activating processes, changing the state of the model).

http://ash-mvc.org/

Page 7: Spring Web MVC

Spring MVC application architecture

• Spring MVC applications are broken down into a series of layers

• A layer is a discrete, orthogonal area of concern within an application

General, high-level layers in a web application

Page 8: Spring Web MVC

Spring MVC application layers

• Typical Spring MVC applications have at least five layers of abstraction

• Isolating problem domains into separate layers creates a flexible and testable application

• The interface is a contract for a layer, making it easy to keep implementations and their details hidden while enforcing correct layer usage

Page 9: Spring Web MVC

Spring MVC application layers

• The user interface layer (also known as the view) is responsible for rendering output for the client

• The web layer manages the user’s navigation through the site

• The service layer provides a stateless, coarse-grained interface for clients to use for system interaction

• The domain model is the collection of nouns in the system, it also contains the business logic of the system

• The data access layer is responsible for interfacing with the persistence mechanism to store and retrieve instances of the object model

Page 10: Spring Web MVC

Required JAR dependencies

Maven dependency configuration (for Spring 3.1.3):<dependency>

<groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.1.3.RELEASE</version>

</dependency>

<dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>3.1.3.RELEASE</version>

</dependency>

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version>

</dependency>

Page 11: Spring Web MVC

Spring MVC komponenti

Spring MVC sastāv no vairākiem komponentiem, starp kuriem notiek sadarbība apstrādājot klienta pieprasījumu

Page 12: Spring Web MVC

Pieprasījuma dzīves cikls (1)

• Klients sūta pieprasījumu, kurš tiek nodots DispatcherServlet komponentam

• Visi pieprasījumi vienmēr tiek nodoti vienam servletam, kuru

sauc par

priekšējo kontrolieri

(front controller)

Page 13: Spring Web MVC

Pieprasījuma dzīves cikls (2)

• Komponents, kurš atbild par pieprasījuma apstrādi ir Controller

• Lai nolemt kuram kontrolierim atdot

pieprasījumu, DispatcherController

izmanto

HandlerMapping

komponentus

• HandlerMapping:

URL piesaistīšana kontrolieriem

Page 14: Spring Web MVC

Pieprasījuma dzīves cikls (3-4)

• Kad DispatcherServlet ir izvēlējies kontroliera objektu, tad parsūta tam pieprasījumu, lai kontrolieris izpilda biznesa loģiku

• Pēc darba pabeigšanas Controller atgriež ModelAndView objektu

• ModelAndView saturView objektu vaiskata loģisko vārdu un modeli

Page 15: Spring Web MVC

Pieprasījuma dzīves cikls (5)

• Ja ModelAndView objekts satur skata loģisko vārdu, tad DispatcherServlet izmanto ViewResolver komponenti

• ViewResolver

atrod atbilstošu

View objektu,

lai attēlot atbildi

klientam

Page 16: Spring Web MVC

Pieprasījuma dzīves cikls (6)

• Visbeidzot, DispatcherServlet atdod pieprasījumu tam View objektam, uz kuru norāda ModelAndView

• View objekts ir atbildīgs par pieprasījumaatbildes atgriešanu un parādīšanu klientam

Page 17: Spring Web MVC

Spring MVC sequence diagram

Page 18: Spring Web MVC

Front Controller

• At the heart of Spring MVC is DispatcherServlet, a servlet that functions as a front controller

• A front controller is a common web-application pattern where a single servlet delegates responsibility for a request to other components of an application to perform the actual processing

Page 19: Spring Web MVC

Processing workflow

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

Page 20: Spring Web MVC

DispatcherServlet config

Jākonfigurē programmas/WEB-INF/web.xml failā:

<servlet> <servlet-name>training</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup></servlet>

Nākamais solis ir nodefinēt servlet mapping:

<servlet-mapping><servlet-name>training</servlet-name><url-pattern>/training/*</url-pattern>

</servlet-mapping>

Page 21: Spring Web MVC

DispatcherServlet context

• WebApplicationContext tiek ielādēts no faila:

training-servlet.xml

kurš atrodas direktorijā WEB-INF (blakus web.xml failam)

• Ir iespējams arī sadalīt

konfigurāciju starp

vairākiem failiem

Page 22: Spring Web MVC

Context hierarchy in Spring Web MVC

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html

Page 23: Spring Web MVC

Konfigurācijas faila piemērs

<?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

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- the application context definition for the DispatcherServlet -->

</beans>

• DispatcherServlet konfigurācijas faila piemērs:

• Šīs fails satur bean definitions, kurus izmanto DispatcherServlet

Page 24: Spring Web MVC

Vienkāršas Web lapas izveidošana

Nepieciešamie soļi, lai izveidot Web lapu ar Spring MVC:

1. Uzrakstīt kontroliera klasi, kas izpildīs biznesa loģiku

2. Iekonfigurēt kontrolieri DispatcherServlet konteksta konfigurācijas failā (training-servlet.xml)

3. Iekonfigurēt view resolver, kurš piesaistīs kontrolieri pie JSP

4. Uzrakstīt JSP, kas attēlos lapu klientam

Page 25: Spring Web MVC

Kontrolieru izveidošanas veidi

Ir divi pamata kontrolieru izveidošanas veidi:

• [pirms 2.5] Paplašināt klases no piedāvātas kontrolieru hierarhijas

• [sākot no 2.5] Izmantot anotācijas

Page 26: Spring Web MVC

Kontroliera izveidošana ( < 2.5 stils)import org.springframework.web.servlet.mvc.Controller;import org.springframework.web.servlet.ModelAndView;

public class HomeController implements Controller {

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

return new ModelAndView("home", "message", greeting); }

private String greeting; public void setGreeting(String greeting) { this.greeting = greeting; }}

• Nodarbojas ar pieprasījuma apstrādāšanu• Pamata metodes signatūra ir līdzīga servleta

service() metodei• Atgriež ModelAndView objektu

Page 27: Spring Web MVC

Kontroliera konfigurēšana

• Kontrolieri ir jāieraksta DispatcherServlet konteksta konfigurācijas failā (training-servlet.xml) :

<bean name="/home" class="com.springinaction.training.mvc.HomeController"><property name="greeting"> <value>Welcome to Spring Training!</value></property></bean>

• The default handler mapping is BeanNameUrlHandlerMapping, which uses the base name as the URL pattern

• When a request comes with a URL that ends with “/home”, DispatcherServlet will dispatch the request to HomeController

Page 28: Spring Web MVC

Kontroliera izveidošana ( >= 2.5 stils)@Controller

public class HomeController {

@RequestMapping("/home")

public ModelAndView helloWorld() {

ModelAndView mav = new ModelAndView();

mav.setViewName("home");

mav.addObject("message", greeting);

return mav;

}

private String greeting;

public void setGreeting(String greeting) {

this.greeting = greeting;

}

}

Lai izmantot anotācijas ir nepieciešama papildus konfigurācija!Lai izmantot anotācijas ir nepieciešama papildus konfigurācija!

Page 29: Spring Web MVC

Enable annotation support

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- Enable autodetection of annotated controllers -->

<context:component-scan base-package="com.web.music.portal.mvc"/>

<bean class="org.springframework.web.servlet.mvc

.annotation.DefaultAnnotationHandlerMapping"/> . . .

</beans>

Page 30: Spring Web MVC

View Resolver deklarēšana• View resolver darbs ir pēc skata loģiska vārda (kurš ir

atgriezts ModelAndView objektā) atrast pašu skatu

• Viens no variantiem ir izmantot skata vārdu kā JSP faila vārdu (jāieraksta training-servlet.xml):<bean id="viewResolver" class="org.springframework.web.

servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property></bean>

“home” /WEB-INF/jsp/home.jsp

Page 31: Spring Web MVC

JSP izveidošana

• Pēdējais kas palika – izveidot pašu JSP

<%@ page session="false"%><%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>

<html><head><title>Spring Training, Inc.</title></head><body><h2><c:out value="${message}"/></h2></body></html>

• Failu ir jānosauc par “home.jsp” un ir jāieliek /WEB-INF/jsp/ direktorijā

Page 32: Spring Web MVC

JSTL konfigurēšana

Lai izmantot JSTL (c:out tagu) JSP lapā, ir nepieciešamas papildus bibliotēkas• Step 1: download standard.jar and jstl.jar

• Step 2: ensure that both files are packaged in /WEB-INF/lib directory of WAR file

• Step 3: Write JSP file that can use core tags

<dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version></dependency>

<dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.1.2</version></dependency>

Page 33: Spring Web MVC

Rezultāta apskatīšana

• Palika izveidot tīmekļa lietojumprogrammas WAR failu (mvn package) un palaist to uz servera

• Pārlūkprogrammā uzrakstīt URL:http://localhost:8080/my_app/training/home.htm

Page 34: Spring Web MVC

Kopsavilkums

Page 35: Spring Web MVC

HandlerMapping

• Tipiski piesaista specifisku kontrolieri pie URL adreses parauga

• Spring piedāvā sekojošas noderīgas HandlerMapping implementācijas

• DefaultAnnotationHandlerMapping

• BeanNameUrlHandlerMapping

• SimpleUrlHandlerMapping

Page 36: Spring Web MVC

DefaultAnnotationHandlerMapping

• Introduced in Spring 2.5 - maps handlers based on HTTP paths expressed through the @RequestMapping annotation inside controller classes annotated with @Controller

• Registered by default in DispatcherServlet on Java 5+

Page 37: Spring Web MVC

BeanNameUrlHandlerMapping

• Piesaista URL adresi pie kontroliera, kurš ir reģistrēts konfigurācijas failā ar tādu pašu vārdu• e.g. /simple.htm maps to a bean named “/simple.htm”

• Ir jāizmanto name atribūtu, jo “/” nav atļauts XML atribūtā id

<bean class="org.springframework.web.servlet. handler.BeanNameUrlHandlerMapping"/>

<bean name="/simple.htm" class="com.mvc.web.SimpleController">. . .</bean>

Page 38: Spring Web MVC

SimpleUrlHandlerMapping

• Pats vispārīgs veids kā piesaistīt pieprasījuma URLus kontrolieriem

• Tiek konfigurēts kā saraksts no name/value pāriem (URL/kontrolieru vārds)

<bean id="simpleUrlMapping" class="org.springframework.web .servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings"> <props> <prop key="/listCourses.htm">listCoursesController</prop> <prop key="/register.htm">registerStudentController</prop> <prop key="/displayCourse.htm">displayCourseController</prop> </props> </property></bean>

Page 39: Spring Web MVC

Multiple handler mappings

• Ir iespējams deklarēt vairākus handler mappings vienā lietojumprogrammā

• Handler mapping klases implementē Spring Ordered interfeisu

• Var uzstādīt order īpašību, lai norādīt izpildes kārtību attiecībā uz citiem handler mapping komponentiem

Page 40: Spring Web MVC

Multiple handler mappings

<bean id="beanNameUrlMapping" class="org.springframework.web.

servlet.handler.BeanNameUrlHandlerMapping">

<property name="order"><value>1</value></property></bean>

<bean id="simpleUrlMapping" class="org.springframework.web.

servlet.handler.SimpleUrlHandlerMapping"> <property name="order"><value>0</value></property> <property name="mappings"> … </property></bean>

Page 41: Spring Web MVC

Kontrolieri

Ja DispatcherServlet ir Spring MVC sirds, tad kontrolieri ir smadzenes

Page 42: Spring Web MVC

Kontrolieru hierarhija ( < 2.5)

• Spring piedāvā bagātu kontrolieruhierarhiju

• Hierarhijas virsotnē atrodas Controller interfeiss

• Parasti ir jāizmantokādu no implementācijas apakšklasēm

Page 43: Spring Web MVC

AbstractController

Pats vienkāršākais kontrolieris

public class SampleController extends AbstractController {

public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {

return new ModelAndView("hello", "message", "Hello World!");

}}

Page 44: Spring Web MVC

ModelAndView objekts

• Iekapsulē skatu un modeļa datus, kurus skats attēlos

• Modelis ir realizēts kā java.util.Map

• Ērts konstruktors viena modeļa objekta gadījumam:

ModelAndView(

String viewName,

String modelName,

Object modelObject)

Page 45: Spring Web MVC

ModelAndView objekts

Ir iespējams arī pievienot modelim vairākus objektus:

public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {

ModelAndView mav = new ModelAndView("welcome"); mav.addObject("message1", "Welcome!"); mav.addObject("message2", "Nice to see you!"); return mav; }

Page 46: Spring Web MVC

Parametru apstrāde

Web pieprasījums bieži satur vienu vai vairākus parametrus

Kādā veidā varētu piekļūt parametriem kontroliera kodā???

<form action="/login" method="POST"> Login: <input id=“login" name="login"/> Password: <input id="password" name="password" type="password"/> <input type="submit" value="Login"/></form>

Page 47: Spring Web MVC

Risinājums

Varētu izmantot AbstractController un nolasīt parametrus no HttpServletRequest

public ModelAndView handleRequestInternal( HttpServletRequest request, HttpServletResponse response) throws Exception {

String login = request.getParameter("login"); String pass = request.getParameter("password"); . . .}

Spring piedāvā ērtāku iespēju!

Page 48: Spring Web MVC

AbstractCommandController

• Automātiski ieraksta parametrus speciālajā komandas objektā (command object)

• Ir iespēja pievienot validatoru, lai nodrošināt to, ka parametri ir pareizi

• Galvenā izpildes metode:

handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)

Page 49: Spring Web MVC

AbstractCommandController

public class DisplayCourseController extends AbstractCommandController {

public DisplayCourseController() {

setCommandClass(DisplayCourseCommand.class);

}

protected ModelAndView handle(HttpServletRequest request,

HttpServletResponse response, Object command,

BindException errors) throws Exception {

DisplayCourseCommand displayCommand =

(DisplayCourseCommand) command;

Course course = courseService.getCourse(displayCommand.getId());

return new ModelAndView("courseDetail", "course", course);

}

Page 50: Spring Web MVC

Command Object

• A command object is a bean that is meant to hold request parameters for easy access

public class DisplayCourseCommand {private Integer id;public void setId(Integer id) {

this.id = id;}public Integer getId() {

return id;}

}

• Spring will attempt to match any parameters passed in the request to properties in the command object

Page 51: Spring Web MVC

Binding a Form to a Bean

• DataBinder is responsible for setting object properties from expression strings and their values

• These expressions, in the form of property.property[2].property, are the names of HTML fields inside HTML forms

• The values come from the submitted HTTP request parameters

name.firstName=joe getName().setFirstName("joe")

Page 52: Spring Web MVC

Binding a Form to a Bean

• The DataBinder supports setting properties of type String, primitives, and nearly any type, through its use of PropertyEditors

• You can also bind to properties of objects that live inside collections, such as Sets, arrays, Lists, and Maps

• You can create and register your own PropertyEditor to meet your specific needs

Page 53: Spring Web MVC

Defining custom property editor

To create and register your own custom property editor override initBinder method in your controller

@Overrideprotected void initBinder(HttpServletRequest request,

ServletRequestDataBinder binder) throws Exception

{ binder.registerCustomEditor(Date.class, new CustomDateEditor(

new SimpleDateFormat("yyyy-MM-dd"), false));}

Page 54: Spring Web MVC

Pārskats

Page 55: Spring Web MVC

Formu apstrāde

• Tipiska tīmekļa lietojumprogramma satur vismaz vienu formu

• Lietotājs aizpilda formu un aizsūta to• Dati tiek nosūtīti serverim• Kad datu apstrāde ir pabeigta, lietotājs saņem

vienu no variantiem:• Lapa ar veiksmīgas izpildes paziņojumu• Formas lapa ar kļūdu paziņojumiem

Kādā veidā varētu to realizēt???

Page 56: Spring Web MVC

Risinājums

• Izmantot AbstractController formas attēlošanai

• Izmantot AbstractCommandController formas apstrādei

• Trūkums: vajag uzturēt divus dažādus kontrolierus, kuri kopā nodarbojas ar viena uzdevuma risināšanu

Page 57: Spring Web MVC

SimpleFormController

Formu kontroliera funkcionalitāte:• Attēlo formu uz HTTP GET pieprasījuma

• Apstrādā formu uz HTTP POST pieprasījuma

• Ja notiek kļūda, tad atkārtoti parāda formu

public class PersonFormController extends SimpleFormController {

public PersonFormController() {setCommandClass(Person.class);

}

public void doSubmitAction(Object command){Person person = (Person)object;personService.save(person);

}. . .}

Page 58: Spring Web MVC

Formas JSP

Spring piedāvā speciālu formas tagu bibliotēku

<%@ page session="false"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><html><body><h1>Add new Person</h1>

<form:form commandName="person"> <form:hidden path="id"/> <label for="name">Name</label> <form:input path="name"/> <label for="surname">Surname</label> <form:input path="surname"/> <input type="submit" value="Save"/></form:form>

</body></html>

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/spring-form.tld.html

Page 59: Spring Web MVC

SimpleFormController config

• Kontrolieris ir uzprojektēts tādā veidā, lai pēc iespējas vairāk atdalīt skatu detaļas no kontroliera koda

<bean name="personFormController" class="com.web.music.portal.mvc.PersonFormController">

<property name="formView" value="add_person_form"/> <property name="successView"

value="person_added"/> <property name="commandName"

value="person"/> . . .</bean>

HTTP GET

• Ja ir nepieciešams aizsūtīt datus skatam, tad vajag izmantot onSubmit() metodi

Page 60: Spring Web MVC

Formu validācija

• Viens no svarīgiem uzdevumiem ir formas datu validācija

• Par validāciju atbild sekojošais interfeisspublic interface Validator { void validate(Object obj, Errors errors); boolean supports(Class clazz);}

• Implementējot interfeisa validate() metodi vajag pārbaudīt objekta atribūtu vērtības un noraidīt nepareizas vērtības izmantojot Errors objektu

Page 61: Spring Web MVC

Validatora piemērspublic class PersonFormValidator implements Validator {

public boolean supports(Class givenClass){ return givenClass.equals(Person.class);}

public void validate(Object obj, Errors errors){ Person person = (Person)obj; if (person == null) errors.reject("error.nullpointer", "Null data received"); else{ if (person.getName().equals("")){ errors.rejectValue(

"name", "error.empty", "Name is required!"); } if (person.getSurname().equals("")){ errors.rejectValue(

"surname", "error.empty", "Surname is required!"); } }}}

Page 62: Spring Web MVC

Validatora reģistrēšana

Validatoru vajag piesaistīt kontrolierim konfigurācijas failā

<bean id="registerStudentController" class="com.springinaction.training.mvc.

RegisterStudentController">… <property name="validator"> <bean class="com.web.music.portal.

mvc.PersonFormValidator"/> </property></bean>

Page 63: Spring Web MVC

Kļūdu attēlošana formā

<form:form commandName="person">

<form:hidden path="id"/>

<p><label for="name">Name</label></br> <form:input path="name"/> <form:errors path="name" cssStyle="color: red"/> </p>

<p><label for="surname">Surname</label></br> <form:input path="surname"/> <form:errors path="surname" cssStyle="color: red" /> </p>

<p><input type="submit" value="Save"/></form:form>

Page 64: Spring Web MVC

Objekta modificēšana tajā pašā formā

• Jauna objekta pievienošanas un eksistējoša objekta modificēšanas formas bieži ir identiskas

• Abiem gadījumiem ir iespējams izmantot vienu un to pašu SimpleFormController

• Lai attēlot formā eksistējoša objekta datus ir nepieciešams kā parametru padot objekta ID

<c:forEach var="person" items="${person_list}"><a href="/music-portal/music/add_person?id=${person.id}"> <c:out value="${person.id}"/></a><br></c:forEach>

Page 65: Spring Web MVC

Metode formBackingObject

• Metode ir definēta klasē AbstractFormController

• Pēc noklusējuma atgriež jauno commandClass instanci, kas ir iekonfigurēts kontrolierim

• Metodi var pārrakstīt, piemērām, lai ielādēt objektu no datubāzes (to objektu, kuru tālāk modificēs formā)

• Lai izmantot form-backing objektu visā formas darba plūsmā (lai uz POST pieprasījumu netiktu izveidota jauna instence) ir jāaktivizē sesijas formas režīmu (sessionForm = true)

Page 66: Spring Web MVC

Piemērs: formBackingObjectpublic class PersonFormController extends SimpleFormController{

public PersonFormController(){ setCommandClass(Person.class); setSessionForm(true); }

@Override protected Object formBackingObject(HttpServletRequest request){ Person person = new Person(); if (!isFormSubmission(request)){ String idString = request.getParameter("id"); if (idString != null && !idString.equals("")) { long id = Long.parseLong(request.getParameter("id")); person = personService.getById(id); } } return person; } . . .}

Page 67: Spring Web MVC

onSubmit metodes

• Ir piedāvātas vairākas metodes, kur var apstrādāt formas iesniegšanu (submit)

• Nākamajā slaidā ir attēlota SimpleFormController aktivitāšu diagramma (activity diagram)

SimpleFormController

Page 68: Spring Web MVC

Expert Spring MVC And Web Flow

Page 69: Spring Web MVC

Metode referenceData

• Metode ir definēta klasē SimpleFormController

• Dod iespēju savākt kopā un atgriezt palīgobjektus (piemērām, objektu sarakstus combo-box elementiem), kuri ir nepieciešami, lai attēlot formu

• Pirms rādīt formu, kontrolieris izveidos kombinētu modeli, kur savienos formas objektu, modeli no referenceData() un iespējamas kļūdas un aizsūtīs to skatam

Page 70: Spring Web MVC

Piemērs: referenceData

@Overrideprotected Map referenceData(HttpServletRequest request) throws Exception { Map data = new HashMap();

List<Language> languages = loadLanguages(); data.put("languages", languages);

List<Country> countries = loadCountries(); data.put("countries", countries);

return data;}

Page 71: Spring Web MVC

Redirect After Submit pattern

• There is a common problem with the handling the display of the confirmation page

• The success view is rendered in the same request as the initial POST, leaving the browser in a state with the ability to replay the form submit

• The user can simply reload the page, resubmitting the form

Page 72: Spring Web MVC

Redirect After Submit pattern

• Redirect After Submit pattern simply redirects the user to the success view instead of internally forwarding the request

• A client redirect is not the same as a RequestDispatcher.forward()• Forwarding method internally redirect a request to

another handler inside the servlet container

• A client redirect instructs the client to issue another GET request

Page 73: Spring Web MVC

Spring’s support for redirect

• Special class exists for this purposeorg.springframework.web.servlet.view.RedirectView

• Spring MVC provides shorthand for redirect views

• The UrlBasedViewResolver (the superclass for InternalResourceViewResolver) recognizes the special prefix redirect: <bean name="personFormController"

class="com.web.music.portal.mvc.PersonFormController"> . . . <property name="successView" value="redirect:person_listall"/> . . .</bean>

Page 74: Spring Web MVC

Annotation-based controller configuration

• Spring 2.5 introduces an annotation-based programming model for MVC controllers, using annotations such as • @Controller• @RequestMapping• @RequestParam• @ModelAttribute • etc

Page 75: Spring Web MVC

Enable annotation support

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- Enable autodetection of annotated controllers -->

<context:component-scan base-package="com.web.music.portal.mvc"/>

<bean class="org.springframework.web.servlet.mvc

.annotation.DefaultAnnotationHandlerMapping"/> . . .

</beans>

Page 76: Spring Web MVC

Annotated controller 1@Controller@RequestMapping("/genre_listall")public class ListAllGenreController {

// need to configure this bean in XML

private GenreService genreService;

@Autowired public ListAllGenreController(GenreService genreService){ this.genreService = genreService; }

@RequestMapping(method = RequestMethod.GET) public String listAllGenres(ModelMap model) {

List<Genre> genres = genreService.findAll();model.addAttribute("list", genres);return "genre_listall";

}}

Page 77: Spring Web MVC

Annotation-based controllers

• The @Controller annotation acts as a stereotype for the annotated class, indicating its role

• The dispatcher scans such annotated classes for mapped methods and detects @RequestMapping annotations

• @RequestMapping annotation maps URLs such as /appointments onto an entire class or a particular handler method

Page 78: Spring Web MVC

Annotated controller 2-1

@Controller

@RequestMapping("/add_genre")

@SessionAttributes("genre")

public class GenreFormController {

// need to configure in XML

private GenreService genreService;

private GenreFormValidator genreFormValidator;

@Autowired

public GenreFormController(GenreService genreService, GenreFormValidator

genreFormValidator){

this.genreService = genreService;

this.genreFormValidator = genreFormValidator;

}

. . .

Page 79: Spring Web MVC

Annotated controller 2-2. . .@RequestMapping(method = RequestMethod.GET)public String setupForm( @RequestParam(required = false, value = "id") Long genreId, ModelMap model) { Genre genre = new Genre(); if (genreId != null && !genreId.equals("")) {

genre = genreService.getById(genreId);}

model.addAttribute("genre", genre); return "add_genre_form";}. . .

Page 80: Spring Web MVC

Annotated controller 2-3. . .@RequestMapping(method = RequestMethod.POST)public String processSubmit(

@ModelAttribute("genre") Genre genre, BindingResult result, SessionStatus status) {

genreFormValidator.validate(genre, result);

if (result.hasErrors()) { return "add_genre_form"; } else { genreService.save(genre); status.setComplete(); return "redirect:genre_listall";

} }. . .

Page 81: Spring Web MVC

Method arguments and return types

• Request or response objects (ServletRequest or HttpServletRequest)

• Session object (HttpSession)

• WebRequest or NativeWebRequest - Allows for generic request parameter access as well as request/session attribute access

• @PathVariable annotated parameters for access to URI template variables

• @RequestParam annotated parameters for access to specific Servlet request parameters

Page 82: Spring Web MVC

Method arguments and return types

• @RequestHeader annotated parameters for access to specific request HTTP headers

• @RequestBody annotated parameters for access to the HTTP request body

• HttpEntity<?> parameters for access to the Servlet request HTTP headers and contents

• Map / Model / ModelMap for enriching the implicit model that is exposed to the web view

• ...

Page 83: Spring Web MVC

Check-box list in the form [1-2]

<form:form commandName="order">

...

<h3>Select items:</h3>

<table>

<c:forEach var="item" items="${items}">

<tr><td>

<form:checkbox path="selectedIds" value="${item.id}"/>

<c:out value="${item.description}" />

</td></tr>

</c:forEach>

</table>

...

</form:form>

Mapping collection of ids in the form:

Page 84: Spring Web MVC

Check-box list in the form [2-2]

public class Order {

...

private List<Long> selectedIds;

...

public List<Long> getSelectedIds() {

return selectedIds;

}

public void setSelectedIds(List<Long> invitedIds) {

this.selectedIds = invitedIds;

}

}

Form baking object:

Page 85: Spring Web MVC

Vairāku darbību apstrāde• Visi līdz šīm apskatītie kontrolieri pildīja kādu

vienu uzdevumu• Veidot vairākus kontrolierus, lai pildīt līdzīgus

uzdevumus, nav īsti racionāli• Piemērām, vajag attēlot kursu sarakstu dažādos

variantos:• Nesakārtotā veidā• Sakārtoti pēc datuma• Sakārtoti pēc nosaukuma

Kādā veidā varētu to realizēt???

Page 86: Spring Web MVC

MultiActionControllerpublic class ListAllArtistController extends MultiActionController {

private ArtistService artistService;

public ModelAndView all(HttpServletRequest request, HttpServletResponse response) {

return doSearch(ArtistType.ALL); }

public ModelAndView singer(HttpServletRequest request, HttpServletResponse response) {

return doSearch(ArtistType.SINGER); }

public ModelAndView band(HttpServletRequest request, HttpServletResponse response) {

return doSearch(ArtistType.MUSIC_BAND); }. . .}

Page 87: Spring Web MVC

Metodes vārda noteikšana

The MethodNameResolver is supposed to resolve method names based on the request coming in:

• ParameterMethodNameResolver

• Resolves the execution method name based on a parameter in the request

• InternalPathMethodNameResolver

• Retrieves the filename from the path and uses that as the method name

• PropertiesMethodNameResolver

• Resolves the name of the execution method by consulting a list of key/value pairs

Page 88: Spring Web MVC

ParameterMethodNameResolver<bean name="listallArtistController“

class="com.web.music.portal.mvc.ListAllArtistController">

<property name="artistService" ref="artistService"/>

<property name="methodNameResolver">

<ref bean="listallArtistMethodResolver"/>

</property>

</bean>

<bean id="listallArtistMethodResolver“

class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">

<property name="paramName"><value>mode</value></property>

</bean>

<bean id="urlMapping"

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

<property name="mappings">

<props>

<key="/artist_listall">listallArtistController</prop>

</props>

</property>

</bean>

Page 89: Spring Web MVC

Vienkāršāk ar anotācijām@Controller

public class DisplaySubjectController {

@RequestMapping(value = "/subject", method = RequestMethod.GET)

public String displayStartPage(ModelMap model, HttpSession session,

@RequestParam(value = ATTR_ID) Long subjectId) {...}

@RequestMapping(value = "/userActionForSubject", params = "addComment", method = RequestMethod.POST)

public String addNewComment(ModelMap model, HttpSession session,

@RequestParam(value = "subject_id") Long subjectId,

@RequestParam(value = "comment_text") String commentText) {...}

@RequestMapping(value = "/userActionForSubject", params = "addFavourite", method = RequestMethod.POST)

public String addFavourite(ModelMap model, HttpSession session,

@RequestParam(value = "subject_id") Long subjectId,

@RequestParam(value = "comment_text") String commentText) {...}

...

Page 90: Spring Web MVC

Wizard (daudzekrānu) formas

Uzdevums – realizēt aptaujas formu ar 40 jautājumiem

Variants – izmantot SimpleFormController, izvietot visus jautājumus vienā lapā.Bet tas nav ērti lietotājam!

Kādā veidā varētu to realizēt???

Page 91: Spring Web MVC

Wizard formas

• Spring piedāvā kontrolieri, kas atbild par secīgu virzīšanos cauri vairākām lapām

AbstractWizardFormController

• Līdzīgs parastai formai, bet ir iespējams validēt datus pa daļām (katrā ekrānā savu daļu)

• Formas apstrāde parasti notek pašās beigās

• Ir iespēja visu procesu atcelt (cancel) jebkurā brīdī

Page 92: Spring Web MVC

Wizard formas kontrolieris

public class FeedbackWizardControllerextends AbstractWizardFormController {

public FeedbackWizardController() {setCommandClass(FeedbackSurvey.class);

}

protected ModelAndView processFinish(HttpServletRequest request,HttpServletResponse response, Object command,BindException errors) throws Exception {

FeedbackSurvey feedback = (FeedbackSurvey) command;feedbackService.submitFeedback(feedback);return new ModelAndView("thankyou");

}

Page 93: Spring Web MVC

Wizard formas konfigurēšana

• Formas kontroliera konfigurēšana

<bean id="feedbackController" class="com.springinaction.training.mvc.MyWizardController">

<property name="pages"> <list> <value>general</value> <value>instructor</value> <value>course</value> </list></property></bean>

• Šeit tiek definētas visas lapas

Page 94: Spring Web MVC

Wizard formas lapas

Pa lapām var pārvietoties ierakstot pieprasījumā parametru ar vārdu "_targetX", kur X ir lapas numurs

<form method="POST" action="feedback.htm">…<input type="submit" value="Back" name="_target1"> <input type="submit" value="Next" name="_target3"></form>

Page 95: Spring Web MVC

Wizard formas finish/cancel

• Formas pabeigšana - tiks izsaukta metode processFinish()

<input type="submit" value="Finish" name="_finish">

• Formas atcelšana - tiks izsaukta metode processCancel()

<input type="submit" value="Cancel" name="_cancel">

Page 96: Spring Web MVC

Wizard formas validācija

Formas komandas objekts tiek validēts pa lapām

protected void validatePage(Object command, Errors errors, int page) {

FeedbackSurvey feedback = (FeedbackSurvey) command;FeedbackValidator validator =

(FeedbackValidator) getValidator();if(page == 0) { validator.validateEmail(feedback.getEmail(), errors);}. . .}

Page 97: Spring Web MVC

Pārskats

Page 98: Spring Web MVC

ThrowawayController

• Nav Controller hierarhijas daļa

• Netiek izmantots HTTP pieprasījums vai komandas objekts

• Parametri tiek ierakstīti tieši kontrolierī• Ir noderīgi, kad nav modeļa objekta, kuru varētu

izmantot• Atšķirībā no citiem kontrolieriem, nav singleton

public interface ThrowawayController { ModelAndView execute() throws Exception;}

Page 99: Spring Web MVC

ThrowawayController

public class DisplayCourseController

implements ThrowawayController {

private Integer id;

public void setId(Integer id) { this.id = id; }

public ModelAndView execute() throws Exception {

Course course = courseService.getCourse(id);

return new ModelAndView(

"courseDetail", "course", course);

}

}

Page 100: Spring Web MVC

Interceptors

• Iespēja pievienot papildus funkcionalitāti pirms un pēc pieprasījuma (līdzīgi servletu filtriem)

• Satur divas interception metodes – preHandle un postHandle

• Satur vienu callback metodi –afterCompletion

• Tiek piesaistīts kontrolieru kopai kopā ar HandlerMapping

Page 101: Spring Web MVC

Piemērs: Interceptor config<beans> <bean id="handlerMapping" class="org.springframework.web.

servlet.handler.SimpleUrlHandlerMapping">

<property name="interceptors"> <list> <ref bean="officeHoursInterceptor"/> </list> </property> <property name="mappings"> <value> /*.form=editAccountFormController

</value> </property> </bean>

<bean id="officeHoursInterceptor" class="samples.TimeBasedAccessInterceptor"> <property name="openingTime" value="9"/> <property name="closingTime" value="18"/> </bean><beans>

Piesaista interceptoruvisiem pieprasījumiem

Page 102: Spring Web MVC

Piemērs: Interceptor kods

public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {

. . .

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

Calendar cal = Calendar.getInstance(); int hour = cal.get(HOUR_OF_DAY); if (openingTime <= hour < closingTime) { return true; } else { response.sendRedirect(

"http://host.com/outsideOfficeHours.html");

return false; } }}

Page 103: Spring Web MVC

Resursi

• Spring Homehttp://www.springsource.org/

• C. Walls, R.Breidenbach. Spring in Action • http://www.manning.com/walls2/

• Seth Ladd et al. Expert Spring MVC And Web Flowhttp://www.amazon.com/Expert-Spring-MVC-Web-Flow/dp/

159059584X

• Spring Web MVC Framework http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

Page 104: Spring Web MVC

Resursi

• Spring form tagshttp://static.springsource.org/spring/docs/current/spring-framework-reference/html/spring-form.tld.html