springMVC,hibernate,sitemesh,pagerlib整合

一、新建Dynamic Web Project:springmvc_hibernate

二、導入jar包

1.Spring4.0.6.RELEASE的所有包
2.log4j的包
3. Apache commons的部分包
4.hibernate包
5.spring的AOP包spring_aspectj
6.JSTL的包
7.sitemesh的包
8.pager-taglib的包
antlr-2.7.6.jar
aopalliance-1.0.jar
aspectj-1.8.10.jar
aspectjrt.jar
aspectjtools.jar
aspectjweaver.jar
bean-validator.jar
commons-collections-3.1.jar
commons-dbcp2-2.1.1.jar
commons-fileupload-1.3.3-sources.jar
commons-fileupload-1.3.3.jar
commons-io-2.5.jar
commons-logging-1.2.jar
commons-pool2-2.4.2.jar
dom4j-1.6.1.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
hibernate3.jar
javassist-3.12.0.GA.jar
jstl.jar
jta-1.1.jar
log4j-1.2.17.jar
org.aspectj.matcher.jar
pager-taglib.jar
sitemesh-2.4.2.jar
slf4j-api-1.6.1.jar
spring-aop-4.0.6.RELEASE-javadoc.jar
spring-aop-4.0.6.RELEASE-sources.jar
spring-aop-4.0.6.RELEASE.jar
spring-aspects-4.0.6.RELEASE-javadoc.jar
spring-aspects-4.0.6.RELEASE-sources.jar
spring-aspects-4.0.6.RELEASE.jar
spring-beans-4.0.6.RELEASE-javadoc.jar
spring-beans-4.0.6.RELEASE-sources.jar
spring-beans-4.0.6.RELEASE.jar
spring-build-src-4.0.6.RELEASE.jar
spring-context-4.0.6.RELEASE-javadoc.jar
spring-context-4.0.6.RELEASE-sources.jar
spring-context-4.0.6.RELEASE.jar
spring-context-support-4.0.6.RELEASE-javadoc.jar
spring-context-support-4.0.6.RELEASE-sources.jar
spring-context-support-4.0.6.RELEASE.jar
spring-core-4.0.6.RELEASE-javadoc.jar
spring-core-4.0.6.RELEASE-sources.jar
spring-core-4.0.6.RELEASE.jar
spring-expression-4.0.6.RELEASE-javadoc.jar
spring-expression-4.0.6.RELEASE-sources.jar
spring-expression-4.0.6.RELEASE.jar
spring-framework-bom-4.0.6.RELEASE-javadoc.jar
spring-framework-bom-4.0.6.RELEASE-sources.jar
spring-framework-bom-4.0.6.RELEASE.jar
spring-instrument-4.0.6.RELEASE-javadoc.jar
spring-instrument-4.0.6.RELEASE-sources.jar
spring-instrument-4.0.6.RELEASE.jar
spring-instrument-tomcat-4.0.6.RELEASE-javadoc.jar
spring-instrument-tomcat-4.0.6.RELEASE-sources.jar
spring-instrument-tomcat-4.0.6.RELEASE.jar
spring-jdbc-4.0.6.RELEASE-javadoc.jar
spring-jdbc-4.0.6.RELEASE-sources.jar
spring-jdbc-4.0.6.RELEASE.jar
spring-jms-4.0.6.RELEASE-javadoc.jar
spring-jms-4.0.6.RELEASE-sources.jar
spring-jms-4.0.6.RELEASE.jar
spring-messaging-4.0.6.RELEASE-javadoc.jar
spring-messaging-4.0.6.RELEASE-sources.jar
spring-messaging-4.0.6.RELEASE.jar
spring-orm-4.0.6.RELEASE-javadoc.jar
spring-orm-4.0.6.RELEASE-sources.jar
spring-orm-4.0.6.RELEASE.jar
spring-oxm-4.0.6.RELEASE-javadoc.jar
spring-oxm-4.0.6.RELEASE-sources.jar
spring-oxm-4.0.6.RELEASE.jar
spring-test-4.0.6.RELEASE-javadoc.jar
spring-test-4.0.6.RELEASE-sources.jar
spring-test-4.0.6.RELEASE.jar
spring-tx-4.0.6.RELEASE-javadoc.jar
spring-tx-4.0.6.RELEASE-sources.jar
spring-tx-4.0.6.RELEASE.jar
spring-web-4.0.6.RELEASE-javadoc.jar
spring-web-4.0.6.RELEASE-sources.jar
spring-web-4.0.6.RELEASE.jar
spring-webmvc-4.0.6.RELEASE-javadoc.jar
spring-webmvc-4.0.6.RELEASE-sources.jar
spring-webmvc-4.0.6.RELEASE.jar
spring-webmvc-portlet-4.0.6.RELEASE-javadoc.jar
spring-webmvc-portlet-4.0.6.RELEASE-sources.jar
spring-webmvc-portlet-4.0.6.RELEASE.jar
spring-websocket-4.0.6.RELEASE-javadoc.jar
spring-websocket-4.0.6.RELEASE-sources.jar
spring-websocket-4.0.6.RELEASE.jar
standard.jar
taglibs-standard-jstlel-1.2.5.jar

三、配置工程
1.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>springmvc_hibernate</display-name>

    <!-- 進行controller界面控制的dispatcher 設置 -->
    <servlet>
        <servlet-name>user</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>user</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

  <!-- 進行字符編碼的Filter,必須在openSessionInViewerFilter之前,才能生效 -->
 <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>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 啓動spring的監聽器,這樣配置在xml文件中的bean纔會初始化  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:beans*.xml</param-value>
  </context-param>

  <!-- 配合使用 Spring 的 HibernateDaoSupport 來進行開發,也就是說,
  我們的dao層的類都要繼承於 HibernateDaoSupport,從中由 Spring 來控制 Hibernate 的 Session 在請求來的時候開啓,
  走的時候關閉,保證了我們訪問數據對象時的穩定性。 -->
  <filter>
    <filter-name>openSessionInViewerFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
      <param-name>sessionFactoryBeanName</param-name>
      <param-value>mySessionFactory</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>openSessionInViewerFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 自定義分頁參數Filter -->
  <filter>
    <filter-name>SystemContextFilter</filter-name>
    <filter-class>com.my.web.SystemContextFilter</filter-class>
    <init-param>
        <param-name>pageSize</param-name>
        <param-value>15</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>SystemContextFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- sitemesh Filter -->
  <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- 登錄驗證Filter;Filter執行從上方向下方一層層過濾 -->
  <filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.my.web.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/user/*</url-pattern>
  </filter-mapping>

</web-app>

2.與web.xml同目錄的,對應servlet-name:user相同路徑下創建user-servlet.xml

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

    <!-- 開啓Annotation -->
    <mvc:annotation-driven />
    <!-- Controller進行掃描的包 annotation  -->
    <context:component-scan base-package="com.my.web"></context:component-scan>
    <!-- 將靜態文件指定到某個特殊的文件夾中,進行統一處理 ; 第一個*表示文件夾中的內容,第二個*表示所有子文件夾-->
    <mvc:resources location="/resources/" mapping="/resources/**"/>

    <!-- 資源顯示處理器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <!-- 查找頁面的前綴;頁面的位置=prefix+(function return String)+suffix -->
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <!-- 查找頁面的後綴 -->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 設置文件上傳 -->
    <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- one of the properties available; the maximum file size in bytes -->
        <property name="maxUploadSize" value="1000000"/>
    </bean>

    <!-- 全局異常處理 -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!-- error頁面處理UserException異常 -->
                <prop key="com.my.model.UserException">error</prop>
                <prop key=" java.lang.NullPointerException">exception</prop>
            </props>
        </property>
    </bean>
</beans>

與web.xml同目錄的sitemesh的decorators.xml

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

<!-- defaultdir 表明 decotaror 所在的文件夾 -->
<decorators defaultdir="/WEB-INF/decorators">
    <!-- Any urls that are excluded will never be decorated by Sitemesh -->
    <excludes>
        <pattern>/exclude.jsp</pattern>
        <pattern>/exclude/*</pattern>
    </excludes>

    <!-- 修飾的頁面 -->
    <decorator name="main" page="main.jsp">
        <pattern>/*</pattern>
    </decorator>

</decorators>

3.classpath目錄src/下的bean.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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 打開spring的Annotation的支持 -->
    <context:annotation-config/>
    <!-- 設置spring去那些包中找Annotation -->
    <context:component-scan base-package="com.my"></context:component-scan>

    <!-- Spring在第三方依賴包中包含了兩個數據源的實現類包,其一是Apache的DBCP,其二是 C3P0。 -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 配置連接池的初始值 -->
        <property name="initialSize" value="1" />
        <!-- 連接池的最大值 -->
        <!-- <property name="maxActive" value="500"/> -->
        <!-- 最大空閒時,當經過一個高峯之後,連接池可以將一些用不到的連接釋放,一直減少到maxIdle爲止 -->
        <!-- <property name="maxIdle" value="2"/> -->
        <!-- 當最小空閒時,當連接少於minIdle時會自動去申請一些連接 -->
        <property name="minIdle" value="1" />
        <!-- <property name="maxActive" value="100" /> -->
        <property name="maxIdle" value="20" />
        <property name="maxWaitMillis" value="1000" />
    </bean>

    <!-- 導入jdbc.properties -->
    <context:property-placeholder location="classpath*:jdbc.properties"/>

    <!-- 如果使用的是Annotation的方式,不能使用LocalSessionFactoryBean,
    而應該使用org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean -->
    <!-- 創建Spring的SessionFactory工廠 -->
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <!-- 注入數據源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 設置spring去哪個包中查找相應的實體類 -->
        <property name="packagesToScan">
            <value>com.my.model</value>
        </property>
        <property name="hibernateProperties">
            <!-- <value>
                hibernate.dialect=org.hibernate.dialect.HSQLDialect
            </value> -->
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.format_sql">false</prop>
            </props>
        </property>
    </bean>

    <!-- 創建HibernateTemplate,爲其注入SessionFactor -->
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory" ref="mySessionFactory"></property>
    </bean>
    <!-- 配置Spring的事務管理 -->
    <!-- 創建事務管理器  -->
    <bean id="myTxManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <!-- 配置AOP,Spring是通過AOP進行事務管理的 -->
    <aop:config>
        <!-- 設置pointcut,設置那些方法要加入事務處理, 在Service處理爲事務 -->
        <aop:pointcut id="productServiceMethods"
                expression="execution(* com.my.service.*.*(..))"/>
        <!-- 通過 aop:advisor確定具體要加入事務控制的方法-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="productServiceMethods"/>
    </aop:config>

    <!-- 配置那些方法要加入事務控制 -->
    <tx:advice id="txAdvice" transaction-manager="myTxManager">
        <tx:attributes>
            <!-- 讓所有的方法都加入事務管理;爲了提高效率,可以把一些查詢之類的方法設置爲只讀的事務 -->
            <tx:method name="*" propagation="REQUIRED" read-only="true"/>
            <!-- 以下方法都是可能涉及修改數據的方法,就無法設置爲只讀 -->
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
</beans>

4.classpath下src/中的jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc_hibernate
jdbc.username=root
jdbc.password=XXXXXX

5.src/中的log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
#log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
#log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

四、編寫工程代碼
1.創建model層,Entity的創建
User.java 【Entity】

package com.my.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

@Entity(name="User")
@Table(name="t_user")
public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private String email;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @NotEmpty(message="username is empty!")
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @NotEmpty(message="password is empty!")
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @NotEmpty(message="nickname is empty!")
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    @Email(message="email format isn't right!")
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
                + ", email=" + email + "]";
    }
    public User(int id, String username, String password, String nickname, String email) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.email = email;
    }
    public User() {
    }
}

UserException.java 【項目異常類】

package com.my.model;

public class UserException extends RuntimeException {

    public UserException() {
        super();
        // TODO Auto-generated constructor stub
    }

    public UserException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
        super(arg0, arg1, arg2, arg3);
        // TODO Auto-generated constructor stub
    }

    public UserException(String arg0, Throwable arg1) {
        super(arg0, arg1);
        // TODO Auto-generated constructor stub
    }

    public UserException(String arg0) {
        super(arg0);
        // TODO Auto-generated constructor stub
    }

    public UserException(Throwable arg0) {
        super(arg0);
        // TODO Auto-generated constructor stub
    }

}

Pager.java 【分頁處理類】

package com.my.model;

import java.util.List;

public class Pager<T> {
    private int offset;
    private int pageSize;
    private long totalRecord;
    private List<T> datas;
    public int getOffset() {
        return offset;
    }
    public void setOffset(int offset) {
        this.offset = offset;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public long getTotalRecord() {
        return totalRecord;
    }
    public void setTotalRecord(long totalRecord) {
        this.totalRecord = totalRecord;
    }
    public List<T> getDatas() {
        return datas;
    }
    public void setDatas(List<T> datas) {
        this.datas = datas;
    }
    public Pager(int offset, int pageSize, long totalRecord, List<T> datas) {
        super();
        this.offset = offset;
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        this.datas = datas;
    }
    public Pager() {
    }
}

SystemContext.java 【工程數據傳輸類,分頁參數】

package com.my.model;

public class SystemContext {
    private static ThreadLocal<Integer> pageOffset=new ThreadLocal<>();
    private static ThreadLocal<Integer> pageSize=new ThreadLocal<>();

    public static Integer getPageOffset() {
        return pageOffset.get();
    }
    public static void setPageOffset(Integer data) {
        pageOffset.set(data);
    }
    public static void removePageOffset() {
        pageOffset.remove();
    }

    public static Integer getPageSize() {
        return pageSize.get();
    }
    public static void setPageSize(Integer data) {
        pageSize.set(data);
    }
    public static void removePageSize() {
        pageSize.remove();
    }
}

2.com.my.dao 【數據庫採集層】
IUserDao.java 【接口】

package com.my.dao;

import java.util.List;

import com.my.model.Pager;
import com.my.model.User;

public interface IUserDao {
    void add(User user);
    void update(User user);
    void delete(int id);
    User load(int id);
    User loadByUsername(String username);
    List<User> list();
    Pager<User> find();
}

UserDao.java 【實體】

package com.my.dao;

import java.util.List;

import javax.annotation.Resource;
import javax.management.Query;

import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.my.model.Pager;
import com.my.model.SystemContext;
import com.my.model.User;
import com.my.util.LogUtil;

@Repository("userDao")
public class UserDao extends HibernateDaoSupport implements IUserDao {
    @Resource(name="mySessionFactory")
    public void setSuperSessionFactory(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }

    @Override
    public void add(User user) {
        getHibernateTemplate().save(user);
    }

    @Override
    public void update(User user) {
        getHibernateTemplate().update(user);
    }

    @Override
    public void delete(int id) {
        User user=load(id);
        getHibernateTemplate().delete(user);
    }

    @Override
    public User load(int id) {
        return getHibernateTemplate().load(User.class, id);
    }

    @Override
    public List<User> list() {
        String hql="from User";
        return getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hql).list();
    }

    String getCountHql(String hql) {
        String from=hql.substring(hql.toLowerCase().indexOf("from"));
        from.replaceAll(" fetch ", "  ");
        String hqlCount="select count(*) "+from;
        return hqlCount;
    }
    @Override
    public Pager<User> find() {
        int pageOffset=SystemContext.getPageOffset();
        if(pageOffset<=0) pageOffset=0;
        int pageSize=SystemContext.getPageSize();
        if(pageSize<=0) pageSize=15;
        String hql="from User";
        org.hibernate.Query query=getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hql);
        query.setFirstResult(pageOffset).setMaxResults(pageSize);
        List<User> datas=query.list();
        String hqlCount=getCountHql(hql);
        long totalRecord=(long) getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hqlCount).uniqueResult();
        LogUtil.printLog(totalRecord);

        Pager<User> pager=new Pager<>(pageOffset, pageSize, totalRecord, datas);
        return pager;
    }

    @Override
    public User loadByUsername(String username) {
        String hql="from User u where u.username=?";
        User user=(User) getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hql).
                setParameter(0, username).uniqueResult();
        return user;
    }

}

3.com.my.service 【Service 服務層】
IUserService.java 【接口】

package com.my.service;

import java.util.List;

import com.my.model.Pager;
import com.my.model.User;

public interface IUserService {
    void add(User user);
    void update(User user);
    void delete(int id);
    User load(int id);
    User loadByUsername(String username);
    List<User> list();
    Pager<User> find();
    User login(String username, String password);
}

UserService.java 【實體】

package com.my.service;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.my.dao.IUserDao;
import com.my.model.Pager;
import com.my.model.User;
import com.my.model.UserException;

@Service("userService")
public class UserService implements IUserService {
    private IUserDao userDao;
    @Resource(name="userDao")
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void add(User user) {
        User user2=loadByUsername(user.getUsername());
        if(null!=user2) {
            throw new UserException(user.getUsername()+" is exist!");
        }
        userDao.add(user);
    }

    @Override
    public void update(User user) {
        User userOld=loadByUsername(user.getUsername());
        if(null==userOld) {
            throw new UserException(user.getUsername()+" isn't exist!");
        }
        userOld.setNickname(user.getNickname());
        userOld.setPassword(user.getPassword());
        userOld.setEmail(user.getEmail());
        userDao.update(userOld);
    }

    @Override
    public void delete(int id) {
        userDao.delete(id);
        throw new UserException("I add this exception purposely! for test spring transaction control!");
    }

    @Override
    public User load(int id) {
        return userDao.load(id);
    }

    @Override
    public User loadByUsername(String username) {
        return userDao.loadByUsername(username);
    }

    @Override
    public List<User> list() {
        return userDao.list();
    }

    @Override
    public Pager<User> find() {
        return userDao.find();
    }

    @Override
    public User login(String username, String password) {
        User user=loadByUsername(username);
        if(null==user) {
            throw new UserException(username+" isn't exit! ");
        }
        if(!user.getPassword().equals(password)) {
            throw new UserException("password isn't correct!");
        }
        return user;
    }

}

4.com.my.web 【Controller層,web控制層】
IndexController.java 【權限控制】

package com.my.web;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import com.my.model.User;
import com.my.service.IUserService;

@Controller
//@SessionAttributes("loginUser") 表明Model中的loginUser屬性會自動存儲到HttpSession中
public class IndexController {
    private IUserService userService;
    @Resource
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value="/login", method=RequestMethod.GET)
    public String login() {
        return "../login";
    }
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public String login(String username, String password, Model model, HttpSession session) {
        if(null==username || null==password) {
            model.addAttribute("errors", "username and password can't be empty!");
            return "../login";
        }
        User loginUser=userService.login(username, password);
        session.setAttribute("loginUser", loginUser);
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/user/list";
    }
}

LoginFilter.java 【權限 過濾器,登錄】

package com.my.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.my.model.SystemContext;
import com.my.model.User;
import com.my.util.LogUtil;

public class LoginFilter implements Filter {
    private User loginUser;

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        LogUtil.printLog("");
        HttpServletRequest httpReq=(HttpServletRequest)request;
        loginUser=(User) httpReq.getSession().getAttribute("loginUser");
        if(null==loginUser) {
            //((HttpServletResponse)response).sendRedirect(httpReq.getContextPath()+"/WEB-INF/login.jsp");
            //服務器端跳轉
            httpReq.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
            return;
        }
        try {
            chain.doFilter(request, response);
        }finally {
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

}

UserController.java 【模塊業務控制】

package com.my.web;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import com.my.model.Pager;
import com.my.model.User;
import com.my.service.IUserService;
import com.my.util.LogUtil;

@Controller
//使用“/user”訪問這個controller
@RequestMapping("/user")
public class UserController {
    private IUserService userService;
    @Resource
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value= {"/", "/list"}, method=RequestMethod.GET)
    public String list(Model model) {
        Pager<User> pager=userService.find();
        model.addAttribute("pager", pager);
        return "user/list";
    }
    @RequestMapping(value="/add", method=RequestMethod.GET)
    public String add(Model model) {
        model.addAttribute(new User());
        return "user/add";
    }
    @RequestMapping(value="/add", method=RequestMethod.POST)
    public String add(@Validated User user, BindingResult br, Model model, HttpServletRequest request) {
        if(br.hasErrors()) {
            return "user/add";
        }
        LogUtil.printLog(user);
        LogUtil.printLog(br.getAllErrors());
        userService.add(user);
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/user/list";
    }
    @RequestMapping(value="/{username}/show", method=RequestMethod.GET)
    public String show(@PathVariable String username, Model model) {
        User user=userService.loadByUsername(username);
        model.addAttribute(user);
        return "user/show";
    }
    @RequestMapping(value="/{id}/update", method=RequestMethod.GET)
    public String update(@PathVariable int id, Model model) {
        User user=userService.load(id);
        model.addAttribute(user);
        return "user/update";
    }
    @RequestMapping(value="/{id}/update", method=RequestMethod.POST)
    public String update(@Validated User user, BindingResult br, @PathVariable int id, HttpServletRequest request) {
        if(br.hasErrors()) {
            //服務器端跳轉
            return "user/update";
        }
        userService.update(user);
        //客戶端跳轉
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/user/"+user.getUsername()+"/show";
    }
    @RequestMapping(value="/{id}/delete", method=RequestMethod.GET)
    public String delete(@PathVariable int id) {
        userService.delete(id);
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/user/list";
    }

    @RequestMapping(value="logout", method=RequestMethod.GET)
    public String logout(HttpSession session) {
        //session.setAttribute("loginUser", null);
        session.invalidate();
        return UrlBasedViewResolver.REDIRECT_URL_PREFIX+"/login";
    }
}

SystemContextFilter.java 【參數過濾器】

package com.my.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.my.model.SystemContext;
import com.my.util.LogUtil;

public class SystemContextFilter implements Filter {
    private int pageOffset;
    private int pageSize;

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        try {           
            pageOffset=Integer.parseInt(request.getParameter("pager.offset"));
        }catch (NumberFormatException e) {
            LogUtil.printLog("pager.offset: "+request.getParameter("pager.offset"));
        }
        SystemContext.setPageOffset(pageOffset);
        SystemContext.setPageSize(pageSize);

        try {
            chain.doFilter(request, response);
        }finally {
            SystemContext.removePageOffset();
            SystemContext.removePageSize();
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        try {
            pageSize=Integer.parseInt(arg0.getInitParameter("pageSize"));
        }catch(NumberFormatException e) {
            LogUtil.printLog("pageSize="+pageSize);
        }
    }

}

五、web界面
1.WebContent/inc/pager.jsp 【分頁模板,直接jsp:include】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page isELIgnored="false" %>
<%
    //param 是 JSTL  request.getParameter的 關鍵字
    //int items =1;
    //int maxPageItems=20;
    //try{
    //  items =Integer.parseInt(request.getParameter("items"));
    //  maxPageItems=Integer.parseInt(request.getParameter("maxPageItems"));
    //}catch(Exception e){
    //  e.printStackTrace();
    //}
    //String searchParameters =request.getParameter("parameters");
    //LogUtil.printLog("maxPageItems="+maxPageItems+" searchParameters:"+searchParameters);
%>
<pg:pager items="${param.items}" maxPageItems="${param.maxPageItems}" maxIndexPages="10"  export="curPage=pageNumber" url="${param.url }">
    <pg:last>
        共有${param.items}條記錄.共${pageNumber}頁&nbsp;${curPage}
    </pg:last>
    <c:forEach var="par" items="${param.parameters}">
        <pg:param name="${par}" />
    </c:forEach>
    <pg:first>
        <a href="${pageUrl}">首頁</a>
    </pg:first>
    <pg:prev>
        <a href="${pageUrl}">上一頁</a>
    </pg:prev>
    <pg:pages>
        <c:if test="${curPage eq pageNumber}">
            ${pageNumber }
        </c:if>
        <c:if test="${curPage ne  pageNumber}">
            <a href="${pageUrl }">${pageNumber }&nbsp;</a>
        </c:if>
    </pg:pages>
    <pg:next>
        <a href="${pageUrl}">下一頁</a>
    </pg:next>
    <pg:last>
        <a href="${pageUrl}">尾頁</a>
    </pg:last>
</pg:pager>

2.WebContent/WEB-INF/decorators/main.jsp 【sitemesh進行web頁面封裝的修飾器】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><decorator:title default="歡迎使用fuck" /> </title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/main.css" />
<decorator:head></decorator:head>
</head>
<body>
    <font color="red">loginUser:${loginUser.username }</font>
    <c:if test="${not empty loginUser}">
        歡迎<font color="green">${loginUser.nickname}</font>!&nbsp;
        <a href="<%=request.getContextPath()%>/user/logout">註銷</a>&nbsp;
        <!-- 使用絕對路徑 -->
        <a href="<%=request.getContextPath() %>/user/add">添加用戶</a>&nbsp;
        <a href="<%=request.getContextPath() %>/user/list">用戶列表</a>&nbsp;
    </c:if>
    <c:if test="${empty loginUser}">
        <a href="<%=request.getContextPath()%>/login">登錄</a>&nbsp;
        <a href="<%=request.getContextPath()%>/"></a>&nbsp;
    </c:if>
    <c:if test="${not empty loginUser && loginUser.username eq \"1\"}">
        <a href="<%=request.getContextPath() %>/"></a>&nbsp;
        <a href="<%=request.getContextPath() %>/"></a>&nbsp;
        <a href="<%=request.getContextPath()%>/"></a>&nbsp;
    </c:if>
    <a href="<%=request.getContextPath() %>/"></a>&nbsp;
    <hr />
    <h1 align="center"><decorator:title default="fuck"></decorator:title> </h1>
    <hr />
    <decorator:body /><hr />
    <div align="center" style="clear:both;margin-top:10px;">
        CopyRight@2022-2222<br />
        fuck項目
    </div>
</body>
</html>

3.WebContent/WEB-INF/login.jsp 【登錄界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>user login</title>
</head>
<body>
    <form action="<%=request.getContextPath() %>/login" method="post">
        <table border="1" cellspacing="1" align="center">
            <tr><td>username:<input type="text" name="username"/> </td> </tr>
            <tr><td>password:<input type="password" name="password"/> </td> </tr>
            <tr><td><input type="submit" value="login"> </td> </tr>
        </table>
    </form>
</body>
</html>

4.WebContent/WEB-INF/jsp/user/ 【用戶功能界面文件夾】
add.jsp 【添加界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>user add</title>
</head>
<body>
    <sf:form method="post" modelAttribute="user">
        <table border="1" cellspacing="0" align="center">
            <tr><td>userName:</td><td><sf:input path="username"/><sf:errors path="username"></sf:errors> </td> </tr>
            <tr><td>password:</td><td><sf:input path="password"/><sf:errors path="password"></sf:errors> </td> </tr>
            <tr><td>nickname:</td><td><sf:input path="nickname"/><sf:errors path="nickname"></sf:errors> </td> </tr>
            <tr><td>email:</td><td><sf:input path="email"/><sf:errors path="email"></sf:errors> </td> </tr>
            <tr><td colspan="2"><input type="submit" value="add"/> </td> </tr>
        </table>
    </sf:form>
</body>
</html>

list.jsp 【列表界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>user list</title>
</head>
<body>
    <table width="700" align="center" border="1" cellpadding="0">
        <thead>
            <tr>
            <td>用戶Id</td><td>用戶名</td><td>密碼</td><td>暱稱</td><td>郵箱</td><td>操作</td>
            </tr>
        </thead>
        <tbody>
            <c:if test="${pager.totalRecord lt 1 }">
                <tr><td colspan="6">沒有用戶</td> </tr>
            </c:if>
            <c:if test="${pager.totalRecord ge 1 }">
                <c:forEach items="${pager.datas }" var="user">
                    <tr>
                    <td>${user.id }</td><td><a href="${user.username }/show">${user.username }</a></td><td>${user.password }</td>
                    <td>${user.nickname }</td><td>${user.email }</td>
                    <td><a href="${user.id }/update">更新</a>&nbsp;<a href="${user.id }/delete">刪除</a></td>
                    </tr>
                </c:forEach>
            </c:if>
        </tbody>
        <tfoot>
            <tr>
            <td colspan="6">
                <jsp:include page="/inc/pager.jsp">
                    <jsp:param value="${pager.totalRecord }" name="items"/>
                    <jsp:param value="${pager.pageSize }" name="maxPageItems"/>
                    <jsp:param value="list" name="url"/>
                </jsp:include>
            </td>
            </tr>
        </tfoot>
    </table>
</body>
</html>

show.jsp 【展示界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>user[${user.username }] show</title>
</head>
<body>
    <c:if test="${empty user }">
        ${user.username } isn't exist!
    </c:if>
    <c:if test="${(not empty user)}">
        <table border="1" cellspacing="0" align="center">
            <tr><td>user ID:</td><td><input type="text" value="${user.id}"/></td> </tr>
            <tr><td>userName:</td><td><input type="text" value="${user.username}"/></td> </tr>
            <tr><td>password:</td><td><input type="password" value="${user.password}"/></td> </tr>
            <tr><td>nickname:</td><td><input type="text" value="${user.nickname}"/></td> </tr>
            <tr><td>email:</td><td><input type="text" value="${user.email}"/></td> </tr>
        </table>
    </c:if>
</body>
</html>

update.jsp 【更新界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>user[${user.username }] update</title>
</head>
<body>
    <c:if test="${empty user }">
        user isn't exist!
    </c:if>
    <c:if test="${(null != user)}">
    <sf:form method="post" modelAttribute="user">
        <table border="1" cellspacing="0" align="center">
            <tr><td>userName:</td><td><input type="hidden" name="username" value="${user.username }" />${user.username }
            <sf:errors path="username"></sf:errors> </td> </tr>
            <tr><td>password:</td><td><sf:password path="password"/><sf:errors path="password"></sf:errors> </td> </tr>
            <tr><td>nickname:</td><td><sf:input path="nickname"/><sf:errors path="nickname"></sf:errors> </td> </tr>
            <tr><td>email:</td><td><sf:input path="email"/><sf:errors path="email"></sf:errors> </td> </tr>
            <tr><td colspan="2"><input type="submit" value="update"/> </td> </tr>
        </table>
    </sf:form>
    </c:if>
</body>
</html>

5.WebContent/WEB-INF/jsp/error.jsp 【錯誤處理界面】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>error Page</title>
</head>
<body>
    <h1>${exception.message }</h1>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章