一、新建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}頁 ${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 } </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>!
<a href="<%=request.getContextPath()%>/user/logout">註銷</a>
<!-- 使用絕對路徑 -->
<a href="<%=request.getContextPath() %>/user/add">添加用戶</a>
<a href="<%=request.getContextPath() %>/user/list">用戶列表</a>
</c:if>
<c:if test="${empty loginUser}">
<a href="<%=request.getContextPath()%>/login">登錄</a>
<a href="<%=request.getContextPath()%>/"></a>
</c:if>
<c:if test="${not empty loginUser && loginUser.username eq \"1\"}">
<a href="<%=request.getContextPath() %>/"></a>
<a href="<%=request.getContextPath() %>/"></a>
<a href="<%=request.getContextPath()%>/"></a>
</c:if>
<a href="<%=request.getContextPath() %>/"></a>
<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> <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>