Basic CRUD Web Aplikasi Menggunakan SpringFramework-MVC, Freemarker, Hibernate dan JPA - Konfigurasi Web Descriptor, Spring-MVC dan DataSource

Article Index

Konfigurasi Web Descriptor, Spring-MVC dan DataSource

Kemudian pada Project Explorer ataupun Project tree-structure pilih item paling atas (nama project) ataupun JPACrud-SpringMVC folder. Klik kanan dan pilih popup menuitem: Add Framework Support.

Pada daftar checkboxes, pilih: Spring, Spring Data JPA, Spring MVC, JAVA EE Persistence, dan Hibernate. Kemudian klik button OK.

Ikuti petunjuk pada layar monitor, jika ada muncul window dialog lainnya.

Kemudian pada menubar pilih menuitem: File -> Project Structure. Pada window dialog left sidebar pilih Modules -> Web. Dan pilih tanda + (New Web deployment descriptor). Pada child window dialog, arahkan lokasi file web.xml pada direktori src/main/webapp/WEB-INF jika lokasi file tidak terisi otomatis. Kemudian pilih servlet versi 3.0 ataupun 3.1 dan klik button OK pada child window dan parent window.

Perlu diketahui bahwa tomcat 7.x hanya support servlet 3.0 dan JPA 2.0, sedangkan tomcat 8.x support hingga servlet 3.1 dan JPA 2.1. Dan project web aplikasi kita menggunakan standard JPA 2.1.

Source code file src/main/webapp/WEB-INF/web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <description>Web application context configuration</description>
    <display-name>JPACrud Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/app-context.xml
        </param-value>
    </context-param>

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

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

</web-app>

Kode diatas dibuat untuk servlet 3.0, jika sewaktu membuat file web.xml memilih servlet 3.1 maka headernya akan sedikit berbeda. File web.xml ini merupakan web deployment "WAR" descriptor yang diperlukan oleh setiap http servlet engine untuk menjalankan web aplikasi yang ditempatkan padanya.

Melalui Project Explorer, pilih folder src/main/webapp/WEB-INF dan buat file Spring Configuration baru. Beri nama file tersebut dengan mvc-dispatcher-servlet.xml.

Source code file src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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-4.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">

    <description>Spring MVC framework configuration</description>

    <mvc:annotation-driven validator="validator" conversion-service="conversionService"
                           ignore-default-model-on-redirect="true"/>
    <mvc:default-servlet-handler/>

    <!-- freemarker configuration and viewResolver -->
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
        <property name="freemarkerSettings">
            <props>
                <prop key="incompatible_improvements">2.3.23</prop>
                <prop key="template_exception_handler">rethrow</prop>
                <prop key="default_encoding">UTF-8</prop>
            </props>
        </property>
        <property name="freemarkerVariables">
            <map>
                <entry key="xml_escape" value-ref="fmXmlEscape"/>
            </map>
        </property>
    </bean>
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
    <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="true"/>
        <property name="prefix" value=""/>
        <property name="suffix" value=".ftl"/>
    </bean>

    <!-- Declare SpringMVC interceptors -->
    <mvc:interceptors>
        <bean class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor"/>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="lang"/>
        </bean>
    </mvc:interceptors>

    <!-- Declare Localization resource bundles -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames" value="WEB-INF/i18n/messages"/>
        <property name="fallbackToSystemLocale" value="false"/>
    </bean>
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="cookieName" value="locale"/>
    </bean>

    <!-- Declare locale message validator dan conversion service -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="registerDefaultFormatters" value="false" />
        <property name="formatters">
            <set>
                <bean class="org.springframework.format.number.NumberFormatAnnotationFormatterFactory" />
                <bean class="org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory" />
            </set>
        </property>
    </bean>

    <!-- Declare cache manager for Spring-MVC -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcache"/>
    </bean>
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml"/>
        <property name="shared" value="true"/>
    </bean>

    <!-- Scan classpath for annotations, eg: @Controller -->
    <context:component-scan base-package="org.fajarapps.jpacrud.controller"/>

</beans>

Melalui Project Explorer, pilih folder src/main/webapp/WEB-INF dan buat folder berikut: freemarker, i18n, spring. Kemudian pilih folder spring, dan buat file Spring Configuration baru. Beri nama file tersebut dengan app-context.xml.

Source code file src/main/webapp/WEB-INF/spring/app-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       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-4.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <description>DataSource, JPA, and Hibernate configuration</description>

    <!-- Declare database connection pool dan JPA DataSource -->
    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="minimumIdle" value="4"/>
        <property name="maximumPoolSize" value="50"/>
        <property name="connectionTimeout" value="50000"/>
        <property name="idleTimeout" value="300000"/>
        <property name="maxLifetime" value="600000"/>
        <property name="validationTimeout" value="30000"/>
        <property name="leakDetectionThreshold" value="30000"/>
        <property name="dataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>
        <property name="dataSourceProperties">
            <props>
                <prop key="port">3306</prop>
                <prop key="serverName">localhost</prop>
                <prop key="user">DBUSER</prop>
                <prop key="password">DBPASSWORD</prop>
                <prop key="databaseName">db_jpacrud</prop>
                <prop key="prepStmtCacheSize">250</prop>
                <prop key="cachePrepStmts">true</prop>
            </props>
        </property>
    </bean>

    <bean id="jdbcDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig"/>
    </bean>

    <!-- Declare SpringData-JPA configuration -->
    <!-- <context:load-time-weaver/> [ optional, please google utk informasi detailnya ] -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="jdbcDataSource"/>
        <property name="packagesToScan" value="org.fajarapps.jpacrud.entity"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="true"/>
                <property name="showSql" value="true"/>
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
                <property name="database" value="MYSQL"/>
            </bean>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
                <prop key="hibernate.generate_statistics">true</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">100</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="dataSource" ref="jdbcDataSource"/>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        </property>
    </bean>

    <!-- Declare JPA Entity message localization -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames" value="WEB-INF/i18n/messages"/>
        <property name="fallbackToSystemLocale" value="false"/>
    </bean>

    <!-- Declare others -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <jpa:repositories base-package="org.fajarapps.jpacrud.repository" transaction-manager-ref="transactionManager" />
    <jpa:auditing modify-on-creation="false" />

    <!-- Scan classpath for annotations, eg: @Component, @Service -->
    <context:annotation-config/>
    <context:component-scan base-package="org.fajarapps.jpacrud.domain"/>

</beans>