Struts2学习总结(十一):Struts2的CRUD

来源:互联网 发布:java身份证识别技术 编辑:程序博客网 时间:2024/06/02 00:45

CRUD是Create(创建)、Read(读取)、Update(更新)和Delete(删除)的缩写。

如果你熟练的掌握了CRUD,就可以应用某个框架来创建普通的应用程序

示例:创建,读取全部信息,删除,更新

(1)创建一个Employee对象:并实现对象属性的set和get方法。创建这个对象的有参和无参的构造方法

package compublic class Employee {    private Integer id;    private String firstName;    private String lastName;    private String email;    public void setId(Integer id) {        this.id = id;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    public void setEmail(String email) {        this.email = email;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public Integer getId() {        return id;    }    public String getFirstName() {        return firstName;    }    public String getEmail() {        return email;    }    public String getLastName() {        return lastName;    }    public Employee(Integer id,String firstName,String lastName,String email)    {        super();        this.email=email;        this.firstName=firstName;        this.lastName=lastName;        this.id=id;    }    public Employee()    {    }    public String toString() {        return "Employee [employeeId=" + id + ", firstName="                + firstName + ", lastName=" + lastName + ", email=" + email                + "]";    }}

(2)创建一个 关数据的基本操作的类:实现获取信息,删除,保存等方法。并没有数据库连接,所以只是用容器存储了数据。

将信息存放在一个Map容器里。因为request是一个Map类型的,将信息就可以存放在request中,以方便读取。

package com;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Dao {    /*    * 对数据进行操作    *    * */    private static Map<Integer ,Employee> emps=new HashMap<Integer,Employee>();    static {        emps.put(1001, new Employee(1001, "AA", "aa", "aa@atguigu.com"));        emps.put(1002, new Employee(1002, "BB", "bb", "bb@atguigu.com"));        emps.put(1003, new Employee(1003, "CC", "cc", "cc@atguigu.com"));        emps.put(1004, new Employee(1004, "DD", "dd", "dd@atguigu.com"));        emps.put(1005, new Employee(1005, "EE", "ee", "ee@atguigu.com"));    }    //获取全部信息    public List<Employee> getEmps() {        return  new ArrayList<>(emps.values());    }    //删除    public void delete(int id)    {        emps.remove(id);    }    //存储    public void save(Employee employee)    {        long time=System.currentTimeMillis();        employee.setId((int)time);        emps.put(employee.getId(),employee);    }    //获取    public Employee get(Integer id)    {        return emps.get(id);    }    //更新    public void update(Employee emp)    {        emps.put(emp.getId(),emp);    }}

(3)创建Action并实现RequestAware接口 :调用dao层的方法进行操作。

思路一:(较为麻烦),在当前的Action类中定义Employee对象的属性,用于接收参数

package com;import org.apache.struts2.interceptor.RequestAware;import java.util.Map;public class EmpAction implements RequestAware{    private Dao dao=new Dao();    private Map<String,Object> request;    //获得所有信息    public String list()    {        request.put("emps",dao.getEmps());        return "list";    }    //对request进行初始化    @Override    public void setRequest(Map<String, Object> arg0) {        this.request = arg0;    }    //定义employee的id属性,以便接受参数    private Integer id;    private String firstName;    private String lastName;    private String email;    public void setLastName(String lastName) {        this.lastName = lastName;    }    public void setEmail(String email) {        this.email = email;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    public void setId(Integer id) {        this.id = id;    } //    private Employee employee;    //会把请求参数给栈顶的属性。删除后要显示删除后的信息,所以可以跳转到action    public String delete()    {        //返回类型为:redirectAction        //也可以是chain, 实际上可以不需要用chain        // 因为:不需要在下一个Action时保留当前Action状态        //若使拥chain,则达到目标页面后,地址栏显示的依然是删除的页面,刷新时会重复提交        dao.delete(id);        return "success";    }    public String save()    {        //1.获取请求参数:通过定义对应属性的方式        //2.调用Dao的save方法       Employee employee=new Employee(null,firstName,lastName,email);        dao.save(employee);        //3.通过redirectAction的方式相应给emp-list        return "success";    }}

思路二:

上面的代码因为Action再次编写了Employee属性的set方法,使代码较为冗长。为了程序的简洁性,Struts2框架会将Action和Model分隔开。

 没使用struts-default.xml默认的拦截器栈,而是使用了paramsPrepareParams拦截器栈(params->prepare->modelDriven->params)。

  • 采用了ModelDriven: Action 类实现了 ModelDriven 接口,该拦截器将把 ModelDriven 接口的 getModel() 方法返回的对象置于栈顶。
  • 采用params:把请求参数的值赋给栈顶对象对应的属性.
  • 实现了Prepare接口:执行PrepareInterceptor拦截器。在执行execute()方法前加入一些其他业务逻辑。为ModelDriven的getModel()方法准备model

处理流程:     

  a:  执行ParametersInteceptors的Intecept()方法(params)。把请求参数的值赋给栈顶对象对应的属性. 若栈顶对象没有对应的属性, 则查询
值栈中下一个对象对应的属性...

注意:getModel方法不能提供以下的实现,的确会返回一个Employee对象到值栈的栈顶,但是返回的Emplyoee的成员变量为空

public Employee getModel() {return new Employee();}    

b:实现Prepareable接口,在为Action的方法编写prepareXxx()方法。为ModelDriven准备model

c:先回执行ModelDrivenInterceptor的intecept方法,对这个方法进行解释:

 public String intercept(ActionInvocation invocation) throws Exception {    //获取 Action 对象: EmployeeAction 对象, 此时该 Action 已经实现了 ModelDriven 接口    //public class EmployeeAction implements RequestAware, ModelDriven<Employee>        Object action = invocation.getAction();//判断 action 是否是 ModelDriven 的实例        if (action instanceof ModelDriven) {        //强制转换为 ModelDriven 类型            ModelDriven modelDriven = (ModelDriven) action;            //获取值栈            ValueStack stack = invocation.getStack();            //调用 ModelDriven 接口的 getModel() 方法            //即调用 EmployeeAction 的 getModel() 方法            /*            public Employee getModel() {employee = new Employee();return employee;}            */            Object model = modelDriven.getModel();            if (model !=  null) {            //把 getModel() 方法的返回值压入到值栈的栈顶. 实际压入的是 EmployeeAction 的 employee 成员变量            stack.push(model);            }            if (refreshModelBeforeResult) {                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));            }        }        return invocation.invoke();    }   

代码示例:

import java.util.Map;import org.apache.struts2.interceptor.RequestAware;import com.opensymphony.xwork2.ModelDriven;import com.opensymphony.xwork2.Preparable;import com.qiaobc.crud.dao.Dao;import com.qiaobc.crud.domin.Employee;public class EmployeeAction implements RequestAware, ModelDriven<Employee>, Preparable {    private Dao dao = new Dao();    /**     * 1. 查找所有员工信息     * @return     */    public String list() {        // 获取所有员工信息,并保存在request请求域中        request.put("emps", dao.getAll());        return "list";    }    // 获取request请求域所对应的Map对象    private Map<String, Object> request;    @Override    public void setRequest(Map<String, Object> arg0) {        this.request = arg0;    }    /**     * 2. 删除一条员工信息     * 方法:在当前Action类中定义employeeId属性,用于接收请求参数     * 注意:返回结果的类型应为redirectAction,即重定向到action:struts.xml文件配置     *  若使用chain,则到达目标页面后,地址栏显示的仍为emp-delete.do,会重复提交,不需要在下一个Action时保留上一个Action的状态     * @return     */    public String delete() {        // 获取请求参数employeeId        dao.delete(employeeId);        return "success";    }      // 定义成员变量employee,利用ModelDriven的getModel()方法为其创建对象并压入值栈    private Employee employee;  @Override    public Employee getModel() {//      if(employeeId == null) {    //          // 注意:不能直接使用return new Employee();//          employee = new Employee();//      } else {//          employee = dao.get(employeeId);//      }        return employee;    } public String save() {  // 获取请求参数并封装为Employee对象,添加到数据库中 dao.add(employee); // 返回结果类型仍为redirectAction     return "success";    }      public void prepareSave() {         employee = new Employee();      } private Integer employeeId; public void setEmployeeId(Integer employeeId)    { this.employeeId = employeeId; }      public String edit() {     /*************************思路1:*************************/      // 此时栈顶对象即为employee,其除employeeId属性外均为null      // 1. 根据请求参数employeeId获取对应的Employee对象     // Employee emp = dao.get(employee.getEmployeeId());//      // 2. 封装栈顶对象employee的属性信息    // employee.setFirstName(emp.getFirstName());    // employee.setLastName(emp.getLastName());   // employee.setEmail(emp.getEmail()); /*************************思路2:失败**************************/    // // 经过重新赋值的employee对象不再是栈顶对象   // employee = dao.get(employee.getEmployeeId()); /*************************思路3:**************************/ // // 将获取的emp对象直接压入值栈,但有浪费之嫌(此时值栈中有两个Employee对象)// ActionContext.getContext().getValueStack().push(dao.get(employee.getEmployeeId())); /*************************解决方案******************************/ // 方案:在genModel()方法中根据请求参数employeeId获取Employee对象并返回 // 判断是Add还是Edit(判定标准:是否有employeeId参数),Add新建而Edit从数据库中获取 // 注意:若通过employeeId来判断,则需要在modelDriven拦截器执行前先执行一个params拦截器! // 此时可以通过使用paramsPrepareParams拦截器栈来实现,在struts.xml文件中配置即可。         return "edit";} public void prepareEdit() {       employee = dao.get(employeeId); } public String update() {       dao.update(employee);       return "success";  } public void prepareUpdate() {     employee = new Employee(); } // 配置PrepareInterceptor的alwaysInvokePrepare属性为false,使当前方法不执行 @Override 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" namespace="/" extends="struts-default">        <!-- 配置使用 paramsPrepareParamsStack 作为默认的拦截器栈 -->        <!-- 修改 PrepareInterceptor 拦截器的 alwaysInvokePrepare 属性值为 false -->        <interceptors>            <interceptor-stack name="atguigustack">                <interceptor-ref name="paramsPrepareParamsStack">                    <param name="prepare.alwaysInvokePrepare">false</param>                </interceptor-ref>            </interceptor-stack>        </interceptors>        <default-interceptor-ref name="atguigustack"/>        <action name="emp-*"                class="com.EmpAction"                method="{1}">            <result name="{1}">emp-{1}.jsp</result>            <result name="success" type="redirectAction">emp-*</result>        </action>        <action name="emp-list"                class="com.EmpAction"                method="list">            <result name="list">/emp-list.jsp</result>        </action>    </package></struts>
jsp:
emp-edit.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></head><body><s:debug></s:debug><br><br><s:form action="emp-update"><s:hidden name="employeeId"></s:hidden><s:textfield name="firstName" label="FirstName"></s:textfield><s:textfield name="lastName" label="LastName"></s:textfield><s:textfield name="email" label="Email"></s:textfield><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></head><body><s:form action="emp-save"><s:textfield name="firstName" label="FirstName"></s:textfield><s:textfield name="lastName" label="LastName"></s:textfield><s:textfield name="email" label="Email"></s:textfield><s:submit></s:submit></s:form><br><hr><br><table cellpadding="10" cellspacing="0" border="1"><thead><tr><td>ID</td><td>FirstName</td><td>LastName</td><td>Email</td><td>Edit</td><td>Delete</td></tr></thead><tbody><s:iterator value="#request.emps"><tr><td>${employeeId }</td><td>${firstName }</td><td>${lastName }</td><td>${email }</td><td><a href="emp-edit?employeeId=${employeeId }">Edit</a></td><td><a href="emp-delete?employeeId=${employeeId }">Delete</a></td></tr></s:iterator></tbody></table></body></html><%System.out.println("now: " + new java.util.Date());%>
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></body></html>




总结:
    通过这个增添改查了解到了Struts2的CRUD。实现CRUD时,注意:
保证Action和Model分割开,使用ModelDriven
 为向ModelDriven的getModel()方法准备Model,实现了params拦截器和prepare拦截器。前一个向栈顶对象赋值,后一个获取对象
 在struts.xml不再使用默认拦截器栈,改为paramsPrepareParams拦截器栈(提供了params,prepare,modelDriven)



原创粉丝点击