zoukankan      html  css  js  c++  java
  • Struts2 简单的增删改查

    1:主页面

    <a href="emp-list">emp-list</a> <br>

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

    <action name="emp-list" class="com.emp.app.EmployeeAction" method="List">
           <result name="list">/pages/emp-list.jsp</result>
    </action>

    然后在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<String, Object> request;
      public void setRequest(Map<String, Object> 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<Integer, Employee> emps = new LinkedHashMap<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> getEmployees(){
            return new ArrayList<Employee>(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" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <h1>显示全部</h1>
      </head>
              
      <body>
        <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>
        <s:debug></s:debug>
      </body>
    </html>

     二:保存

    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<Employee>{
        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" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <h1>添加一个</h1>
      </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>
        <s:debug></s:debug>
      </body>
    </html>

    四:修改

    页面:

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

    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<Employee>{
        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拦截器
    <default-interceptor-ref name="paramsPrepareParamsStack"></default-interceptor-ref>
        */
      目的就是从栈顶中得到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
    
    <interceptors>
        <interceptor-stack name="parentStack">
            <interceptor-ref name="defaultStack">
                <param name="params.excludeParams">token</param>
            </interceptor-ref>
        </interceptor-stack>
    </interceptors>
     
    <default-interceptor-ref name="parentStack"/>
    
    ----------------------------------源代码解析---------------------------------
    
    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<Employee>, 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<String, Object> request;
    
        @Override
        public void setRequest(Map<String, Object> 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

    <!-- 配置使用 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"/>



  • 相关阅读:
    [Unity3D]调用Android接口
    android studio build.gradle中 project.ANDROID_BUILD_SDK_VERSION
    java中static{}语句块详解
    [Android][Android Studio] *.jar 与 *.aar 的生成与*.aar导入项目方法
    c++中 extern
    android studio一直卡在Gradle:Executing tasks
    Android Studio导入第三方类库的方法
    Android按返回键退出程序但不销毁,程序后台运行,同QQ退出处理方式
    Ubuntu64位下使用eclipse闪退的解决
    Android4.1中BinderService的作用
  • 原文地址:https://www.cnblogs.com/bulrush/p/7759816.html
Copyright © 2011-2022 走看看