博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Struts2 简单的增删改查
阅读量:5327 次
发布时间:2019-06-14

本文共 12399 字,大约阅读时间需要 41 分钟。

1:主页面

然后到struts.xml文件中找到对应的emp-list

/pages/emp-list.jsp

然后在Action处理业务层处理。class="com.emp.app.EmployeeAction"  

package com.emp.app;import java.util.Map;import org.apache.struts2.interceptor.RequestAware;public class EmployeeAction implements RequestAware{        private Dao dao = new Dao();    private Employee employee; private Map
request;   public void setRequest(Map
arg0) { this.request = arg0; } public String List(){ System.out.println(dao.getEmployees()); request.put("emps", dao.getEmployees()); System.out.println(request.size()); return "list"; }   private Integer employeeId;          public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;     }     public String delete(){
        dao.deleteEmployees(employeeId);         return "success";     } }

到DAO层处理数据:

package com.emp.app;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.util.ValueStack;public class Dao {    ValueStack vs=ActionContext.getContext().getValueStack();    private static Map
emps = new LinkedHashMap
(); 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
getEmployees(){ return new ArrayList
(emps.values()); } public Employee deleteEmployees(Integer empId){ return emps.remove(empId); } }

处理完后 result到对应的页面展示数据。

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib prefix="s" uri="/struts-tags" %>      

显示全部

ID FirstName LastName Email Edit Delete
${employeeId } ${firstName } ${lastName } ${email } Edit Delete

 二:保存

 

1):struts2的运行流程。

 

拦截器中有个parameters拦截器。它的用处是:把表单字段映射到ValueStack栈的栈顶对象的各个属性中。如果某个字段在模型里没有匹配的属性。Param拦截器将尝试把字段压入到ValueStack栈中的下一个对象。

把表单的值赋给栈顶对象的属性。此时栈顶对象是Action。

拦截器的顺序是从第一个到最后一个依次进行。

 2):ModelDriven拦截器:

作用:将ModelDriven拦截器接口的getModel()方法返回的对象置于栈顶。

 

1. Action 实现 ModelDriven 接口后的运行流程

1). 先会执行 ModelDrivenInterceptor 的 intercept 方法.
    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();
    }
   
2). 执行 ParametersInterceptor 的 intercept 方法: 把请求参数的值赋给栈顶对象对应的属性. 若栈顶对象没有对应的属性, 则查询
值栈中下一个对象对应的属性...
3). 注意: getModel 方法不能提供以下实现. 的确会返回一个 Employee 对象到值栈的栈顶. 但当前 Action
的 employee 成员变量却是 null.
public Employee getModel() {
    return new Employee();
}   

 代码实现:

package com.emp.app;import java.util.Map;import org.apache.struts2.interceptor.RequestAware;import com.opensymphony.xwork2.ModelDriven;public class EmployeeAction implements RequestAware,ModelDriven
{ private Dao dao = new Dao(); private Employee employee; public Employee getModel() { employee=new Employee(); return employee; }public String save(){ dao.save(employee); return "success"; } }

DAO层:

public void save(Employee employee){        long time=System.currentTimeMillis();        employee.setEmployeeId((int)time);        emps.put(employee.getEmployeeId(), employee);    }

页面:emp-save.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib prefix="s" uri="/struts-tags" %>      

添加一个

四:修改

页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags" %>
Insert title here

 

DAO层:

public Employee get(Integer empId){        System.out.println(empId+"aaa");        return emps.get(empId);    }        public void update(Employee emp){        emps.put(emp.getEmployeeId(), emp);    }

先得到ID,然后修改Employee对象

package com.emp.app;import java.util.Map;import org.apache.struts2.interceptor.RequestAware;import com.opensymphony.xwork2.ModelDriven;public class EmployeeAction implements RequestAware,ModelDriven
{ private Dao dao = new Dao(); private Employee employee; public Employee getModel() {
    /*判断是创建还是修改。若是创建。employee=new Employee();       修改:employee=dao.get(employeeId);     判断标准就是有没有employeeId这个参数。     若通过employeeId来判断。需要在modelDriven拦截器先执行一个params拦截器。因为params拦截器是把表单的值赋予栈顶的对象。   需要在struts.xml中配置默认的 paramsPrepareParamsStack拦截器
    */   目的就是从栈顶中得到employee对象。然后修改的时候回显到emp-edit.jsp页面。 if(employeeId==null) employee=new Employee(); else employee=dao.get(employeeId); return employee; }private Integer employeeId; public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } public String edit(){ return "edit"; } public String update(){ dao.update(employee); return "success"; }}

 

5):存在的问题:getModel 方法public Employee getModel() {    if(employeeId == null)        employee = new Employee();    else        employee = dao.get(employeeId);        return employee;}I.   在执行删除的时候, employeeId 不为 null, 但 getModel 方法却从数据库加载了一个对象. 不该加载!II.  指向查询全部信息时, 也 new Employee() 对象. 浪费!. 解决方案: 使用 PrepareInterceptor 和 Preparable 接口.7). 关于 PrepareInterceptor[分析后得到的结论] 若 Action 实现了 Preparable 接口, 则 Struts 将尝试执行 prepare[ActionMethodName] 方法,若 prepare[ActionMethodName] 不存在, 则将尝试执行 prepareDo[ActionMethodName] 方法.若都不存在, 就都不执行.若 PrepareInterceptor  的 alwaysInvokePrepare 属性为 false,则 Struts2 将不会调用实现了 Preparable 接口的  Action 的 prepare() 方法[能解决 5) 的问题的方案]可以为每一个 ActionMethod 准备 prepare[ActionMethdName] 方法, 而抛弃掉原来的 prepare() 方法将 PrepareInterceptor  的 alwaysInvokePrepare 属性置为 false, 以避免 Struts2 框架再调用 prepare() 方法.如何在配置文件中为拦截器栈的属性赋值: 参看 /struts-2.3.15.3/docs/WW/docs/interceptors.html
token
----------------------------------源代码解析---------------------------------public String doIntercept(ActionInvocation invocation) throws Exception { //获取 Action 实例 Object action = invocation.getAction(); //判断 Action 是否实现了 Preparable 接口 if (action instanceof Preparable) { try { String[] prefixes; //根据当前拦截器的 firstCallPrepareDo(默认为 false) 属性确定 prefixes if (firstCallPrepareDo) { prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX}; } else { prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX}; } //若为 false, 则 prefixes: prepare, prepareDo //调用前缀方法. PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof Exception) { throw (Exception) cause; } else if(cause instanceof Error) { throw (Error) cause; } else { throw e; } } //根据当前拦截器的 alwaysInvokePrepare(默认是 true) 决定是否调用 Action 的 prepare 方法 if (alwaysInvokePrepare) { ((Preparable) action).prepare(); } } return invocation.invoke();}PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes) 方法:public static void invokePrefixMethod(ActionInvocation actionInvocation, String[] prefixes) throws InvocationTargetException, IllegalAccessException { //获取 Action 实例 Object action = actionInvocation.getAction(); //获取要调用的 Action 方法的名字(update) String methodName = actionInvocation.getProxy().getMethod(); if (methodName == null) { // if null returns (possible according to the docs), use the default execute methodName = DEFAULT_INVOCATION_METHODNAME; } //获取前缀方法 Method method = getPrefixedMethod(prefixes, methodName, action); //若方法不为 null, 则通过反射调用前缀方法 if (method != null) { method.invoke(action, new Object[0]); }}PrefixMethodInvocationUtil.getPrefixedMethod 方法:public static Method getPrefixedMethod(String[] prefixes, String methodName, Object action) { assert(prefixes != null); //把方法的首字母变为大写 String capitalizedMethodName = capitalizeMethodName(methodName); //遍历前缀数组 for (String prefixe : prefixes) { //通过拼接的方式, 得到前缀方法名: 第一次 prepareUpdate, 第二次 prepareDoUpdate String prefixedMethodName = prefixe + capitalizedMethodName; try { //利用反射获从 action 中获取对应的方法, 若有直接返回. 并结束循环. return action.getClass().getMethod(prefixedMethodName, EMPTY_CLASS_ARRAY); } catch (NoSuchMethodException e) { // hmm -- OK, try next prefix if (LOG.isDebugEnabled()) { LOG.debug("cannot find method [#0] in action [#1]", prefixedMethodName, action.toString()); } } } return null;}

 使用:ModelDriven<Employee>, Preparable

package com.atguigu.struts2.app;import java.util.Map;import org.apache.struts2.interceptor.RequestAware;import com.opensymphony.xwork2.ModelDriven;import com.opensymphony.xwork2.Preparable;public class EmployeeAction implements RequestAware, ModelDriven
, Preparable{ private Dao dao = new Dao(); private Employee employee; public String update(){ dao.update(employee); return "success"; } public void prepareUpdate(){ employee = new Employee(); } public String edit(){ return "edit"; } public void prepareEdit(){ employee = dao.get(employeeId); } public String save(){ dao.save(employee); return "success"; } public void prepareSave(){ employee = new Employee(); } public String delete(){ dao.delete(employeeId); return "success"; } public String list(){ request.put("emps", dao.getEmployees()); return "list"; } private Map
request; @Override public void setRequest(Map
arg0) { this.request = arg0; } private Integer employeeId; public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } @Override public Employee getModel() { return employee; } @Override public void prepare() throws Exception { System.out.println("prepare..."); } }

在struts.xml中修改 PrepareInterceptor 拦截器的 alwaysInvokePrepare 属性值为 false

false

 

转载于:https://www.cnblogs.com/bulrush/p/7759816.html

你可能感兴趣的文章
Object-C Xcode 编译提示 note: please rebuild precompiled header ZWYLPrefixHeader
查看>>
使用InternetGetConnectedState判断本地网络状态(C#举例)
查看>>
ios 读取通讯录数据
查看>>
Shapley值的一个应用
查看>>
遍历父视图上的button
查看>>
Tomcat安装后,远程IP无法访问的问题。
查看>>
在Ubuntu11.10中如何将“打开终端”添加进右击菜单选项中
查看>>
区分Activity的四种加载模式
查看>>
锁的阻塞,死锁,锁升级
查看>>
JZOJ #4711 Binary (按位操作 + 树状数组)
查看>>
IA-32 保护模式 实模式
查看>>
java.lang.RuntimeException: Annotation processors must be explicitly declared now.
查看>>
自定义类加载器深入详解
查看>>
为什么有时候修改了css文件,页面的样式却没有改变?
查看>>
QuantLib 金融计算——数学工具之优化器
查看>>
Mysql基础知识--触发器
查看>>
ORM篇——有关NHibernate查询封装
查看>>
微信sdk分享功能详解
查看>>
linux 硬盘信息查看
查看>>
获取公网IP地址
查看>>