Web application development. Part 4

В предыдущей части я разработал серверную часть вэб-приложения с помощью Java. В этой части, я «подружу» клиентскую и серверную часть вэб-приложения с помощью Spring Framework.

Создадим spring контекст my-context.xml c:
• настройками подключения к БД;
• бином EntityManager — объект, через который происходит взаимодействие с БД. Инжектится в CarDaoImpl.java;
• инжектом объекта класса CarDaoImpl.java в объект класса CarServiceImpl.java;



my-context.xml
<code class="xml">
    <?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:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                           http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          p:dataSource-ref="dataSource"
          p:packagesToScan="model"
          p:jpaProperties-ref="jpaProperties"
          p:persistenceProvider-ref="persistenceProvider"/>

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"
          depends-on="entityManagerFactory"/>

    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"
          p:driverClass="com.mysql.jdbc.Driver"
          p:jdbcUrl="jdbc:mysql://localhost:3306/CarCatalog?characterEncoding=UTF-8"
          p:username="root"
          p:password="1234"
          p:idleConnectionTestPeriodInMinutes="1"
          p:idleMaxAgeInSeconds="240"
          p:minConnectionsPerPartition="2"
          p:maxConnectionsPerPartition="5"
          p:partitionCount="2"
          p:acquireIncrement="1"
          p:statementsCacheSize="100"
          p:releaseHelperThreads="2"
          p:statisticsEnabled="false"/>

    <bean id="persistenceProvider" class="org.hibernate.ejb.HibernatePersistence"/>

    <bean id="jpaProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="properties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="connection.pool_size">1</prop>
                <prop key="current_session_context_class">thread</prop>
                <prop key="show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
            </props>
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
          p:entityManagerFactory-ref="entityManagerFactory"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean name="carDao" class="model.dao.impl.CarDaoImpl">
    </bean>

    <bean name="CarService" class="service.impl.CarServiceImpl">
        <property name="carDao" ref="carDao">
        </property>
    </bean>

</beans>
</code>

Создайте БД с названием CarCatalog и кодировкой utf_general_ci или измените название в контексте my-context.xml на своё. Также измените p:username и p:password, если не совпадает.

Создадим настройки для spring DispatcherServlet, который будет обрабатывать запросы с клиента:


mvc-dispatcher-servlet.xml
<code class="xml">
    <?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="controllers"/>
    <mvc:view-controller path="/" view-name="/index.jsp"/>
    <mvc:resources mapping="/**" location="/"/>
    <mvc:annotation-driven/>

    </beans>
</code>
context:component-scan поиск и регистрация компонентов в контейнере спринга;
mvc:view-controller домашняя страница;
mvc:resources автоматически обрабатывать запросы на получение статических данных;

Добавим spring контекст my-context.xml и настройки для spring DispatcherServlet в дескриптор развертывания web.xml:
<code class="xml">
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

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

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/my-context.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>
</code>

Добавим в контролер CarCatalogController.js параметр refs и обработчики для компонентов:
<code class="javascript">
    Ext.define('CarCatalog.controller.CarCatalogController', {
    extend: 'Ext.app.Controller',

    refs: [
        {selector: 'carGridView',
            ref: 'carGridView'},
        {selector: 'carGridView button[action="add"]',
            ref: 'carGridAdd'},
        {selector: 'carGridView button[action="delete"]',
            ref: 'carGridDelete'},
        {selector: 'searchCarView button[action="search"]',
            ref: 'searchCar'},
        {selector: 'addCarFormView',
            ref: 'addCarFormView'},
        {selector: 'carCatalogView',
            ref: 'carCatalogView'},
        {selector: 'addCarFormView textfield[name=name] ',
            ref: 'addCarFormName'},
        {selector: 'addCarFormView textfield[name=price]',
            ref: 'addCarFormPrice'},
        {selector: 'addCarFormView button[action=save]',
            ref: 'addCarFormSave'}
    ],

    init: function () {
        this.control({
            'carGridView  button[action=add]': {
                click: this.onAddCar
            },
            'carGridView  button[action=delete]': {
                click: this.onDelCar
            },
            'searchCarView  textfield[name="search"]': {
                change: this.onChangeText
            },
            'carGridView': {
                cellclick: this.onLineGrid
            },
            'addCarFormView  button[action=save]': {
                click: this.onSaveCar
            },
            'addCarFormView  textfield[name=name]': {
                change: this.onValidation
            },
            'addCarFormView  textfield[name=price]': {
                change: this.onValidation
            }
        });
    },

    onSaveCar: function (button) {
        var me = this;
        var carModel = Ext.create('CarCatalog.model.CarCatalogModel');
        carModel.set(this.getAddCarFormView().down('form').getValues());
        carModel.save({
            success: function (operation, response) {
                var objAjax = operation.data;
                Ext.getStore('CarCatalogStore').add(objAjax);
                me.getAddCarFormView().close();
            },
            failure: function (dummy, result) {
                Ext.MessageBox.show({
                    title: 'Дубликат!',
                    msg: 'Такая модель и цена уже существуют',
                    buttons: Ext.Msg.OK,
                    icon: Ext.Msg.ERROR
                });
            }

        });
    },

    onAddCar: function () {
        Ext.widget('addCarFormView');
    },

    onDelCar: function () {
        var sm = this.getCarGridView().getSelectionModel();
        var rs = sm.getSelection();
        this.getCarGridView().store.remove(rs[0]);
        this.getCarGridView().store.commitChanges();
        this.getCarGridDelete().disable();
    },

    onChangeText: function () {
        Ext.getStore('CarCatalogStore').load({
            params: {
                search: this.getCarCatalogView().down('searchCarView').getValues()
            }
        });
    },

    onLineGrid: function () {
        this.getCarGridDelete().enable();
    },

    onValidation: function () {
        if (this.getAddCarFormName().validate() && this.getAddCarFormPrice().validate()) {
            this.getAddCarFormSave().enable();
        } else {
            this.getAddCarFormSave().disable();
        }
    }

});
</code>
ref ссылка на что-то в selector'e;
selector указывает на компоненты, для быстро обращения к ним через ref;
onSaveCar создается модель данных и сохраняется;
onAddCar создает виджет формы добавления;
onDelCar удаляет запись;
onChangeText загружает данные в соответствии со значением в поле поиска;
onLineGrid при выделении строки кнопка «Удалить» становится активной;
onValidation валидация полей формы добавления;

И последнее — добавим иконки к кнопкам «Добавить» и «Удалить».


index.jsp
<code class="html">
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Каталог</title>
    <link rel="stylesheet" type="text/css" href="resources/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css"/>
    <script type="text/javascript" src="resources/ext-all.js"></script>
    <script type="text/javascript" src="resources/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script>
    <script type="text/javascript" src="app.js"></script>
    <style type="text/css">
        .icon-delete {
            background-image: url(resources/delete.png) !important;
        }
        .icon-add {
            background-image: url(resources/add.png) !important;
        }
    </style>
</head>
<body>
</body>
</html>
</code>



Скачать проект: CarCatalog

You need to login to create comments.

Comments ()



    Last comments

    Recent posts

    Popular posts

    By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy и Terms of Service.