struts2中如何实现CRUD操作

一、实现CRUD简单操作的最终结果图


图1-1文件组织结构图



图1-2(index.jsp首页界面,点击list All Employees进入emp-list.jsp界面)

图1-3(emp-edit.jsp修改界面效果图,必须实现回显)


图1-4(emp-list .jsp显示所有雇员记录,并且可以在上方表单中添加雇员)


二、实现CRUD操作步骤

1、配置struts2的开发环境

复制struts2必须的jar包到工程文件lib目录下

在web.xml文件中配置struts2过滤器,配置信息如下

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

在src目录下添加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>
<package name="default" extends="struts-default" namespace="/">
</package>

</struts>

2.通过上面的步骤,我们已经搭好了struts2的开发环境,现在根据我们项目的需求在首页需要一个action入口查询所有雇员信息。index.jsp页面的源码如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"  %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">    
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">

  </head>

  <body>
   <s:a href="emp-list.action">list All Employees</s:a>
  </body>
</html>

这个时候我们需要一个action来处理显示所有雇员信息,首先我们需要新建一个雇员的实体类,源码如下:

package com.lizhenhua.struts2.app;


public class Employee {
private Integer employeeId;
private String firstName;
private String lastName;
private String email;
public Employee(Integer employeeId, String firstName, String lastName,
String email) {
super();
this.employeeId = employeeId;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public Employee() {
super();
}
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
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;
}

}


我们还需要实现一个简单的数据库Dao,实现简单的CRUD方法,源码如下:

package com.lizhenhua.struts2.app;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 模拟数据库
 * @author Administrator
 *
 */
public class Dao {
private static Map<Integer,Employee> emps = new HashMap<Integer,Employee>();
static{

emps.put(1001, new Employee(1001,"AA", "aa", "lizhenhua@vip.qq.com"));
emps.put(1002, new Employee(1002,"BB", "bb", "lizhenhua@vip.qq.com"));
emps.put(1003, new Employee(1003,"CC", "cc", "lizhenhua@vip.qq.com"));
emps.put(1004, new Employee(1004,"DD", "dd", "lizhenhua@vip.qq.com"));
emps.put(1005, new Employee(1005,"EE", "ee", "lizhenhua@vip.qq.com"));
}
/**
* 得到所有雇员信息
* @return
*/
public List<Employee> getEmployees(){
return new ArrayList<Employee>(emps.values());
}
/**
* 根据雇员id删除一个雇员
* @param empId
*/
public void delete(Integer empId){
emps.remove(empId);
}
/**
* 添加一个雇员,不需要指定id,id自动根据系统时间生成
* @param emp 
*/
public void save(Employee emp){
long time = System.currentTimeMillis();
emp.setEmployeeId((int) time);
emps.put(emp.getEmployeeId(), emp);
}
/**
* 根据雇员id返回雇员信息
* @param empId
* @return
*/
public Employee get(Integer empId){
return emps.get(empId);
}
/**
* 修改雇员信息
* @param emp
*/
public void update(Employee emp){
emps.put(emp.getEmployeeId(), emp);
}
}


最终,我们的主要业务操作都在EmployeeAction中完成。代码如下:

package com.lizhenhua.struts2.app;


import java.util.Map;


import org.apache.struts2.interceptor.RequestAware;


public class EmployeeAction implements RequestAware {
private Dao dao = new Dao();

//需要在当前的EmployeeAction中定义employeeId属性
//以接受请求参数
private Integer employeeId;

private String firstName;
private String lastName;
private String email;


public String getFirstName() {
return firstName;
}


public void setFirstName(String firstName) {
this.firstName = firstName;
}


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 Integer getEmployeeId() {
return employeeId;
}


public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}

public String save(){
//1.获取请求参数:通过定义对应属性的方式
Employee employee = new Employee(null, firstName, lastName, email);
dao.save(employee);
//2.调用dao的save方法
//3.通过redirectAction的方法响应结果
return "success";
}


public String delete(){
dao.delete(employeeId);
//返回结果的类型应为:redirectAction
//也可以是chain:实际上chain是没有必要的,因为不需要在下一个Action中保留当前Action的状态
//还有,若使用chain,则到达目标页面后,地址栏显示的依然是删除的那个连接。刷新时会重复提交。

return "success";
}

public String list(){
reqeust.put("emps", dao.getEmployees());
return "list";
}

private Map<String, Object> reqeust;


public void setRequest(Map<String, Object> arg0) {
this.reqeust = arg0;

}
}

定义好了action,我们需要在struts.xml配置文件中配置action

<action name="emp-*" class="com.lizhenhua.struts2.app.EmployeeAction" method="{1}">
<result name="{1}">emp-{1}.jsp</result>
<result name="success" type="redirectAction">emp-list</result>
</action>

通过以上的action代码确实完成了对雇员信息的CRUD操作,不过大家看看这个EmployeeAction中是否存在一些不足之处呢?很显然我们又在action中重新定义了employee的属性的getter和setter方法,我们不是在Employee实体类中定义了吗?这样是不是显得重复。struts2中是否有一种机制能够解决这个问题呢?答案是肯定的,strusts2中通过ModelDriven接口的getModel()方法返回的对象置于栈顶,解决方案后的action代码如下:

/**
 * 版本二
 * 如果Action类实现了ModelDriven接口,该拦截器将把ModelDriven接口的getModel()方法返回的对象置于栈顶
 */


package com.lizhenhua.struts2.app;


import java.util.Map;


import org.apache.struts2.interceptor.RequestAware;


import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ModelDriven;


public class EmployeeAction2 implements RequestAware,ModelDriven<Employee>{
private Employee employee;
private Dao dao = new Dao();


public String update(){
dao.update(employee);
return "success";
}

public String save(){
//1.获取请求参数:通过定义对应属性的方式


dao.save(employee);
//2.调用dao的save方法
//3.通过redirectAction的方法响应结果,给
return "success";
}


public String delete(){
// dao.delete(employee.getEmployeeId());  使用employeeId后
dao.delete(employeeId);

//返回结果的类型应为:redirectAction
//也可以是chain:实际上chain是没有必要的,因为不需要在下一个Action中保留当前Action的状态
//还有,若使用chain,则到达目标页面后,地址栏显示的依然是删除的那个连接。刷新时会重复提交。

return "success";
}

public String edit(){
//1.获取传入的employeeId
//2.根据employeeId获取Employee对象
// Employee emp = dao.get(employee.getEmployeeId());
//3.把栈顶对象的属性装配好
//目前的employee对象只有employeeId属性,其他属性为null
// employee.setEmail(emp.getEmail());
// employee.setFirstName(emp.getFirstName());
// employee.setLastName(emp.getLastName());

//employee = dao.get(employee.getEmployeeId());不能够进行表单的回显,因为经过重写赋值的employee对象已经不是栈顶对象了

//手动的把从数据库中获取的Employee对象放到值栈的栈顶,但此时值栈栈顶
//但此时值栈栈顶及第二个对象均为Employee对象,不完美,多了一个对象。
ActionContext.getContext().getValueStack().push(dao.get(employee.getEmployeeId()));
return "edit";
}

public String list(){
reqeust.put("emps", dao.getEmployees());
return "list";
}

private Map<String, Object> reqeust;


public void setRequest(Map<String, Object> arg0) {
this.reqeust = arg0;

}

private Integer employeeId;//id特殊属性



public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}


public Employee getModel() {
//判断是Create还是Edit
//若为Create,则employee = new Employee();
//若为Edit,则employee = dao.get(employeeId);
//判定标准为是否有employeeId这个请求参数,若有该参数,则视为Edit;若没有该参数,则视为Create
//若通过employeeId来判断,则需要在modelDriven拦截器之前先执行一个params拦截器!
//而这可以通过使用paramsPrepareParams拦截器栈实现,
//需要在struts.xml文件中配置使用paramsPrepareParamsStack参数
if(employeeId == null)
employee = new Employee();
else{
employee = dao.get(employeeId);
}
return employee;
}
}


上面这个action也能够完成CRUD操作,但是仍然存在一些问题:

在执行删除的时候,getModel方法存在问题
1.在执行删除的时候,employeeId不为null,但Model方法却从数据库加载了一个对象,不该加载!
2.指向查询全部信息时,也new Employee()对象,浪费!

那么,怎么解决呢?我们引入了使用PrepareInterceptor和Preparable接口来解决这一问题。

实现后的action代码如下:

/**
 *版本三
 * 如果Action类实现了ModelDriven接口,该拦截器将把ModelDriven接口的getModel()方法返回的对象置于栈顶
 */


package com.lizhenhua.struts2.app;
import java.util.Map;
import org.apache.struts2.interceptor.RequestAware;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;


public class EmployeeAction3 implements RequestAware,ModelDriven<Employee>,Preparable {
private Employee employee;
private Dao dao = new Dao();

public String update(){
dao.update(employee);
return "success";
}
public void prepareUpdate(){
employee = new Employee();
}

public String save(){
dao.save(employee);
return "success";
}
public void prepareSave(){
employee = new Employee();
}

public String delete(){
dao.delete(employeeId);
return "success";
}

public String edit(){
return "edit";
}
public void prepareEdit(){
employee = dao.get(employeeId);
}

public String list(){
reqeust.put("emps", dao.getEmployees());
return "list";
}

private Map<String, Object> reqeust;

public void setRequest(Map<String, Object> arg0) {
this.reqeust = arg0;
}

private Integer employeeId;//id特殊属性

public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}


public Employee getModel() {
return employee;
}


/**
* prepare方法的主要作用:为getModel()方法准备model的
*/
public void prepare() throws Exception {
System.out.println("prepare...");
}
}


最终的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>
<package name="default" extends="struts-default" namespace="/">
<!-- 修改PrepareInterceptor拦截器的(alwaysInvokePrepare) 属性值为false -->
<interceptors>
    <interceptor-stack name="atguigustack">
        <interceptor-ref name="paramsPrepareParamsStack">
            <param name="prepare.alwaysInvokePrepare">false</param>
        </interceptor-ref>
    </interceptor-stack>
</interceptors>
<!-- 配置使用paramsPrepareParams为拦截器栈 -->
<default-interceptor-ref name="atguigustack"></default-interceptor-ref>
<action name="emp-*" class="com.lizhenhua.struts2.app.EmployeeAction3" method="{1}">


<result name="{1}">emp-{1}.jsp</result>
<result name="success" type="redirectAction">emp-list</result>
</action>
</package>
</struts>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值