zoukankan      html  css  js  c++  java
  • struts2进阶篇(2)

    一、Action与MVC
    struts2是一个基于MVC的web应用框架,它将应用程序分为三个组件:模型,视图,控制器。
    模型:包含了应用程序的业务逻辑和业务数据,由封装数据和处理业务的javaBean组成。
    视图:封装了应用程序的输出形式,也就是页面,如jsp,html。
    控制器:负责接收用户的http请求,再调用模型中响应的方法来处理业务,然后调用响应的视图作为显示。
    三者共同协同处理响应客户端的请求。

    在struts2中控制器分为两部分:
    1.核心控制器:它就是在web.xml中配置的StrutsPrepareAndExecuteFilter负责过滤用户的所有请求,根据请求不同,分发不同的Action处理。
    2.业务控制器:也就是Action,负责调用模型来实现请求的业务,并把结果交给视图层。

    二、Action接收参数
    在action中接收用户从jsp传入的参数有三种方式:
    1.属性方式
    2.JavaBean方式
    3.ModelDriven方式

    1.属性方式:

    在action 里面定义要接收的参数,并提供相应的setter,getter方法。注:Action中定义的属性需和提交参数的名称一致。

    在Action类中定义与请求参数同名的属性,struts2便能自动接收请求参数并赋予给同名的属性。

    <form action="testAction!login" method="post"> 
        用户名:&nbsp;<input type="text" name="username"/><br/>
        密码:&nbsp;<input type="password" name="password"/><br/>
        <input type="submit" value="提交"/> 
        <input type="reset" value="重置"/> 
    </form> 
    package com.lxx.action;
    import com.opensymphony.xwork2.ActionSupport;
    
    public class TestAction extends ActionSupport {
    
        private String username;
        private String password;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String execute() {    
            return "index";
        }
        
        public String login(){
            System.out.println("用户名:"+username + "-----------------"+"密码:"+password);
            return "index";
        }
    }

    说明:
    (1)在form表单中的用户名和密码的<input>标签中的name属性username和password,和action中的定义的成员变量username和password相同,在提交表单时struts会把值赋为名字相同的字段名。
    (2)如果参数包含中文,则action接收可能存在乱码,可以修改struts.xml文件,添加<constant name="struts.i18n.encoding" value="utf-8">

    2.JavaBean的方式

    (1)、定义User对象实体类,并添加username,password和相应的get,set方法

    package com.lxx.model;
    
    public class User {
        private String username;
        private String password;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
    }

    (2)、添加JavaBean的action,添加User类型的成员变量user和get,set方法。

    package com.lxx.action;
    import com.lxx.model.User;
    import com.opensymphony.xwork2.ActionSupport;
    
    public class TestAction extends ActionSupport {
    
        private User user;
      //错误的写法,不能自己实例化,struts会自动实例化 
      //private User user = new User();

      public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String execute() { return "index"; } public String login(){ System.out.println("用户名:"+user.getUsername() + "-----------------"+"密码:"+user.getPassword()); return "index"; } }

    获取Bean属性的原理:
    Struts2首先通过反射技术调用User的默认构造器创建user的实例,然后再通过反射技术调用user中与请求参数同名的属性的setter方法,来获取请求参数数值。

    (3)、form表单中添加页面代码:

    <form action="testAction!login" method="post"> 
        用户名:&nbsp;<input type="text" name="user.username"/><br/>
        密码:&nbsp;<input type="password" name="user.password"/><br/>
        <input type="submit" value="提交"/> 
        <input type="reset" value="重置"/> 
    </form> 

    说明:
    (1).在提交form表单时会将属性值通过User实体属性传递给Action,但必须保持前后属性的一致性。
    (2).在jsp页面中,<input>标签的name属性需要添加对象,即“对象名.属性名”这种形式,如name="user.username"。

    3.ModelDriven方式接收参数
    在action中实现ModelDriven接口来接收客户端上传的参数,这种方式仍然需要实体User。
    它的运行过程是:Struts2调用ModelDriven接口中的getModel()方法取得Action中的user对象,再把上传的用户名密码存入user对象。

    package com.lxx.action;
    import com.lxx.model.User;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    public class TestAction extends ActionSupport implements ModelDriven<User> {
        //手动实例化
        private User user = new User();
        
        public User getModel() { 
            //返回实例
            return user; 
        } 
    
        public String execute() {    
            return "index";
        }
        
        public String login(){
            System.out.println("用户名:"+user.getUsername() + "-----------------"+"密码:"+user.getPassword());
            return "index";
        }
    }
    <form action="testAction!login" method="post"> 
        用户名:&nbsp;<input type="text" name="username"/><br/>
        密码:&nbsp;<input type="password" name="password"/><br/>
        <input type="submit" value="提交"/> 
        <input type="reset" value="重置"/> 
    </form>

    说明:
    使用ModelDriven方式接收页面参数,name属性不需要添加对象,即name="username";

    总结:

    Struts2中Action接收参数的方法主要有以下三种:
    1.使用Action的属性接收参数:
        a.定义:在Action类中定义属性,创建get和set方法;
        b.接收:通过属性接收参数,如:userName;
        c.发送:使用属性名传递参数,如:user1!add?userName=Magci;
    2.使用DomainModel接收参数:
        a.定义:定义Model类,在Action中定义Model类的对象(不需要new),创建该对象的get和set方法
        b.接收:通过对象的属性接收参数,如:user.getUserName();
        c.发送:使用对象的属性传递参数,如:user2!add?user.userName=MGC;
    3.使用ModelDriven接收参数:
        a.定义:Action实现ModelDriven泛型接口,定义Model类的对象(必须new),不需要提供该对象的get和set方法,通过getModel方法返回该对象
        b.接收:通过对象的属性接收参数,如:user.getUserName();
        c.发送:直接使用属性名传递参数,如:user2!add?userName=MGC

    三、Struts.xml中<action>标签中method属性的用法

    1.在<action>的配置代码中method属性默认调用action类的execute()方法,但是在实际应用中一个action需要处理很多方法,就可以添加method="不同的方法名"来调用acton中对应的方法。

    <?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.devMode" value="true" /> 
        <constant name="struts.i18n.encoding" value="utf-8" /> 
        <package name="default" namespace="/" extends="struts-default"> 
              
            <action name="login" class="com.demo.action.UserAction" method="login"> 
                <result type="chain">all</result> 
                <result name="input">login.jsp</result> 
            </action> 
          
            <action name="all" class="com.demo.action.DeptAction" method="getDept"> 
                <result>list.jsp</result> 
            </action> 
      
        </package> 
    </struts> 

    上面<action>标签中定义method='login'和method='getDept'方法,就会请求Action类中方法名为login和getDept的方法。

    2.动态方法调用

    <?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.devMode" value="true" /> 
        <constant name="struts.i18n.encoding" value="utf-8" /> 
        
        <package name="default" namespace="/" extends="struts-default"> 
            <action name="login" class="com.demo.action.UserAction"> 
                <result name="input">login.jsp</result> 
            </action> 
        </package> 
    </struts> 

    不难发现上面的方法并没有指定具体调用哪个方法,这是因为在下面的form表单中指定。

    <form action="login!userLogin" method="post"> 
        用户名:&nbsp;<input type="text" name="user.username"/><br/>
        密码:&nbsp;<input type="password" name="user.password"/><br/>
        <input type="submit" value="提交"/> 
        <input type="reset" value="重置"/> 
    </form>

    在form表单中的action="login!userLogin"会调用Action类中的userLogin方法。
    不难发现动态调用的语法是:actionName!methodName.action,其中.action可以省略,但是值得注意的是,动态方法调用可能会带了安全隐患,暴露业务方法给用户,官方也不推荐这样用,不过可以在struts.xml中添加<constant name="struts.enable.DynamicMethodInvocation" value="false"/>来禁用动态方法调用。

    四、使用通配符简化struts.xml中<action>标签的配置
    1.在<action>中使用通配符简化配置
    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.devMode" value="true" /> 
        <constant name="struts.i18n.encoding" value="utf-8" /> 
        
        <package name="default" namespace="/" extends="struts-default"> 
            <action name="house_*" class="com.demo.action.HouseAction" method="{1}"> 
                <result>list_{1}.jsp</result> 
            </action> 
        </package> 
    </struts> 

     以上的配置在jsp页面的<form action="house_add"></form>或者<form action="house_update"></form>都会得到响应的请求,也就是action属性是house_任意字符都会得到请求,返回result中的list_任意字符的jsp页面,也就是house_后面的字符和{1}是一样的匹配。

    问题:当有多个<action>匹配的时候会匹配哪个?
    假如有下配置会匹配哪个呢:

    <?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.devMode" value="true" /> 
        <constant name="struts.i18n.encoding" value="utf-8" /> 
        
        <package name="default" namespace="/" extends="struts-default"> 
            <action name="house_add" class="com.demo.action.HouseAction" method="add"> 
                <result name="success">add.jsp</result> 
            </action> 
          
            <action name="house_*" class="com.demo.action.HouseAction" method={1}> 
                <result>{1}.jsp</result> 
            </action> 
        </package> 
    </struts> 

    答案:如果有完全匹配的就优先使用完全匹配的,没有完全匹配的使用通配符匹配,如果有多个通配符匹配的,按照先后顺序优先使用在前的匹配。

  • 相关阅读:
    Adventure C CF-665E(字典树、二进制)
    实验7投资问题
    Beautiful Array CF-1155D(DP)
    Salary Changing CF-1251D(二分)
    Beautiful Sets of Points CF-268C(乱搞)
    Vasya And Array CF1187C(构造)
    Tree Painting CF-1187E(换根DP)
    Vus the Cossack and Numbers CF-1186D(思维)
    Tree POJ-1741(点分治+树形DP)
    Magical Girl Haze 计蒜客-A1958(分层最短路)
  • 原文地址:https://www.cnblogs.com/xiaoxi/p/5688049.html
Copyright © 2011-2022 走看看