springMVC,hibernate,sitemesh,pagerlib整合

来源:互联网 发布:线切割编程要证明的 编辑:程序博客网 时间:2024/06/10 22:48

一、新建Dynamic Web Project:springmvc_hibernate

二、导入jar包

1.Spring4.0.6.RELEASE的所有包2.log4j的包3. Apache commons的部分包4.hibernate包5.spring的AOP包spring_aspectj6.JSTL的包7.sitemesh的包8.pager-taglib的包
antlr-2.7.6.jaraopalliance-1.0.jaraspectj-1.8.10.jaraspectjrt.jaraspectjtools.jaraspectjweaver.jarbean-validator.jarcommons-collections-3.1.jarcommons-dbcp2-2.1.1.jarcommons-fileupload-1.3.3-sources.jarcommons-fileupload-1.3.3.jarcommons-io-2.5.jarcommons-logging-1.2.jarcommons-pool2-2.4.2.jardom4j-1.6.1.jarhibernate-jpa-2.0-api-1.0.1.Final.jarhibernate3.jarjavassist-3.12.0.GA.jarjstl.jarjta-1.1.jarlog4j-1.2.17.jarorg.aspectj.matcher.jarpager-taglib.jarsitemesh-2.4.2.jarslf4j-api-1.6.1.jarspring-aop-4.0.6.RELEASE-javadoc.jarspring-aop-4.0.6.RELEASE-sources.jarspring-aop-4.0.6.RELEASE.jarspring-aspects-4.0.6.RELEASE-javadoc.jarspring-aspects-4.0.6.RELEASE-sources.jarspring-aspects-4.0.6.RELEASE.jarspring-beans-4.0.6.RELEASE-javadoc.jarspring-beans-4.0.6.RELEASE-sources.jarspring-beans-4.0.6.RELEASE.jarspring-build-src-4.0.6.RELEASE.jarspring-context-4.0.6.RELEASE-javadoc.jarspring-context-4.0.6.RELEASE-sources.jarspring-context-4.0.6.RELEASE.jarspring-context-support-4.0.6.RELEASE-javadoc.jarspring-context-support-4.0.6.RELEASE-sources.jarspring-context-support-4.0.6.RELEASE.jarspring-core-4.0.6.RELEASE-javadoc.jarspring-core-4.0.6.RELEASE-sources.jarspring-core-4.0.6.RELEASE.jarspring-expression-4.0.6.RELEASE-javadoc.jarspring-expression-4.0.6.RELEASE-sources.jarspring-expression-4.0.6.RELEASE.jarspring-framework-bom-4.0.6.RELEASE-javadoc.jarspring-framework-bom-4.0.6.RELEASE-sources.jarspring-framework-bom-4.0.6.RELEASE.jarspring-instrument-4.0.6.RELEASE-javadoc.jarspring-instrument-4.0.6.RELEASE-sources.jarspring-instrument-4.0.6.RELEASE.jarspring-instrument-tomcat-4.0.6.RELEASE-javadoc.jarspring-instrument-tomcat-4.0.6.RELEASE-sources.jarspring-instrument-tomcat-4.0.6.RELEASE.jarspring-jdbc-4.0.6.RELEASE-javadoc.jarspring-jdbc-4.0.6.RELEASE-sources.jarspring-jdbc-4.0.6.RELEASE.jarspring-jms-4.0.6.RELEASE-javadoc.jarspring-jms-4.0.6.RELEASE-sources.jarspring-jms-4.0.6.RELEASE.jarspring-messaging-4.0.6.RELEASE-javadoc.jarspring-messaging-4.0.6.RELEASE-sources.jarspring-messaging-4.0.6.RELEASE.jarspring-orm-4.0.6.RELEASE-javadoc.jarspring-orm-4.0.6.RELEASE-sources.jarspring-orm-4.0.6.RELEASE.jarspring-oxm-4.0.6.RELEASE-javadoc.jarspring-oxm-4.0.6.RELEASE-sources.jarspring-oxm-4.0.6.RELEASE.jarspring-test-4.0.6.RELEASE-javadoc.jarspring-test-4.0.6.RELEASE-sources.jarspring-test-4.0.6.RELEASE.jarspring-tx-4.0.6.RELEASE-javadoc.jarspring-tx-4.0.6.RELEASE-sources.jarspring-tx-4.0.6.RELEASE.jarspring-web-4.0.6.RELEASE-javadoc.jarspring-web-4.0.6.RELEASE-sources.jarspring-web-4.0.6.RELEASE.jarspring-webmvc-4.0.6.RELEASE-javadoc.jarspring-webmvc-4.0.6.RELEASE-sources.jarspring-webmvc-4.0.6.RELEASE.jarspring-webmvc-portlet-4.0.6.RELEASE-javadoc.jarspring-webmvc-portlet-4.0.6.RELEASE-sources.jarspring-webmvc-portlet-4.0.6.RELEASE.jarspring-websocket-4.0.6.RELEASE-javadoc.jarspring-websocket-4.0.6.RELEASE-sources.jarspring-websocket-4.0.6.RELEASE.jarstandard.jartaglibs-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.Driverjdbc.url=jdbc:mysql://localhost:3306/springmvc_hibernatejdbc.username=rootjdbc.password=XXXXXX

5.src/中的log4j.properties

### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.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 SQLlog4j.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>