struts2笔记

来源:互联网 发布:百视通网络电视直播 编辑:程序博客网 时间:2024/06/15 03:33

学习视屏地址https://www.bilibili.com/video/av13748042/index_1.html#page=1

文件配置

  1. 导入9个必备jar到classes
  2. 复制struts.xml到src下
  3. 复制web.xml

    struts.xml下文件解释:
    配置后可以不用重启服务器

    区分重名
    package

—寻址顺序
localhost:8080/web项目 –> struts.xml –> namespace –> action –> result

namespace

决定了action的访问路径, 默认为”“,表示可以接受所有路径的action
namespace可以写成/ 或者 /xxx/yyy 对应的action访问路径为/index.action, /xxx/index.action, 或/xxx/yyy/index.action, namespace最好也用模块来进行命名, namespace如果要自定义,必须要以’/’开头


struts.xml 内容

1.package

1.干什么: 类似于代码包, 区别不同的action, 要配置action,必须要首先写package标签, 在package里面才能配置action
2. name属性: 区分不同package
3. extends属性: 继承struts-default, 才有action的功能
4. namespace属性: 和action中的name属性组合, 默认不写为’/’

2.action

1.name属性: 同action的name值不能相同,和package中的namespace属性组合
2.class属性: action类的全路径
3.method属性:action默认执行action中的excute方法, 使用这个属性后可以指定自定义的方法

result

1.根据action类的方法的返回值, 配置到不同的路里面,
2. name属性: 和action类方法的返回值一样
3. type属性: 配置如何到路径中(转发或重定向) 默认是转发

include (分模块开发)

用来引入package文件


action类3种编写方式

  1. 创建普通类, 不继承任何类, 不实现任何接口, 写上execute()
  2. 实现接口
import com.opensymphony.xwork2.Action;public class MyAction implements Action{    public String execute(){        //return "Hello_struts";         return SUCCESS; //本身就是一个字符串    }}

3.继承类

import com.opensymphony.xwork2.ActionSupport;public class OneAction extends ActionSupport{    @Override    public String execute() throws Exception {        return super.execute();    }}

excute()

返回值 可以是String 还可以是void
若要返回空的String 可以先继承类, 在返回Action.NONE
此方法返回的非空字符串在struts.xml必须要有对应的name,否则会网页报错


访问action类的三种方法

  1. 使用action标签的method属性, 在这个属性里执行action的方法
    *创建一个action类使用自定义的方法, 可以不适用execute(),需要在struts.xml中配置methon
public class OneAction extends ActionSupport{       public String add(){        System.out.println("add..");        return "hello";    }    public String update(){        System.out.println("update..");        return NONE;    }}

*struts.xml, 通过访问localhost:8080/项目名/addAction 就会跳转到Hello.jsp上去

<struts>    <!-- 定义常量, devMode 开发模式, 不用重启tomcat -->    <constant name="struts.devMode" value="true" />    <package name="default" namespace="/" extends="struts-default">        <action name="addAction" class="struts2.OneAction" method="add"><!-- uri根据name来访问 -->            <result name="hello">                Hello.jsp            </result>        </action>        <action name="updateAction" class="struts2.OneAction" method="update"></action>    </package></struts>
  1. 使用通配符方式
    action类同上
    struts.xml, {1}表示填充*号
    <package name="default" namespace="/" extends="struts-default">        <action name="action_*" class="struts2.OneAction" method="{1}">            <result name="hello">Hello.jsp</result>        </action>    </package>

通配符解释
https://www.bilibili.com/video/av13748042/index_6.html#page=17

3. 动态访问(不用)

全局结果页面

创建两个action 类,要求两个action都会调到同一个jsp上可以在struts.xml中这么写(也叫做局部结果页面)

    <package name="default" namespace="/" extends="struts-default">        <action name="one" class="struts2.OneAction">            <result name="success">/success.jsp</result>        </action>        <action name="tow" class="struts2.TowAction">            <result name="success">/success.jsp</result>        </action>    </package> 

由于这么写导致action重复, 这时候就可以用全局结果页面,配置如下,在package下添加global-results标签

    <package name="default" namespace="/" extends="struts-default">        <global-results>            <result name="success">/success.jsp</result>        </global-results>        <action name="one" class="struts2.OneAction"></action>        <action name="tow" class="struts2.TowAction"></action>    </package> 

注意: 当同时存在全局和局部页面时,优先局部

Result标签的type属性

1) 规定如何到指定路径里面(重定向 or 转发)
2) 属性值:
*默认值为转发(dispatcher)
*重定向为(redirect)
*重定向到另一个action(redirect-action) ,如下, 访问towaction则会定向到one在到success.jsp页面

        <action name="one" class="struts2.OneAction">            <result name="success">/success.jsp</result>        </action>        <action name="tow" type="redirect-action" class="struts2.TowAction">            <result name="success">one</result>        </action>

*转发到另一个action (chain)


在action类中获取表单的数据

由于action没有request对象, 不能直接使用request对象,struts提供3种方式来获取:
1.使用ActionContet类获取
2.使用ServletActionContext类获取
3.使用接口注入方式(不做要求)

1.使用ActionContet类获取

                //获取ActionContext对象        ActionContext context = ActionContext.getContext();        //得到表单数据        Map<String, Object> map = context.getParameters();        //key是唯一值        Set<String> keys = map.keySet();        //遍历内容        for (String key : keys){            Object[] obj = (Object[])map.get(key); //得到value            System.out.println(Arrays.toString(obj));        }

2.使用ServletActionContext类获取

        //直接得到request        HttpServletRequest request = ServletActionContext.getRequest();        String username = request.getParameter("username");        String password = request.getParameter("password");        System.out.println(username+password+"ha");

在action中操作3个作用域

1.request域

HttpServletRequest request = ServletActionContext.getRequest();request.setAttribute("req","reqValue");

2.session域

        HttpSession session = request.getSession();        session.setAttribute("sess", "sessValue");

3.ServletContext 域

        ServletContext context = ServletActionContext.getServletContext();        context.setAttribute("context", "contextValue");

将表单数据封装到实体类中

1)原始方式需要new出实体对象通过构造或set()进行封装
2)struts提供的封装:
一. 属性封装
1. 在action类中定义同form表单name相同名称的变量,并生成get,set方法就已经实现了封装

public class Form1Action extends ActionSupport{    String username;    String password;    @Override    public String execute() throws Exception {        System.out.println(username+password);        return NONE;    }    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;    }}

二. 使用模型接口方式 使用ModelDriven接口

public class Form1Action extends ActionSupport implements ModelDriven<User>{    //创建对象, 前提是表单name和实体类的属性相同    User user = new User();    public String execute() throws Exception {        return NONE;    }    @Override    public User getModel() {        return user;    }}

三. 表达式封装
1.在action里声明实体类
2.生成实体类变量的set和get方法
3.在表单输入项的name属性里面写表达式形式
要在表单中写 上对象.属性作为name

username:<input name="user.username" /><br/>password:<input name="user.password"><br>

action类, 需要创建对象,生成对象的get,set

public class Form1Action extends ActionSupport{    //创建对象, 前提是表单name和实体类的属性相同    User user = new User();    public String execute() throws Exception {        System.out.println(user.toString());        return NONE;    }    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }   }

表达式封装和模型封装的区别:

模型封装一个action只能实例化一个类(应为接口的泛型只能指定一个), 表达式封装可以实例化多个类, 只要在action中创建相应类对象并生成get,set方法, 在jsp中使用对象.属性给表单组件name起名即可

封装数据到list集合

1.在action中声明list, 并生成list的get,set方法
2.在表当输入项中写表达式
jsp 中每个list表示一个user对象

    <form action="${pageContext.request.contextPath}/form1" method="post">        username:<input name="list[0].username" /><br/>        password:<input name="list[0].password"><br><br>        username:<input name="list[1].username" /><br/>        password:<input name="list[1].password"><br>        <input type="submit">    </form>

action

public class Form1Action extends ActionSupport{    List<User> list = new ArrayList<User>();    public String execute() throws Exception {        System.out.println(list);        return NONE;    }    public List<User> getList() {        return list;    }    public void setList(List<User> list) {        this.list = list;    }}

封装数据到map集合

1.在action中声明map, 并生成map的get,set方法
2.在表当输入项中写表达式

ognl

在jsp页面引入标签库

<%@ taglib uri="/struts-tags" prefix="s" %>

在jsp页面得到字符串长度:

  <body>    <s:property value="'aaa'.length()"/>  </body>

值栈

什么是值栈

以前把数据防盗域对象中,在页面使用el表达式获取, 在struts2中,值栈类似域对象, 可以存(在action类中存)取(在页面取)值

servlet 和 action的区别

servlet 默认在第一次访问的时候创建,创建一次,单实例对象
action 访问的时候创建,没访问一次都会创建一个新的action,多实例对象, 在每个action对象中都有一个值栈对象

值栈对象

值栈中有两种结构

  1. root(是list集合)
  2. context(是map集合)
    查看两种结构:
    在jsp页面到入struts2标签库,并写代码:

    <%– 使用struts2标签查看值栈结构 –%>


    此时页面就会出现debug超链接, 点击后会显示root和context

向值栈中存数据

1.获取值栈对象, 调用值栈的set方法
ValueStack stack = context.getValueStack(); //得到值栈对象
stack.set(“username”, “xxxx”);

在jsp中获取设置的值  <body>        <s:property value="username"/>  </body>

2.获取值栈对象, 调用值栈的push方法
ValueStack stack = context.getValueStack(); //得到值栈对象
stack.push(“abcde”);

获取push的值,push设置的只有值,没有名称, 当每次push都会把值放入名为top的数组中 ,我们可以从数据中取出(数组写法是struts2规定的 ,不用纠结)  <body>        <s:property value="[0].top"/>  </body>

3.在action定义变量, 生成变量的get方法(一般使用这个方法)

public class Form1Action extends ActionSupport{    String name;    public String getName() {        return name;    }    public Form1Action() {        System.out.println("执行。。。");    }    public String execute() throws Exception {        name = "cdab";        return "hello";    }}

案列:向值栈中存放对象
1. 定义对象,生成get方法
2.在excute中设置对象值
3.访问此action转发的页面的debug连接后, 会看到root中有user对象值

public class Form1Action extends ActionSupport{    User user = new User();    public User getUser() {        return user;    }    public Form1Action() {        System.out.println("执行。。。");    }    public String execute() throws Exception {        user.setUsername("zs");        user.setPassword("1234");        return "hello";         }}

案列:在值栈中存放List对象

public class Form1Action extends ActionSupport{    List<User> list = new ArrayList<User>();    public List<User> getList() {        return list;    }    public Form1Action() {        System.out.println("执行。。。");    }    public String execute() throws Exception {        User user1 = new User();        user1.setUsername("zs");        user1.setPassword("123");        User user2 = new User();        user2.setUsername("zs");        user2.setPassword("123");        list.add(user1);        list.add(user2);        return "hello";    }}

在值栈中获取数据

  1. 获取字符串, 在action类中设置字符串变量, 并生成get()方法
    jsp页面
  <body>    <s:property value="name"/>  </body>

2.获取对象数据

 <body>    <s:property value="user.username"/>    <s:property value="user.password"/>  </body>

3.获取list数据
1)第一种方式 ,比较局限

  <body>    <s:property value="list[0].username"/>    <s:property value="list[0].password"/>  </body>

2)第二种方式, 使用遍历方法,常用

    <s:iterator value="list">        <s:property value="username"/>        <s:property value="password"/>    </s:iterator>

3)第三种方式, 这种类似于for遍历list,u为每个list对象, 必须使用#号开头

  <body>    <s:iterator value="list" var="u">        <s:property value="#u.username"/>        <s:property value="#u.password"/>    </s:iterator>  </body>

用el表示式获取list数据

        <c:forEach items="${list }" var="user">            ${user.username }            ${user.password }        </c:forEach>

el表达式为什么能取到值栈的数据
request对象getAttribute()中获取域对象的值,如果没有 ,则会到值栈中获取值,在把值放进域对象中


“#”号的操作

在action类中向request域中放值

public class Form1Action extends ActionSupport{    public Form1Action() {        System.out.println("执行。。。");    }    public String execute() throws Exception {        HttpServletRequest request = ServletActionContext.getRequest();        request.setAttribute("req","reqvalue");        return "hello";    }}

在jsp页面中使用#获取request域值

  <body>    <s:property value="#request.req"/>  </body>

%使用

使用%{#request.req} 才能取到域对象的值
s:textfield 是struts2封装的一个

<s:textfield name="username" value="%{#request.req}"></s:textfield>
原创粉丝点击