Day43-Struts02

来源:互联网 发布:军犬网络舆情监控系统 编辑:程序博客网 时间:2024/05/17 01:59

一、跳转的页面的分类 – 全局页面和局部页面

  • 局部页面 – 在action的内部声明的
    在action内部自己定义的页面称之为局部页面。 也就是一个action跑自己的页面去。
<!-- 配置action --><struts>      <package name="demo" extends="struts-default" >        <action name="demo_*" class="com.itheima.test.ActionDemo3" method="{1}">                 <result  type="redirect">/other.jsp</result>        </action>      </package></struts>
  • 全局页面
    有点像java里面的全局变量
<!-- 配置action --><struts>      <package name="demo" extends="struts-default">           //这个是全局页面 。 可以让多个action都指向这个地址           <global-results>                 <result name="success"> /other.jsp</result>           </global-results>           <action name="demo_*" class="com.itheima.test.ActionDemo3"                 method="{1}">           </action>      </package></struts>

如果提供了全局页面的result的同时,在action中还有一个同名的result,例如上述例子,在action中还有一个name=”success” 的result,那么就依据就近原则,执行action内部的result进行跳转

全局页面的应用场景:
1)错误页面跳转
2)如果没有登录,避免访问某些页面,跳转到登录页面;


二、结果跳转

跳转的分类:

*      跳转到jsp页面*      跳转到其他Action*      其他跳转,例如跳转到网络资源等等。

1、跳转jsp页面

  • 请求转发跳转 – type=”dispatcher”
    其实不写type , 默认采用的就是请求转发跳转
<result name="success" type="dispatcher">/success02.jsp</result>
  • 重定向跳转 – type=”redirect”
<result name="success" type="redirect">/success02.jsp</result>
  1. 如果要给页面带数据, 一般都是用请求转发去跳转。 因为重定向无法带数据过去。
  2. 请求转发会在地址栏上显示请求的地址 ,第一次请求的地址。

2、跳转Action

跳转action没有什么默认的说法, 如果不写type 默认就是dispatcher , 但是这个dispatcher只能跳转页面,不能跳转action,它会把后面给的地址看成是一个页面,从而产生错误

  • 请求转发跳转action
<result name="success" type="chain">actionDemo02_add02</result>
  • 重定向跳转
<result name="success" type="redirectAction">actionDemo02_add02</result>
 注意:

1)跳转的result后面的action的名字不能包含package的名字,只能够写真正的action的名字,如果package加了namespace当然要加上,不然就只写写action的名字。因为package只是拿来区分的,并不需要在跳转的时候加上包名

2)跳转Action一般采用什么跳转。
一般采用重定向跳转redirectAction。 因为重定向跳转,会抛弃掉第一个action的执行结果以及它的执行参数。如果使用请求转发跳转,会把第一个action的参数以及结果都带到第二个Action上,有可能影响第二个action的执行结果。

3)如果一个action方法里面有返回值,但是没有配置result的话,那跳转的时候就要报错
以后如果哪一个方法不想跳转结果,建议采用返回none常量这种方式,而不适用void的写法。

public class ActionDemo3 extends ActionSupport {      public String add(){           System.out.println("add方法执行了~~~~");           return NONE;      }}

4)如果要跳转action,一定要写type,如果不写的话默认是type=’dispatcher’,但是dispatcher是跳转页面的,不能够跳转action,他会把后面写的地址看成是页面,完成跳转失败
注意:跳转action的时候不能够写/开头

其他跳转:
Stream Result,可以看看Struts给的文档的index.xml中的说明
JSON Result

以json为例子:
1)导入jar包:struts2-json-plugin-2.3.32.jar
2)编写类:
list需要为全局变量
需要提供一个get方法

public class JsonTest extends ActionSupport {      List<User> list ;      public List<User> getList(){           return list;      }      public String test(){           list = new ArrayList<User>();           System.out.println("执行到这里了,日志");           for(int i=1;i<6;i++){                 User user = new User();                 user.setId(i);                 user.setUsername("张三"+i);                 list.add(user);           }           return "success";      }}

3)配置struts.xml

<struts>      <package name="json" extends="json-default">           <action name="json_*" class="com.itheima.test.JsonTest"                 method="{1}">                 <result name="success" type="json">                      <param name="root">list</param>                 </result>           </action>      </package></struts>

三、获取表单数据

1. 获取零散数据

 所谓的获取零散数据,就是我们得到页面的数据之后,还得手动封装成一个实体对象
  • 使用ActionContext类获取
    翻译过来是Action的上下文,通过它可以获取到有关Action的信息
    ActionContext:就是包含了action的一切信息,都在这个对象的身上;
    actionContexct只提供了拿getParameters提取这个map的方法
    缺点:这个ActionContext无法获取单个参数
      public void test01(){           ActionContext context = ActionContext.getContext();           Map<String, Object> map = context.getParameters();           System.out.println(map);           for (String key : map.keySet()) {                 System.out.println(key+":"+Arrays.toString((String[])map.get(key)));           }      }
  • 使用ServletActionContext获取
    该类是ActionContext的子类,所以功能上应该稍微有扩展。 该类不仅可以获取数据,它还提供了获取response对象 、 request对象、servletContext对象当然它也能得到它父类对ActionContext
    其实这个类本质上就是让我们回到了原来的servlet的处理方式处理页面传递的数据
      public void test01(){           HttpServletRequest request = ServletActionContext.getRequest();           String username = request.getParameter("username");           String password = request.getParameter("password");           System.out.println("username:"+username);           System.out.println("password:"+password);      }
  • 使用实现接口方式获取
    这种方式其实和第二种方式一样。唯一的不同只是这种方式获取request对象是采用实现接口的方式获取。 大家获取参数的手法都是通过request获取的。
public class GetParameters extends ActionSupport implements ServletRequestAware{      HttpServletRequest request;      @Override      public void setServletRequest(HttpServletRequest request) {           this.request = request;      }      public String test01() {           String username = request.getParameter("username");           String password = request.getParameter("password");           System.out.println("username:"+username);           System.out.println("password:"+password);           return NONE;      }}

2. 封装表单数据成对象

  • 属性封装
    只要在action上声明全局变量,并且提供set方法, struts会自动对这些变量进行赋值。但是有一个要求: 这个全局变量的名字必须和 页面的标签 name属性值 一致。
    action :
            public class ActionDemo extends ActionSupport {                private String username;                private String password;                //1. 声明全局变量                //2. 提供set方法 --struts框架会调用set方法对我们的全局变量进行赋值。                public void setUsername(String username) {                    this.username = username;                }                public void setPassword(String password) {                    this.password = password;                }            }

以上方式可以拿到页面交过来的数据,但是还只是零散的数据,并没有封装成对象。而且还要考虑一个隐患,如果页面提交过来的数据太多,我们还需要写很多的set方法,并且最后还要自己封装成实体对象。

Action : 
        //属性封装,直接封装成实体        public class ActionDemo02 extends ActionSupport {            private User user ;            //set方法的本意是: 赋值对象。 注意:现在这个user并没有new出来对象 。            // 1. 先new一个user对象 调用setUser方法,让我们的这个user指向了曾经new出来的对象            public void setUser(User user) {                this.user = user;            }            //因为要赋值的话,需要得到这个user对象,然后调用user.setXXX()            public User getUser() {                return user;            }        }

页面:

       用户名:<input type="text" name="user.username"><br>        密码:<input type="password" name="user.password"><br>

  • 模型驱动封装【重点掌握】

    1. 让Action实现接口ModelDriven

    2. 实现方法 getModel ,并在里面返回要封装的对象。

        public class ActionDemo extends ActionSupport implements ModelDriven<User>{            private User user  ;            public String add() {                System.out.println("user2222==="+user);                return NONE;            }            @Override            public User getModel() {                //一定要在返回user对象之前 new出来user                if(user == null){                    user = new User();                }                return user;            }        }

这个模型驱动是怎么封装数据的。 — 是通过拦截器封装的。


  • 封装集合数据 – 比较类似于属性封装的封装成为实体
    一般这种情况只有在批量操作的时候才会出现,比如:批量添加用户

    Action :

        private List<User> list;        public void setList(List<User> list) {            this.list = list;        }        public List<User> getList() {            return list;        }
页面: 
        用户名:<input type="text" name="list[0].username"><br>        密码:<input type="password" name="list[0].password"><br>        <br>-------------------------------<br>        用户名:<input type="text" name="list[1].username"><br>        密码:<input type="password" name="list[1].password"><br>    ---------------------------------------------------------------------    下面是Map集合            private Map<String , User> map ;            public void setMap(Map<String, User> map) {                this.map = map;            }            public Map<String, User> getMap() {                return map;            }页面        用户名:<input type="text" name="map['aa'].username"><br>        密码:<input type="password" name="map['aa'].password"><br>        <br>-------------------------------<br>        用户名:<input type="text" name="map['bb'].username"><br>        密码:<input type="password" name="map['bb'].password"><br>

原创粉丝点击