zoukankan      html  css  js  c++  java
  • Struts学习笔记_Action

    一,struts运行机制:

     二,namesapce

    1,  packsge 解决重名问题

    2 , namespace决定了action的访问路径,默认为"",可以接收所有路径的action
    namespace可以写为/,或者/xxx,或者/xxx/yyy,对应的action访问路径为/index.action, /xxx/index.action,或者/xxx/yyy/index.action.
    namespace最好也用模块来进行命名

    3, 具体视图的返回可以由用户自己定义的Action来决定
    具体的手段是根据返回的字符串找到对应的配置项,来决定视图的内容
    具体Action的实现可以是一个普通的java类,里面有public String execute方法即可
    或者实现Action接口
    不过最常用的是从ActionSupport继承,好处在于可以直接使用Struts2封装好的方法

    <package name="front" extends="struts-default" namespace="/">
            <action name="index" class="com.bjsxt.struts2.front.action.IndexAction3">//当访问action时,会找到class内容,通过IndexAction3的execute()方法返回的内容
                <result name="success">/ActionIntroduction.jsp</result>                //与result 中的name比对与来决定视图的内容
            </action>
        </package>
    public class IndexAction3 extends ActionSupport {
        
        @Override
        public String execute() {
            return "success";
        }
    }

    4, struts2中的路径问题是根据action的路径而不是jsp路径来确定,所以尽量不要使用相对路径。
    虽然可以用redirect方式解决,但redirect方式并非必要。
    解决办法非常简单,统一使用绝对路径。(在jsp中用request.getContextRoot方式来拿到webapp的路径)
    或者使用myeclipse经常用的,指定basePath

    <%
      String path = request.getContextPath();
    
      String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  //相当于http://localhost:8080/...
    %>

    Head里面

    
    

    <base href="<%=basePath%>" /》

    
    
     

    5, Action执行的时候并不一定要执行execute方法可以在配置文件中配置Action的时候用method=来指定执行哪个方法

    <struts>
        <constant name="struts.devMode" value="true" />
        <package name="user" extends="struts-default" namespace="/user">
            <action name="userAdd" class="com.bjsxt.struts2.user.action.UserAction" method="add">
                <result>/user_add_success.jsp</result>
            </action>
            
            <action name="user" class="com.bjsxt.struts2.user.action.UserAction">
                <result>/user_add_success.jsp</result>
            </action>
        </package>
    </struts>

      也可以在url地址中动态指定(动态方法调用DMI)(推荐) 

    <a href="<%=context %>/user/userAdd">添加用户</a>
    
        <a href="<%=context %>/user/user!add">添加用户</a>

        前者会产生太多的action,所以不推荐使用

    6, 使用通配符,将配置量降到最低
    不过,一定要遵守"约定优于配置"的原则

        <action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
    
                <result>/Student{1}_success.jsp</result>
    
            </action>
    
           
    
            <action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
    
                <result>/{1}_{2}_success.jsp</result>
    
                <!-- {0}_success.jsp -->
    
            </action>

     

    7, 参数传递的四个方法:

    • 使用action属性接受参数name=a&age=2;
    使用action属性接收参数<a href="user/user!add?name=a&age=8">添加用户</a>
    public class UserAction extends ActionSupport {
        
        private String name;
        private int age;
        
        public String add() {
            System.out.println("name=" + name);
            System.out.println("age=" + age);
            return SUCCESS;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
        
        
    }
    • 域模型  user.name=a&user.age=2;
    使用Domain Model接收参数<a href="user/user!add?user.name=a&user.age=8">添加用户</a>
    public class UserAction extends ActionSupport {
        
        private User user;
        //private UserDTO userDTO;
        public String add() {
            System.out.println("name=" + user.getName());
            System.out.println("age=" + user.getAge());
            return SUCCESS;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
        
    }
    • DTO(数据传输对象),

    DTO用于解决传入参数和DomainModel中属性不匹配问题。可以先将传入参数传入到DTO中,再将相应的参数传入搭配DomainModel中。

    如何是用户登录,希望有一个用户名,一个密码,一个确认密码。可是我们的用户域模型通常只有两个属性:用户名,密码。

    那么用域模型就不可以了。那么如何解决这个问题呢?

    1、答:可以直接用属性接收,如果喜欢用域模型,则再建立一个user。

    2、除了上面方法外,,还有一种方式,就是再定义一个DTO(data transfer object)数据传输对象。,由这个对象,再生成域对象。

     public class UserDTO {
    
        private String name;
    
        private String password;
    
        private String confirmingpassword;
    
        public String getName() {
    
           return name;
    
        }
    
        public void setName(String name) {
    
           this.name = name;
    
        }
    
        public String getPassword() {
    
           return password;
    
        }
    
        public void setPassword(String password) {
    
           this.password = password;
    
        }
    
        public String getConfirmingpassword() {
    
           return confirmingpassword;
    
        }
    
        public void setConfirmingpassword(String confirmingpassword) {
    
           this.confirmingpassword = confirmingpassword;
    
        }
    
     
    
    }

    在UserAction类中用UserDTO属性

    public class UserAction extends ActionSupport {  
    
           private User user;
    
           //private UserDTO userDTO;
    
           public String add(){
    
                  System.out.println("name="+user.getName());
    
                  System.out.println("age="+user.getAge());
    
                  return SUCCESS;
    
           }
    
           public User getUser() {
    
                  return user;
    
           }
    
           public void setUser(User user) {
    
                  this.user = user;
    
           }
    
    }
    
    
    这样前台输入进来的参数,就与UserDTO相匹配了。
    
    然后在UserAction里面处理完之后,再根据UserDTO ,生成User对象。
    
    方法就是从UserDTO里面拿到相应的参数,添加到User里面。
    
    UserDTO就是把参数传递过来,在new User时,再把参数传递给User对象。
    • ModelDriven

    实现了ModelDriven接口,当接收到参数时,先new一个action,发现它实现了ModelDrven接口,然后就会调用GetModel()方法并返回User类型的user

    使用ModelDriven接收参数<a href="user/user!add?name=a&age=8">添加用户</a>
    public class UserAction extends ActionSupport implements ModelDriven<User>{
        
        private User user = new User();
        
        public String add() {
            System.out.println("name=" + user.getName());
            System.out.println("age=" + user.getAge());
            return SUCCESS;
        }
    
        @Override
        public User getModel() {
            return user;
        }
        
    }

    8,  传中文参数

        在strust.xaml 中

    <constant name="struts.i18n.encoding" value="GBK" /> <!-- internationalization -->

    9, 使用addFieldError方法和s:fieldError标签简单处理数据校验

    定义一个action

    public class UserAction extends ActionSupport {
        private String name;
        
        public String add() {
            if(name == null || !name.equals("admin")) {
                this.addFieldError("name", "name is error"); //通过addFieldError方法把内容写到值栈中,在Jsp中s:fieldError标签或s:property读取
                this.addFieldError("name", "name is too long"); //一个name可有多个值
                return ERROR;
            } 
            return SUCCESS;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
        
    }

    在jsp中

    <?xml version="1.0" encoding="GB18030" ?>
    <%@ page language="java" contentType="text/html; charset=GB18030"
        pageEncoding="GB18030"%>
    <%@taglib uri="/struts-tags" prefix="s" %> <!-- 添加标签的url ,指向标签所在标签库,prefix指定所用标签的前缀-->
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
    <title>Insert title here</title>
    </head>
    <body>
        User Add Error!
        <s:fielderror fieldName="name" theme="simple"/>   <!-- 读取值栈中的值方法1-->
        <br />
        <s:property value="errors.name[0]"/>   <!-- 读取值栈中的值方法2,用来去valuestack和context的属性-->
        <s:debug></s:debug><!-- 调试,查看值栈内容-->
    </body>
    </html>

    10,访问web元素

    取得Map类型request,session,application的引用

    方法一:依赖于容器

    public class LoginAction1 extends ActionSupport {
        
        private Map request;
        private Map session;
        private Map application;
        
        public LoginAction1() {
            request = (Map)ActionContext.getContext().get("request");
            session = ActionContext.getContext().getSession();        //actionContext 放置action执行时的内容
            application = ActionContext.getContext().getApplication();
        }
        
        public String execute() {
            request.put("r1", "r1");
            session.put("s1", "s1");
            application.put("a1", "a1");
            return SUCCESS; 
        }
        
        
    }

    在jsp中

    <body>
        User Login Success!
        <br />
        <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br /> <!-- 取得Stack Context中的request-->
        <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />
        <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />
        <s:property value="#attr.a1"/><br /><!--不怎么用-->
        <s:property value="#attr.s1"/><br />
        <s:property value="#attr.r1"/><br />
        <s:debug></s:debug>
        <br />
    </body>

    方法二;DI/IOC,实现了RequestAware,SessionAware, ApplicationAware接口,让struts给我们拿到request。。。(最常用,其他可以不纪)

    public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {
        
        private Map<String, Object> request;
        private Map<String, Object> session;
        private Map<String, Object> application;
        
        //DI dependency injection
        //IoC inverse of control
        public String execute() {
            request.put("r1", "r1");
            session.put("s1", "s1");
            application.put("a1", "a1");
            return SUCCESS; 
        }
    
        @Override
        public void setRequest(Map<String, Object> request) {
            this.request = request;
        }
    
        @Override
        public void setSession(Map<String, Object> session) {
            this.session = session;
        }
    
        @Override
        public void setApplication(Map<String, Object> application) {
            this.application = application;
        }
        
        
    }

    在jsp中

    <body>
        User Login Success!
        <br />
        <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br /> <!-- 取得Stack Context中的request-->
        <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />
        <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />
        <s:property value="#attr.a1"/><br /><!--不怎么用-->
        <s:property value="#attr.s1"/><br />
        <s:property value="#attr.r1"/><br />
        <s:debug></s:debug>
        <br />
    </body>

     获取真实类型 HttpServletRequest, HttpSession, ServletContext的引用(不常用)

    方法一:依赖于容器

    public class LoginAction3 extends ActionSupport {
        
        private HttpServletRequest request;
        private HttpSession session;
        private ServletContext application;
        
        public LoginAction3() {
            request = ServletActionContext.getRequest();
            session = request.getSession();
            application = session.getServletContext();
        }
        
        public String execute() {
            request.setAttribute("r1", "r1");
            session.setAttribute("s1", "s1");
            application.setAttribute("a1", "a1");
            return SUCCESS; 
        }
        
    }

    方法二:DI/IOC

    public class LoginAction4 extends ActionSupport implements ServletRequestAware {
        
        private HttpServletRequest request;
        private HttpSession session;
        private ServletContext application;
        
        
        
        public String execute() {
            request.setAttribute("r1", "r1");
            session.setAttribute("s1", "s1");
            application.setAttribute("a1", "a1");
            return SUCCESS; 
        }
    
    
    
        @Override
        public void setServletRequest(HttpServletRequest request) {
            this.request = request;
            this.session = request.getSession();
            this.application = session.getServletContext();
        }
        
    }

    11,incluse

    <struts>
        <constant name="struts.devMode" value="true" />
        <include file="login.xml" />
    </struts>

     12,默认的action

    <struts>
        <constant name="struts.devMode" value="true" />
        
        <package name="default" namespace="/" extends="struts-default">
            <default-action-ref name="index"></default-action-ref> //放访问的路径不存在时,会跳转到默认的界面
            <action name="index">
                <result>/default.jsp</result>
            </action>
        </package>
    </struts>

     

    Action总结

    1. 实现一个Action的最常用方式:从ActionSupport继承
    2. DMI动态方法调用   user!add
    3. 通配符配置 * {1} {2} …

        a)         *_*

      4.接收参数的方法(一般用属性或者DomainModel来接收)

      5.简单参数验证addFieldError

        a)         一般不使用Struts2的UI标签

      6.访问Web元素

      a)         Map类型

                             i.              IoC

                           ii.              依赖Struts2

      b)         原始类型

                             i.              IoC

                           ii.              依赖Struts2

      7.包含文件配置

      8.默认action处理

  • 相关阅读:
    python遍历字典元素
    Asp.net网站优化【转】
    三、HTTP协议
    二、 OSI模型的实现TCP 、IP
    一、OSI模型
    JVM原理:4 运行期优化
    JS:jquery插件表格单元格合并.
    28-语言入门-28-1的个数
    27-语言入门-27-成绩转换
    26-语言入门-26-兄弟郊游问题
  • 原文地址:https://www.cnblogs.com/enjoy-life-clh/p/4077567.html
Copyright © 2011-2022 走看看