一 架构
1Action类
2 配置文件
3 View页面
二 Code
1 src
(1)com.atguigu.ssh.actions
>EmployeeAction.java
package com.atguigu.ssh.actions; import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map; import org.apache.struts2.interceptor.RequestAware; import com.atguigu.ssh.entities.Employee;
import com.atguigu.ssh.service.DepartmentService;
import com.atguigu.ssh.service.EmployeeService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable; public class EmployeeAction extends ActionSupport implements RequestAware,
ModelDriven<Employee>,Preparable{ private static final long serialVersionUID = 1L; private EmployeeService employeeService; public void setEmployeeService(EmployeeService employeeService){
this.employeeService=employeeService;
} //5 校验注册的姓名是否可用
private String lastName; public void setLastName(String lastName) {
this.lastName = lastName;
} public String validateLastName() throws UnsupportedEncodingException{
if(employeeService.lastNameIsValid(lastName)){
inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
}else{
inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
}
return "ajax-success";
} //**** 4 使用ModelDriven拦截器方法存储添加的信息
public String save(){
//第一次添加 就加上系统时间,否则直接保存不修改时间
if(id == null){
model.setCreateTime(new Date());
}
employeeService.saveorUpdate(model);
return SUCCESS;
} /**
* 可以根据 id 来判断为 save 方法准备的 model 是 new 的还是从数据库获取的!
*/
//****6-2 Edit
public void prepareSave(){
//第一次添加
if(id == null){
model=new Employee();
}
//修改,从数据库中获取
else{
model = employeeService.get(id);
} } //3-1 查询Department
private DepartmentService departmentService;
public void setDepartmentService(DepartmentService departmentService) {
this.departmentService = departmentService;
}
//3-2 实现添加员工信息的方法
public String input(){
request.put("departments", departmentService.getAll());
return INPUT;
} //**** 6-1 拦截器的方法
public void prepareInput(){
//说明在修改,这时从数据库中获取状态
if(id != null){
model = employeeService.get(id);
}
}
//2 删除
private Integer id;
public void setId(Integer id) {
this.id = id;
}
/*public String delete(){
employeeService.delete(id);
return SUCCESS;
}*/
//2-1 使用Ajax方式删除
private InputStream inputStream; public InputStream getInputStream() {
return inputStream;
} public String delete(){
employeeService.delete(id);
try {
//删除成功
inputStream=new ByteArrayInputStream("1".getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
//删除失败
try {
inputStream=new ByteArrayInputStream("0".getBytes("UTF-8"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
return "ajax-success";
}
//1 查询
public String list(){
request.put("employees", employeeService.getAll());
return "list";
} //放到页面里
private Map<String,Object> request; @Override
public void setRequest(Map<String, Object> arg0) {
this.request=arg0;
} //****
@Override
public void prepare() throws Exception {
}
//****
private Employee model;
//****
@Override
public Employee getModel() {
return model;
} }
(2)com.atguigu.ssh.converters
>SSHDateConverter.java
package com.atguigu.ssh.converters; import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; public class SSHDateConverter extends StrutsTypeConverter { private DateFormat dateFormat; public SSHDateConverter()
{
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
} @Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if(toClass == Date.class){
if(values !=null && values.length>0){
String value=values[0];
try {
return dateFormat.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
return values;
} @Override
public String convertToString(Map context, Object o) {
if(o instanceof Date){
Date date=(Date)o;
return dateFormat.format(date);
}
return null;
} }
(3)com.atguigu.ssh.dao
>BaseDao.java
package com.atguigu.ssh.dao; import org.hibernate.Session;
import org.hibernate.SessionFactory; public class BaseDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
} public Session getSession(){
return this.sessionFactory.getCurrentSession();
}
}
>DepartmentDao.java
package com.atguigu.ssh.dao; import java.util.List; import com.atguigu.ssh.entities.Department; public class DepartmentDao extends BaseDao{ //获取查询到的Department集合
public List<Department> getAll(){
String hql="FROM Department";
return getSession().createQuery(hql).list();
}
}
>EmployeeDao.java
package com.atguigu.ssh.dao; import java.util.List; import org.hibernate.Query; import com.atguigu.ssh.entities.Employee; public class EmployeeDao extends BaseDao{ /*放到父类BaseDao中
private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory=sessionFactory;
} public Session getSession(){
return this.sessionFactory.getCurrentSession();
}*/ //5 Edit
public Employee get(Integer id){
return (Employee) getSession().get(Employee.class, id);
} //4 校验注册的姓名是否可用
public Employee getEmployeeByLastName(String lastName){
String hql = "FROM Employee e WHERE e.lastName = ?";
Query query = getSession().createQuery(hql).setString(0, lastName);
Employee employee = (Employee) query.uniqueResult();
//System.out.println("***"+employee.getDepartment().getClass().getName());
return employee;
}
//3 添加、存储
public void saveOrUpadate(Employee employee){
getSession().saveOrUpdate(employee);
}
//2 删除
public void delete(Integer id){
String hql="DELETE FROM Employee e WHERE e.id=?";
getSession().createQuery(hql).setInteger(0,id).executeUpdate();
}
//1获取
public List<Employee> getAll(){
String hql="FROM Employee e LEFT OUTER JOIN FETCH e.department";
return getSession().createQuery(hql).list();
}
}
(4)com.atguigu.ssh.entities
>Department.java
package com.atguigu.ssh.entities; public class Department { private Integer id;
private String departmentName="";
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
} }
>Employee.java
package com.atguigu.ssh.entities; import java.util.Date; public class Employee {
private Integer id; private String lastName="";
private String email; private Date birth;
private Date createTime; private Department department; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getLastName() {
return lastName;
} public void setLastName(String lastName) {
this.lastName = lastName;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public Date getBirth() {
return birth;
} public void setBirth(Date birth) {
this.birth = birth;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public Department getDepartment() {
return department;
} public void setDepartment(Department department) {
this.department = department;
} /*@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email="
+ email + ", birth=" + birth + ", createTime=" + createTime
+ ", department=" + department+ "]";
}*/ }
>Department.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-18 16:53:56 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.atguigu.ssh.entities.Department" table="SSH_DEPARTMENT">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="departmentName" type="java.lang.String">
<column name="DEPARTMENT_NAME" />
</property>
</class>
</hibernate-mapping>
>Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-18 16:53:56 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.atguigu.ssh.entities.Employee" table="SSH_EMPLOYEE"> <id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="lastName" type="java.lang.String">
<column name="LAST_NAME" />
</property>
<property name="email" type="java.lang.String">
<column name="EMAIL" />
</property>
<property name="birth" type="java.util.Date">
<column name="BIRTH" />
</property>
<property name="createTime" type="java.util.Date">
<column name="CREATE_TIME" />
</property>
<many-to-one name="department" class="com.atguigu.ssh.entities.Department" lazy="false">
<column name="DEPARTMENT_ID" />
</many-to-one>
</class>
</hibernate-mapping>
(5)com.atguigu.ssh.service
>DepartmentService.java
package com.atguigu.ssh.service; import java.util.List; import com.atguigu.ssh.dao.DepartmentDao;
import com.atguigu.ssh.entities.Department; public class DepartmentService { private DepartmentDao departmentDao;
public void setDepartmentDao(DepartmentDao departmentDao) {
this.departmentDao = departmentDao;
} public List<Department> getAll(){
return departmentDao.getAll();
}
}
>EmployeeService.java
package com.atguigu.ssh.service; import java.util.List; import com.atguigu.ssh.dao.DepartmentDao;
import com.atguigu.ssh.entities.Department; public class DepartmentService { private DepartmentDao departmentDao;
public void setDepartmentDao(DepartmentDao departmentDao) {
this.departmentDao = departmentDao;
} public List<Department> getAll(){
return departmentDao.getAll();
}
}
2 conf
(1)applicationContext-beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="employeeDao" class="com.atguigu.ssh.dao.EmployeeDao">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <bean id="departmentDao" class="com.atguigu.ssh.dao.DepartmentDao">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <bean id="employeeService" class="com.atguigu.ssh.service.EmployeeService">
<property name="employeeDao" ref="employeeDao"></property>
</bean> <bean id="departmentService" class="com.atguigu.ssh.service.DepartmentService">
<property name="departmentDao" ref="departmentDao"></property>
</bean> <bean id="employeeAction" class="com.atguigu.ssh.actions.EmployeeAction"
scope="prototype">
<property name="employeeService" ref="employeeService"></property>
<property name="departmentService" ref="departmentService"></property>
</bean>
</beans>
(2)applicationContext.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties"/> <!-- 导入C3P0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean> <!--配置Hibernate 的sessionFactory的实例 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="mappingLocations" value="classpath:com/atguigu/ssh/entities/*.hbm.xml"></property>
</bean> <!--配置Spring声明式事务 -->
<!--1 配置hibernate事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean> <!--2 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="lastNameIsValid" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <!--3 配置事务切入点 -->
<aop:config>
<aop:pointcut expression="execution(* com.atguigu.ssh.service.*.*(..))" id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config> </beans>
(3)db.properties
jdbc.user=root
jdbc.password=920614
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring_ssh jdbc.initPoolSize=5
jdbc.maxPoolSize=10
#...
(4)hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>
(5)struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" /> <package name="default" namespace="/" extends="struts-default">
<!-- 定义新的拦截器栈,
配置 prepare 拦截器栈的 alwaysInvokePrepare 参数值为 false -->
<interceptors>
<interceptor-stack name="sshStack">
<interceptor-ref name="paramsPrepareParamsStack">
<param name="prepare.alwaysInvokePrepare">false</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 使用新的拦截器栈 -->
<default-interceptor-ref name="sshStack"></default-interceptor-ref> <action name="emp-*" class="employeeAction"
method="{1}">
<result name="list">/WEB-INF/views/emp-list.jsp</result> <result type="stream" name="ajax-success">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
<result name="input">/WEB-INF/views/emp-input.jsp</result> <result name="success" type="redirect">/emp-list</result>
</action>
</package> </struts>
(6)xwork-conversion.properties
java.util.Date=com.atguigu.ssh.converters.SSHDateConverter
3 WebContent-----WEB-INF
(1)views
>emp-input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
<script type="text/javascript" SRC="scripts/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function(){
$(":input[name=lastName]").change(function(){
var val = $(this).val();
val = $.trim(val);
var $this = $(this); if(val != ""){
//把当前节点后面的所有 font 兄弟节点删除
$this.nextAll("font").remove(); var url="emp-validateLastName";
var args={"lastName":val,"time":new Date()};
$.post(url,args,function(data){
//姓名可用
if(data == "1"){
$this.after("<font color='green'>LastName可用!</font>");
}
//不可用
else if(data == "0"){
$this.after("<font color='red'>LastName不可用!</font>");
}
//服务器错误
else{
alert("服务器错误!");
}
});
}else{
alert("lastName不能为空!");
$(this).val("");
//$(this).focus();
}
});
})
</script>
</head>
<body> <s:debug></s:debug> <h4>Employee Input Page</h4> <s:form action="emp-save" method="post">
<s:if test="id != null">
<s:textfield name="lastName" label="LastName" disabled="true"></s:textfield>
<s:hidden name="id"></s:hidden> <%--通过隐藏域的方法
<s:hidden name="lastName"></s:hidden>
<s:hidden name="createTime"></s:hidden> --%>
</s:if> <s:else>
<s:textfield name="lastName" label="LastName"></s:textfield>
</s:else>
<s:textfield name="email" label="Email"></s:textfield>
<s:textfield name="birth" label="Birth"></s:textfield> <s:select list="#request.departments"
listKey="id" listValue="departmentName" name="department.id"
label="Department"></s:select>
<s:submit></s:submit>
</s:form> </body>
</html>
>emp-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
<script type="text/javascript" SRC="scripts/jquery-1.7.2.js"></script>
<script type="text/javascript">
//删除, 使用 ajax 的方式
$(function(){
$(".delete").click(function(){
var lastName=$(this).next(":input").val();
var flag=confirm("是否要删除"+lastName+"的信息吗?");
//确认删除, 使用 ajax 的方式
if(flag){
//获取要删除的行
var $tr=$(this).parent().parent();
var url=this.href;
var args={"time":new Date()};
$.post(url,args,function(data){
//若 data 的返回值为 1, 则提示 删除成功, 且把当前行删除
if(data== "1"){
alert("删除成功!");
$tr.remove();
}else{
//若 data 的返回值不是 1, 提示删除失败.
alert("删除失败!");
}
});
}
return false;
});
})
</script>
</head>
<body>
<h3>Employee List Page</h3> <s:if test="#request.employees == null ||#request.size()==0">
没有员工信息
</s:if>
<s:else>
<table border="1" cellpadding="10" cellspacing="0">
<tr>
<td>ID</td>
<td>LASTNAME</td>
<td>EMAIL</td>
<td>BIRTH</td>
<td>CREATETIME</td>
<td>DEPARTMENT</td>
<td>DELETE</td>
<td>EDIT</td>
</tr>
<s:iterator value="#request.employees">
<tr>
<td>${id}</td>
<td>${lastName}</td>
<td>${email }</td>
<%--
<td>${birth}</td>
<td>${createTime}</td>
--%>
<!-- 格式化时间 -->
<td>
<s:date name="birth" format="yyyy-MM-dd"/>
</td>
<td>
<s:date name="createTime" format="yyyy-MM-dd hh:mm:ss"/>
</td> <td>${department.departmentName}</td>
<td>
<a href="emp-delete?id=${id }" class="delete">Delete</a>
<input type="hidden" value="${lastName}"/>
</td>
<td>
<a href="emp-input?id=${id }">Edit</a>
</td>
</tr>
</s:iterator>
</table>
</s:else>
</body>
</html>
(2)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_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 配置spring配置文件.xml的名称和位置路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param> <!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 配置Struts的Filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> </web-app>
(3)WebContent----index.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>Insert title here</title>
</head>
<body> <a href="emp-list">显示所有员工信息:List All Employees</a>
<br><br><br>
<a href="emp-input">添加员工向信息:Add Employees' Information</a> </body>
</html>