struts2笔记

学习视屏地址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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值