Spring EJB Spring 3 Spring EJB Spring 4
Spring чи EJB ? Spring 3
Spring чи EJB ? Spring 4
Spring Framework для Web (http: //www. springframework. org/documentation) Spring 7
Проекти Spring Web MVC Spring 9
Ілюстрація до проектів Spring Web MVC (http: //www. springframework. org/documentation) Spring 11
Ще одна ілюстрація до проектів Spring Web MVC Agile Java Development with Spring, Hibernate and Eclipse By Anil Hemrajani. . . Publisher: Sams Pub Date: May 09, 2006 Print ISBN-10: 0 -672 -32896 -8 Print ISBN-13: 978 -0 -672 -32896 -1 Spring 12 Pages: 360
Front Controller (Dispatcher. Servlet) та файл web. xml (дескрипторний файл web-проектів) <? xml version="1. 0" encoding="UTF-8"? > <web-app. . . > (Web-) контекст Web Application за замовчуванням задається у файлі /WEB-INF/springapp-servlet. xml. . . <servlet> <servlet-name> springapp </servlet-name> <servlet-class>org. springframework. web. servlet. Dispatcher. Servlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springapp 1</servlet-name> <url-pattern>*. htm</url-pattern> </servlet-mapping>. . . </web-app> Spring 15
Варіант використання кількох файлів конфігурації контексту. Файл web. xml <? xml version="1. 0" encoding="UTF-8"? > Listener Servlet – це “завантажувач контексту” <web-app. . . > (“Context Loader” ) проекту. (За замовчуванням. . . файлом конфігурації контексту виступає <listener> / WEB-INF/ application. Context. xml. ) <listener-class> org. springframework. web. context. Context. Loader. Listener </listener-class> </listener> <context-param> <param-name>context. Config. Location</param-name> <param-value> /WEB-INF/ application. Context. xml, /WEB-INF/ springapp-servlet. xml, Файл конфігурації “веб”контексту за замовчуванням /WEB-INF/ yet_app. Context. xml </param-value> </context-param>. . . </web-app> Spring 16
Використання Simple. Url. Handler. Mapping. Приклад Calc. S-servlet. xml <beans> (фрагмент) <bean id="url. Mapping" class= "org. springframework. web. servlet. handler. Simple. Url. Handler. Mapping"> <property name="mappings"> <props> <prop key="/calc. html">Controller</prop> <!-. . . --> </props> </property> </bean> <bean id="Controller" class="Sum. Controller" > </beans> Spring 18
Abstract. Controller. Spring MVC Web проект Hello (Hello World !) <beans> <bean name="/hello. htm" class="Hello. Controller"/> </beans> Hello-servlet. xml (фрагмент) public class Hello. Controller extends Abstract. Controller{ public Model. And. View handle. Request. Internal ( Http. Servlet. Request request, Http. Servlet. Response response){ return new Model. And. View("hello. jsp"); } } Abstract. Controller забезпечує базову підтримку GET та POST методів. Для цього прикладу можна обійтись і без розширення (extends) Abstract. Controller: public class Hello. Controller implements Controller {. . . } <html> <head><title>Spring Application</title></head> <body> <h 1>Hello World!</h 1> </body> hello. jsp Spring </html> 22
Model & View Клас Model. And. View (з пакету org. springframework. web. servlet) є контейнерним класом. Відповідні об'єкти містять дані стосовно View та Model. При цьому використовується досить високий рівень абстракції: Model. And. View mv = new Model. And. View(my. View, my. Model). • Клас View (org. springframework. web. servlet. View) забезпечує підтримку різних View-технологій: JSP, Excel, Pdf, Xslt, Free Marker, Html, Tiles, Velocity, Jasper Reports etc: return new Model. And. View("hello. jsp") (з попереднього слайду). • Об'єкти Model (класу org. springframework. ui. Model. Map) є по суті Mapоб'єктами, які містять додаткову інформацію, що використовується разом з View для візуального відображення: 1) Map my. Model = new Hash. Map(); Model. And. View mv = new Model. And. View(my. View, my. Model). 2) Map<String, Object> my. Model = new Hash. Map<String, Object>(); my. Model. put("now", now); Spring 24
Model. And. View. Приклади 1) Model. And. View mv = new Model. And. View("my. View. jsp", "var", var); 2) Model. And. View mav = new Model. And. View("calc. jsp"); mav. add. Object("z", z); mav. add. Object("x", x); mav. add. Object("y", y); // див. також наступний слайд 3) Model. And. View mv = new Model. And. View("my. View"). Тут my. View є логічним (іменем) View (Logical View) View Resolver: Logical View Physical View Location. my. View. jsp my. View. xml. . . + розташування Spring 25
Клас Abstract. Controller. Model. And. View. Приклад: Spring MVC Web проект Calc 1 Spring 26
Інтерфейс Controller. Model. And. View. Приклад: Spring MVC Web проект springapp public class Inventory. Controller implements Controller { private Product. Manager product. Manager; public Model. And. View handle. Request( Http. Servlet. Request request, Http. Servlet. Response response) throws Servlet. Exception, IOException { String now = (new java. util. Date()). to. String(); Map<String, Object> my. Model = new Hash. Map<String, Object>(); my. Model. put("now", now); my. Model. put("products", this. product. Manager. get. Products()); return new Model. And. View("hello", "model", my. Model); } } public void set. Product. Manager( Product. Manager product. Manager) { this. product. Manager = product. Manager; } Spring 27
Використання Simple. Form. Controller. Приклад. (1/5) Об'єкт "price. Increase” (class Price. Increase) Об'єкт форми priceincrease. jsp Simple. Form Controller <bean name="/priceincrease. htm" class= "Price. Increase. Form. Controller"> Контролер (фрагмент файлу springapp-servlet. xml) class Price. Increase. Form. Controller extends Simple. Form. Controller Spring 29
Використання Simple. Form. Controller. Приклад. (2/5) (Class Price. Increase. Form. Controller) public class Price. Increase. Form. Controller extends Simple. Form. Controller { public Model. And. View on. Submit (Object command) throws Servlet. Exception { int increase = ((Price. Increase) command). get. Percentage(); . . . return new Model. And. View(. . . ); } protected Object form. Backing. Object ( Http. Servlet. Request request) throws Servlet. Exception { Price. Increase price. Increase = new Price. Increase(); price. Increase. set. Percentage (20); return price. Increase; } } Життєвий цикл контролерів для web-сторінок із формами Spring 30
Використання Simple. Form. Controller. Приклад. (3/5) (Class Price. Increase) public class Price. Increase { private int percentage; public void set. Percentage(int i) { percentage = i; } public int get. Percentage() { return percentage; } Клас об'єкта форми } Spring 31
Використання Simple. Form. Controller. Приклад. (4/5) (Бін-контролер та його складові) Фрагмент конфігураційного (контекстного) файлу springapp-servlet. xml . . . <bean name="/priceincrease. htm» Клас біна class="Price. Increase. Form. Controller"> <property name="session. Form" value="true"/> <property name="command. Name" value="price. Increase"/> <property name="command. Class" value="Price. Increase"/> Зв'язок з “об'єктом форми” <property name="validator"> (“командним об'єктом”) <bean class="Price. Increase. Validator"/> </property> View, що містить форму <property name="form. View" value="priceincrease"/> <property name="success. View" value="hello. htm"/> <property name="product. Manager" ref="product. Manager"/> </bean> Spring 32
Використання Simple. Form. Controller. Приклад. (5/5) (Форма у priceincrease. jsp) Фрагменти файлу priceincrease. jsp <%@ taglib prefix="form" uri="http: //www. springframework. org/tags/form" %>. . . Командний об'єкт (“об'єкт форми”) <form: form method="post" command. Name="price. Increase">. . . <form: input path="percentage"/>. . . <input type="submit" align = "center" value="Execute"> </form: form>. . . Spring 33
Spring: арсенал View Resolver Чималий арсенал готових до використання варіантів View Resolver: – Internal. Resource. View. Resolver; – Bean. Name. View. Resolver; – Free. Marker. View. Resolver; – Jasper. Reports. View. Resolver; – Resource. Bundle. View. Resolver; – Url. Based. View. Resolver; – Velocity. Layout. View. Resolver; – Velocity. View. Resolver; – Xml. View. Resolver; – Xslt. View. Resolver. Spring 35
Клас Internal. Resource. View. Resolver. Приклад. <bean id="view. Resolver" class="org. springframework. web. servlet. view. Internal. Resource. View. Resolver"> <property name="view. Class» value="org. springframework. web. servlet. view. Jstl. View"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=". jsp"/> JSTL (JSP Standard Tag Library) </bean> Можливості захисту. Не можна безпосередньо дістатись до jsp- сторінок hello, priseincrease, задаючи у браузері їх імена, оскільки сторінки знаходяться у “внутрішньому” підкаталозі /WEB-INF/jsp/. Spring 36
? ? Bean. Name. View. Resolver. Приклад. Можливість динамічно генерувати View (не тільки за рахунок префіксу-суфіксу!). Приклад: return Model. And. View("pdf") <bean id="bean. Name. View. Resolver" class="org. springframework. web. servlet. view. Bean. Name. View. Resolver"/> <bean id = "pdf" class = "Pdf. Generator"/> public class Pdf. Generator extends org. springframework. web. servlet. view. document. Abstract. Pdf. View {…} Spring 37
Використання валідатора (Validator) (3/4) Price. Increase. Validator (початок) import org. springframework. validation. Validator; import org. springframework. validation. Errors; import org. apache. commons. logging. Log. Factory; public class Price. Increase. Validator implements Validator { private int DEFAULT_MIN_PERCENTAGE = 0; private int DEFAULT_MAX_PERCENTAGE = 50; private int min. Percentage = DEFAULT_MIN_PERCENTAGE; private int max. Percentage = DEFAULT_MAX_PERCENTAGE; public boolean supports(Class clazz) { return Price. Increase. class. equals(clazz); } public void set. Min. Percentage(int i){min. Percentage = i; } public int get. Min. Percentage() { return min. Percentage; } public void set. Max. Percentage(int i) {. . . } public int get. Max. Percentage() {. . . } Spring 40
Використання валідатора (Validator) (4/4) Price. Increase. Validator (завершення) } public void validate(Object obj, Errors errors) { Price. Increase pi=(Price. Increase)obj; if(pi==null){ errors. reject. Value("percentage", "error. not-specified", null, "Value required. "); } else { if (pi. get. Percentage() > max. Percentage) { errors. reject. Value("percentage", "error. too-high", new Object[] {new Integer(max. Percentage)}, "Value too high. "); } if (pi. get. Percentage() <= min. Percentage) { errors. reject. Value("percentage", "error. too-low", new Object[] {new Integer(min. Percentage)}, "Value too low. "); } } } Spring 41
Проект розгорнуто у Tomcat Склад (мінімальний) проекту calc 1 (1/2) <servlet-name>Calc. S</servlet-name> calc 1| WEB-INF| classes| Sum. Controller. class | lib | commons-beanutils. jar | spring-2. 0. 4. jar |. . . | web. xml | Calc. S-servlet. xml Spring 43 | calc. jsp
Файл WEB-INF/web. xml (дескрипторний файл web- проектів) <web-app version="2. 4" xmlns="http: //java. sun. com/xml/ns/j 2 ee" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //java. sun. com/xml/ns/j 2 ee/web-app_2_4. xsd" > <servlet-name>Calc. S</servlet-name> <servlet-class> org. springframework. web. servlet. Dispatcher. Servlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Calc. S</servlet-name> <url-pattern>*. html</url-pattern> </servlet-mapping> </web-app> Spring 45
WEB-INF/Calc. S-servlet. xml – конфігураційний файл Spring Framework (задається Web. Application. Context) <servlet-name>Calc. S</servlet-name> <beans> <bean id="Controller" class="Sum. Controller" > </bean> За створення об'єктів (бінів) відповідає Spring (пригадаємо Io. C) <bean id="url. Mapping» class= "org. springframework. web. servlet. handler. Simple. Url. Handler. Mapping"> <property name="mappings"> <props> <prop key="/calc. html">Controller</prop> </props> Url- або request-mapping </property> </beans> Spring 46
Class Sum. Controller import javax. servlet. http. Http. Servlet. Request; javax. servlet. http. Http. Servlet. Response; org. springframework. web. servlet. Model. And. View; org. springframework. web. servlet. mvc. Abstract. Controller; public class Sum. Controller extends Abstract. Controller { protected Model. And. View handle. Request. Internal( Http. Servlet. Request request, Http. Servlet. Response response) throws Exception { Model. And. View mav = new Model. And. View("/calc. jsp"); View try { int x=Integer. parse. Int(request. get. Parameter("x")); int y=Integer. parse. Int(request. get. Parameter("y")); int z = x + y; mav. add. Object("x", x); mav. add. Object("y", y); mav. add. Object("z", z); Model } catch (Number. Format. Exception e){e. print. Stack. Trace(); } return mav; } Spring 47 }
Файл calc. jsp <%@ page content. Type="text/html; charset=UTF-8" language="java" %> <html> <head> <title>Calc Sum- 1</title> </head> <body> <form> <input type="text" name="x" value="${x}"/> <input type="text" name="y" value="${y}"/> <br/> <input type="submit" value="Calc Sum!"/> </form> </body> </html> Spring + = ${z} 48
Модифікація Calc 1 -проекту (проект. Calc 2) // Sum. Controller. java import java. util. *; . . . mav. add. Object("y", y); Model mav. add. Object("date", new Date()); . . . Java Standard Tag Library <%-- calc. jsp --%> <%@ taglib prefix="c" uri="http: //java. sun. com/jstl/core"%>. . . <input type="text" name="x" value="${x}"/> + <input type="text" name="y" value="${y}"/> = ${z} <br/> <input type="submit" value="Calc Sum!"/> <br/> <c: out value="At" /> ${date} Spring 50 <h 4> Обчислення в JSP: ${x+y}<h 4/>. . .
Додаток 2. Tomcat Spring 53
Eclipse (Tomcat plugin) Spring 54
Перевірка Tomcat Spring 55
Додаток 3. Використання Eclipse (+ Spring IDE plugin) Spring 56
Обрання типу проекту — Dynamic Web Proect Spring 57
Eclipse. Spring Explorer. Open Graph Spring 61
Eclipse. Spring Explorer. Open Graph (проект greeting) Spring 62
Eclipse. Запуск проекту (на сервері): Run As: Run on Server Spring 63
“Get your personalized Eclipse” Spring 65
Додаток 4. Ant Spring 66
Приклад запуску Ant ant deploy Файл build. xml <? xml version="1. 0"? > <project. . . <target name="deploy". . . </target> </project> Spring 68
Опис завдань (фрагмент build. xml) - 1 <target name="build" description="Compile main source tree java files"> <mkdir dir="${build. dir}"/> <javac destdir="${build. dir}" source="1. 5" target="1. 5" debug="true" deprecation="false" optimize="false" failonerror="true"> <src path="${src. dir}"/> <classpath refid="master-classpath"/> </javac> </target> <target name="deploy" depends="build" description="Deploy application"> <copy todir="${deploy. path}/${name}" preservelastmodified="true"> <fileset dir="${web. dir}"> <include name="**/*. *"/> </fileset> </copy> Spring 69 </target>
Опис завдань (фрагмент build. xml) - 2. (Використання з БД та технологією JDBC API) <target name="print. Data"> <echo message="PRINT DATA USING: ${db. driver} ${db. url}"/> <sql driver="${db. driver}" url="${db. url}" userid="${db. user}" password="${db. pw}" JDBC (Java Data. Base Connectivity) onerror="continue" SQL (Structured Query Language) print="true"> <classpath refid="master-classpath"/> SELECT * FROM products; </sql> </target> Перелік завдань (target), пов'язаних із БД: – drop. Tables; – load. Data; – print. Data; – clear. Data; Spring – shutdown. Db. 70
Опис завдань (фрагмент build. xml) - 3. (Використання з БД та технологією JDBC API) <target name="load. Data"> <echo message="LOAD DATA USING: ${db. driver} ${db. url}"/> CREATE TABLE products ( <sql driver="${db. driver}" id INTEGER NOT NULL PRIMARY KEY, url="${db. url}" description varchar(255), userid="${db. user}" price decimal(15, 2) password="${db. pw}" ); CREATE INDEX products_description ON onerror="continue" products(description); src="db/load_data. sql"> Файл create_products. sql <classpath refid="master-classpath"/> для target “create. Tables” </sql> </target> Файл load_data. sql INSERT INTO products (id, description, price) values(1, 'Lamp', 5. 00); INSERT INTO products (id, description, price) values(2, 'Table', 75. 00); INSERT INTO products (id, description, price) values(3, 'Chair', 22. 00); Spring 71
Файл build. xml (початковий фрагмент) <? xml version="1. 0"? > <project name="springapp 1" basedir=". " default="usage"> <property file="build. properties"/> Для зручності в окремому файлі визначені властивості (properties) для налаштування на конкретні веб-сервер та СУБД <property name="src. dir" value="src"/> <property name="web. dir" value="war"/> <property name="build. dir" value="${web. dir}/WEB-INF/classes"/> <property name="name" value="springapp 1"/>. . . Spring 72
Файл build. properties (налаштування на Tomcat 6, hsqldb ) # Ant properties for building the springapp 1 appserver. home=c: /tomcat # for Tomcat 5 use $appserver. home}/server/lib # for Tomcat 6 use $appserver. home}/lib appserver. lib=${appserver. home}/lib deploy. path=${appserver. home}/webapps tomcat. manager. url=http: //localhost: 8080/manager tomcat. manager. username=admin tomcat. manager. password= driver. Class. Name (hsqldb. jar) ########### DB ############# db. driver=org. hsqldb. jdbc. Driver db. url=jdbc: hsqldb: hsql: //localhost db. user=sa db. pw= Spring 73
JDBC. Файл build. properties (переналаштування проекту на My. SQL ) # Ant properties for building the springapp 1 driver. Class. Name. . . (mysql-connector-java-3. 1. 14. jar) ########### DB ############# db. driver=com. mysql. jdbc. Driver db. url=jdbc: mysql: //localhost/test db. user=root db. pw=root Spring 74
Файл build. xml. Не мучайтесь, копіюйте! Не для перегляду, тільки для можливого <? xml version="1. 0"? > копіювання! <project name="springapp 1" Цей basedir=". " файлdefault="usage"> (build. xml) майже без змін <property file="build. properties"/> узято з документації до Spring Framework (http: //www. springframework): <property name="src. dir" value="src"/> <property name="web. dir" value="war"/> spring-framework-2. 5. 3 -with-docs. zip <property name="build. dir" value="${web. dir}/WEB-INF/classes"/> <property name="name" value="springapp 1"/> <path id="master-classpath"> <fileset dir="${web. dir}/WEB-INF/lib"> <include name="*. jar"/> </fileset> <!-- We need the servlet API classes: --> <!-- * for Tomcat 5/6 use servlet-api. jar --> <!-- * for other app servers - check the docs --> <fileset dir="${appserver. lib}"> <include name="servlet*. jar"/> </fileset> <pathelement path="${build. dir}"/> </path> <target name="usage"> <echo message=""/> Spring <echo message="${name} build file"/> <echo message="------------------"/> 75
Додаток 5. Приклад: springapp 1 (spring-проект з БД) Проект розроблено на основі прикладу з документації, що надається в одному архіві із Spring Framework (spring-framework-2. 5. 3 -with-docs. zip): spring-framework-2. 5. 3docsMVC-step-by-step): Spring 76 http: //www. springframework. org
Запуск СУБД HSQL у серверному режимі (із визначенням робочої БД test) java -classpath. . warWEB-INFlibhsqldb. jar org. hsqldb. Server -database test Spring 77
Створення БД test (1/3) (з використанням ant) ant create. Tables load. Data print. Data JDBC (Java Data. Base Connectivity) SQL (Structured Query Language) SQL JDBC Налаштування на СУБД HSQL Spring 78
Створення таблиць БД test (2/3) (використання SQL JDBC) Target load. Data Spring Target create. Tables 79
Створення таблиць БД test (виконання ant-завдання) (3/3) ant create. Tables load. Data print. Data Spring 80
Запуск Tomcat catalina start Spring 82
Запуск клієнта http: //localhost: 8080/springapp 1 Spring 83
Запити ресурсів hello. htm priceincrease. htm Spring 84
Переналаштування на СУБД My. SQL, технологія JDBC (Java Data. Base Connectivity) <bean id="data. Source" class="org. apache. commons. dbcp. Basic. Data. Source» destroy-method="close"> <property name="driver. Class. Name" value="${jdbc. driver. Class. Name}"/> <property name="url" value="${jdbc. url}"/> <property name="username" value="${jdbc. username}"/> <property name="password" value="${jdbc. password}"/> </bean> З файлу application. Context. xml jdbc. driver. Class. Name=org. hsqldb. jdbc. Driver Фрагмент jdbc. properties jdbc. url=jdbc: hsqldb: hsql: //localhost для СУБД HSQL Фрагмент jdbc. properties для СУБД My. SQL jdbc. driver. Class. Name=com. mysql. jdbc. Driver Spring jdbc. url=jdbc: mysql: //localhost/test 86
Використання My. SQL (3/4) My. SQL: створення таблиць БД test (ant-завдання) ant create. Tables load. Data print. Data Spring 89
Клієнт (проекту springapp 2 з My. SQL БД) http: //localhost: 8080/springapp 2 Spring 91
web. xml (фрагмент) <web-app. . . > <listener-class>org. springframework. web. context. Context. Loader. Listener </listener-class> </listener> <servlet-name>springapp</servlet-name> <servlet-class>org. springframework. web. servlet. Dispatcher. Servlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springapp</servlet-name> <url-pattern>*. htm</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file> index. jsp </welcome-file> </welcome-file-list> <jsp-config> <taglib-uri>/spring</taglib-uri> <taglib-location>/WEB-INF/tld/spring-form. tld</taglib-location> </taglib> </jsp-config> </web-app> Spring 92
springapp-servlet. xml (фрагменти) - (1/2) <beans xmlns="http: //www. springframework. org/schema/beans" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //www. springframework. org/schema/beans/spring-beans-2. 5. xsd"> <bean id="message. Source" class= "org. springframework. context. support. Resource. Bundle. Message. Source"> <property name="basename" value="messages"/> </bean> <bean name="/hello. htm" class="springapp. web. Inventory. Controller"> <property name="product. Manager" ref="product. Manager"/> </bean> <bean id="view. Resolver" class= "org. springframework. web. servlet. view. Internal. Resource. View. Resolver"> <property name="view. Class" value= "org. springframework. web. servlet. view. Jstl. View"> </property> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=". jsp"></property> Spring 93 </bean>
springapp-servlet. xml (фрагменти) - (2/2) <bean name="/priceincrease. htm" class="springapp. web. Price. Increase. Form. Controller"> <property name="session. Form" value="true"/> <property name="command. Name" value="price. Increase"/> <property name="command. Class" value="springapp. service. Price. Increase"/> <property name="validator"> <bean class="springapp. service. Price. Increase. Validator"/> </property> <property name="form. View" value="priceincrease"/> <property name="success. View" value="hello. htm"/> <property name="product. Manager" ref="product. Manager"/> </beans> Spring 94
application. Context. xml (фрагменти) - (1/3) <beans xmlns="http: //www. springframework. org/schema/beans" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //www. springframework. org/schema/beans/spring-beans-2. 5. xsd"> <bean id="product. Manager» class="springapp. service. Simple. Product. Manager"> <property name="products"> <list> <ref bean="product 1"/> <ref bean="product 2"/> <ref bean="product 3"/> </list> </property> </bean> Spring 95
application. Context. xml (фрагменти) - (2/3) <bean id="product 1" class="springapp. domain. Product"> <property name="description" value="Lamp"/> <property name="price" value="5. 75"/> </bean> <bean id="product 2" class="springapp. domain. Product"> <property name="description" value="Table"/> <property name="price" value="75. 25"/> </bean> <bean id="product 3" class="springapp. domain. Product"> <property name="description" value="Chair"/> <property name="price" value="22. 79"/> </bean> <bean name="/hello. htm" class="springapp. web. Inventory. Controller"> <property name="product. Manager" ref="product. Manager"/> </bean> Spring 96
application. Context. xml (фрагменти) - (3/3) <bean name="/priceincrease. htm» class="springapp. web. Price. Increase. Form. Controller"> <property name="session. Form" value="true"/> <property name="command. Name" value="price. Increase"/> <property name="command. Class" value="springapp. service. Price. Increase"/> <property name="validator"> <bean class="springapp. service. Price. Increase. Validator"/> </property> <property name="form. View" value="priceincrease"/> <property name="success. View" value="hello. htm"/> <property name="product. Manager" ref="product. Manager"/> </bean> <bean id="view. Resolver" class= "org. springframework. web. servlet. view. Internal. Resource. View. Resolver"> <property name="view. Class" value="org. springframework. web. servlet. view. Jstl. View"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=". jsp"/> </beans> Spring 97
class Product package springapp. domain; import java. io. Serializable; public class Product implements Serializable { private int id; private String description; private Double price; public void set. Id(int i) { id = i; } public int get. Id() { return id; } public String get. Description() { return description; } public void set. Description(String description) { this. description = description; } public Double get. Price() { return price; } public void set. Price(Double price) {this. price = price; } public String to. String() { String. Buffer buffer = new String. Buffer(); buffer. append("Description: " + description + "; "); buffer. append("Price: " + price); return buffer. to. String(); } } Spring 98
interface Product. Dao package springapp. dao; import java. util. List; import springapp. domain. Product; public interface Product. Dao { public List<Product> get. Product. List(); public void save. Product(Product prod); } Spring 99
class Jdbc. Product. Dao - (1/2) package springapp. dao; import java. sql. Result. Set; import java. sql. SQLException; import java. util. List; import org. springframework. jdbc. core. namedparam. Map. Sql. Parameter. Source; import org. springframework. jdbc. core. simple. Parameterized. Row. Mapper; import org. springframework. jdbc. core. simple. Simple. Jdbc. Dao. Support; import springapp. domain. Product; public class Jdbc. Product. Dao extends Simple. Jdbc. Dao. Support implements Product. Dao { public List<Product> get. Product. List() { List<Product> products = get. Simple. Jdbc. Template(). query( "select id, description, price from products", new Product. Mapper()); return products; } Spring 100
class Jdbc. Product. Dao - (2/2) public void save. Product(Product prod) { int count = get. Simple. Jdbc. Template(). update( "update products set description = : description, price = : price where id = : id", new Map. Sql. Parameter. Source(). add. Value("description", prod. get. Description()). add. Value("price", prod. get. Price()). add. Value("id", prod. get. Id())); } private static class Product. Mapper implements Parameterized. Row. Mapper<Product> { public Product map. Row(Result. Set rs, int row. Num) throws SQLException { Product prod = new Product(); prod. set. Id(rs. get. Int("id")); prod. set. Description(rs. get. String("description")); prod. set. Price(new Double(rs. get. Double("price"))); return prod; } } } Spring 101
class Price. Increase package springapp. service; import org. apache. commons. logging. Log. Factory; public class Price. Increase { private int percentage; public void set. Percentage(int i) { percentage = i; } public int get. Percentage() { return percentage; } } Spring 102
class Price. Increase. Validator - (1/2) package springapp. service; import org. springframework. validation. Validator; import org. springframework. validation. Errors; public class Price. Increase. Validator implements Validator { private int DEFAULT_MIN_PERCENTAGE = 0; private int DEFAULT_MAX_PERCENTAGE = 50; private int min. Percentage = DEFAULT_MIN_PERCENTAGE; private int max. Percentage = DEFAULT_MAX_PERCENTAGE; public boolean supports(Class clazz) { return Price. Increase. class. equals(clazz); } public void validate(Object obj, Errors errors) { Price. Increase pi = (Price. Increase) obj; if (pi == null) { errors. reject. Value("percentage", "error. not-specified", null, "Value required. ") } else { if (pi. get. Percentage() > max. Percentage) { errors. reject. Value("percentage", "error. too-high", new Object[] {new Integer(max. Percentage)}, "Value too high. "); Spring 103 }
class Price. Increase. Validator - (2/2) if (pi. get. Percentage() <= min. Percentage) { errors. reject. Value("percentage", "error. too-low", new Object[] {new Integer(min. Percentage)}, "Value too low. "); } } } public void set. Min. Percentage(int get. Min. Percentage() { void set. Max. Percentage(int get. Max. Percentage() { i) { min. Percentage = i; } return min. Percentage; } i) { max. Percentage = i; } return max. Percentage; } } Spring 104
interface Product. Manager package springapp. service; import java. io. Serializable; import java. util. List; import springapp. domain. Product; public interface Product. Manager extends Serializable{ public void increase. Price(int percentage); public List<Product> get. Products(); } Spring 105
class Simple. Product. Manager package springapp. service; import java. util. List; import springapp. domain. Product; import springapp. dao. Product. Dao; public class Simple. Product. Manager implements Product. Manager { private Product. Dao product. Dao; public List<Product> get. Products() { return product. Dao. get. Product. List(); } public void increase. Price(int percentage) { List<Product> products = product. Dao. get. Product. List(); if (products != null) { for (Product product : products) { double new. Price = product. get. Price(). double. Value() * (100 + percentage)/100; product. set. Price(new. Price); product. Dao. save. Product(product); } } } public void set. Product. Dao(Product. Dao product. Dao) { this. product. Dao = product. Dao; } Spring } 106
hello. jsp <%@ page session="false"%> <%@ taglib prefix="c" uri="http: //java. sun. com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http: //java. sun. com/jsp/jstl/fmt" %> <html> <head><title><fmt: message key="title"/></title></head> <body> <h 3><fmt: message key="heading"/></h 3> <p><fmt: message key="greeting"/> <c: out value="${model. now}"/></p> <h 3>Товари</h 3> <c: for. Each items="${model. products}" var="prod"> <c: out value="${prod. description}"/> <i>$<c: out value="${prod. price}"/></i> </c: for. Each> <a href="<c: url value="priceincrease. htm"/>">Increase Prices</a> </body> </html> Spring 107
priceincrease. jsp <%@ page session="false"%> <%@ taglib prefix="c" uri="http: //java. sun. com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http: //java. sun. com/jsp/jstl/fmt" %> <%@ taglib prefix="form" uri="http: //www. springframework. org/tags/form" %> <html> <head> <title><fmt: message key="title"/></title> <style>. error { color: red; } </style> </head> <body> <h 1><fmt: message key="priceincrease. heading"/></h 1> <form: form method="post" command. Name="price. Increase"> <table width="95%" bgcolor="f 8 f 8 ff" border="0" cellspacing="0» cellpadding="5"> <tr> <td align="right" width="20%">Increase (%): </td> <td width="20%"> <form: input path="percentage"/> </td> <td width="60%"><form: errors path="percentage" css. Class="error"/> </td> </tr> </table> <input type="submit" align="center" value="Execute"> </form: form> <a href="<c: url value="hello. htm"/>">Home</a> Spring 108 </body> </html>
index. jsp <%@ page session="false"%> <%@ taglib prefix="c" uri="http: //java. sun. com/jsp/jstl/core" %> <c: redirect url="/hello. htm"/> Spring 109
Eclipse. Структура проектів Spring Web MVC calc | WEB-INF | classes | Sum. Controller. class | lib | servlet-api. jar | spring-2. 0. 4. jar |. . . | web. xml | Calc. S-servlet. xml | calc. jsp Spring 110
Деякі особливості Spring-проектів. Url- або request-mapping (з файлу. . . -servlet. xml). . . <bean id="url. Mapping» class= "org. springframework. web. servlet. handler. Simple. Url. Handler. Mapping"> <property name="mappings"> <props> <prop key="/calc. html">Controller</prop> <prop key="/yet. html">Yet. Controller</prop>. . > </props> Url- або request-mapping </property> </bean>. . . Spring 111
Деякі особливості Spring-проектів. View. Resolver (з файлу. . . -servlet. xml). . . <bean id="view. Resolver" class= Model. And. View mav = new Model. And. View("calc"); "org. springframework. web. servlet. view. Internal. Resource. View. Resolver"> <property name="view. Class"> <value> org. springframework. web. servlet. view. Jstl. View </value> </property> <property name="prefix"> <value> /WEB-INF/jsp/ </value> </property> <property name="suffix"><value>. jsp</value></property> </bean>. . . calc --> /WEB-INF/jsp/ calc. jsp / Spring 112
Контролери Spring Web MVC Spring 113
Контролери для web-сторінок без форм (з файлу. . . -servlet. xml) <bean id="read. My. Notes. Controller" class="Read. My. Notes. Controller"> <property name=”note. Manager"><ref bean=”note. Manager"/> </property> </bean> <bean id="note. Manager" class="Note. Manager">. . . </bean> Об'єкт бізнес-рівня public class Read. My. Notes. Controller extends Abstract. Controller { private INote. Manager note. Manager; protected Model. And. View handle. Request. Internal( Http. Servlet. Request request, Http. Servlet. Response response) throws Exception {. . . public void set. Note. Manager(INote. Manager note. Manager) { this. note. Manager = note. Manager; } Spring 114. . .
Контролери для web-сторінок з формами (з файлу. . . -servlet. xml) <bean id="user. Login. Form. Validator” class="User. Login. Form. Validator"> <property name="user. Manager"><ref bean="user. Manager. Service"/> </property> Валідатор (перевіряє дані, що уводяться у формі) </bean> <bean id="user. Login. Form. Controller” class="User. Login. Form. Controller"> <property name="session. Form"><value>true</value></property> <property name="command. Name"><value>user. To. Login</value> </property> <property name="command. Class"><value>User. Dto</value> </property> <property name="validator"> <ref bean="user. Login. Form. Validator"/> </property> <property name="form. View"><value>user. Login</value></property> <property name="success. View"><value>user. Start. html</value> </property> <property name="user. Manager"><ref bean="user. Manager"/> </property> Spring 116 </bean>
Контролери для web-сторінок з формами. User. Login. Form. Controller public class User. Login. Form. Controller extends Simple. Form. Controller { public Model. And. View on. Submit(Http. Servlet. Request request, Http. Servlet. Response response, Object command, Bind. Exception e) throws Servlet. Exception {. . . } protected Object form. Backing. Object(Http. Servlet. Request request) throws Servlet. Exception { User. Dto user = new User. Dto(); return user; } private IUser. Manager user. Manager; public void set. User. Manager (IUser. Manager user. Manager. Service) { this. user. Manager = user. Manager; } } Spring 118
user. Login. jsp <form. . . <spring: bind path="user. To. Login. name"> <tr> <td align="right">name: </td> <input type="text" name="login" value="${status. value}"> </td> <font color="red">${status. error. Message}</font></td> </tr> </spring: bind> <spring: bind path="user. To. Login. parole"> <tr><td align="right">parole: </td> <td><input type="password» name="parole"value="${status. value}"> </td> <td><font color="red">${status. error. Message}</font> </td> </tr> </spring: bind>. . . Spring 119 </form>
Архітектурні рівні та об'єкти • Data. Base Layer – Domain Object – Data Access Object (DAO) • Business Object Layer – Business Object – Data Transfer Object (DTO) • User Interface Layer Spring 120
Приклад. Blog Spring 121
User. java public class User implements Serializable { private Long id; private String login; private Set<Note> notes = new Hash. Set<Note>(); private Set<User> friends = new Hash. Set<User> (); . . . public Long get. Id() { return id; } public void set. Id(Long id) { this. id = id; }. . . } Spring 123
User. hbm. xml <hibernate-mapping package = "domain"> <class name="User"> <id name="id" column="id" type="long"> <generator class="native" /> </id> <property name="login" not-null="true" unique="true"/> <set inverse="true" name="notes" cascade="all” lazy="false"> <key column="user. Id" /> <one-to-many class="Note" /> </set> <set name="friends" lazy="false"> <key column="user. Id" /> <many-to-many column="friend. Id" class="User" /> </set> </class> </hibernate-mapping> Spring 124
Note. java public class Note implements Serializable { private Long id; private User user; private String content; . . . public Long get. Id() { return id; } public void set. Id(Long id) { this. id = id; }. . . } Spring 125
Note. hbm. xml <? xml version="1. 0"? > <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate Mapping DTD 3. 0//EN" "http: //hibernate. sourceforge. net/hibernate-mapping-3. 0. dtd"> <hibernate-mapping package = "domain"> <class name="Note"> <id name="id" column="id" type="long"> <generator class="native" /> </id> <many-to-one class="User" name="user" column="user. Id" not-null="true"/> <property name="content" not-null="true"/> </class> </hibernate-mapping> Spring 126
- Slides: 127