Day43-Struts02

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

  • 局部页面 – 在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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值