Struts2框架

1. 环境搭建

struts2是web层的框架,需要创建web工程。

1.1 导入jar包

导入struts的核心jar包,书写在项目的pom.xml文件中,内容如下:

<!--struts2 -->
<dependency>
	<groupId>org.apache.struts</groupId>
	<artifactId>struts2-core</artifactId>
	<version>2.5.13</version>
</dependency>

1.2 书写web.xml文件

struts2框架的入口核心过滤器,书写在项目的WEB-INF下到的web.xml文件中,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">

  <!-- struts2的入口、核心过滤器 -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

:其中<url-pattern>/*</url-pattern>表示拦截所有请求。

1.3 配置文件(struts.xml)

1) 创建struts.xml文件

struts2框架的核心配置文件,书写在项目的resource下struts.xml文件中,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
</struts>

1. 只是一个公共头,需要书写相应的请求处理类再添加配置。

2.文件名只能为struts.xml

2) 书写请求处理类

Action接口,内容如下:

package com.opensymphony.xwork2;

public interface Action {
    String SUCCESS = "success";
    String NONE = "none";
    String ERROR = "error";
    String INPUT = "input";
    String LOGIN = "login";

    String execute() throws Exception;
}

SUCCESS  --》 请求成功
NONE         --》 请求资源找不到
ERROR       --》 异常
INPUT         --》 输入有错
LOGIN        --》  登录出错

请求处理类,通常约定叫Action,Action是一个接口我们可以通过实现该接口并实现该接口的方法,自定义请求处理类。

我们可以创建一个action包将创建的请求处理类都统一放到该包中。

例如: helloAction1请求处理类

package com.sunfeng.action;

import com.opensymphony.xwork2.Action;

public class HelloAction1 implements Action {
    @Override
    public String execute() throws Exception {
        System.out.println("hello struts2");
        return SUCCESS;
    }
}

请求怎么进入到处理类中的?需要在struts.xml配置文件中配置对应关系。

3)配置请求与处理类的连接

<struts>
    <package name="default" extends="struts-default">
        <action name="hello" class="com.sunfeng.action.HelloAction">
            <result name="success">hello1.jsp</result>
        </action>
    </package>
</struts>

作用:通过action标签将请求与处理请求的类绑定在一起。

属性解析:

package标签

        name属性类似于命名空间可以自己随意命名。

        extends属性是继承struts默认的处理请求参数的工具包(封装的有过滤器)。

action标签

        name属性请求路径的地址(例: http://localhost:8080/hello)

        class属性处理类的全限定名称

result标签

        name属性是处理类返回的结果,标签内是对应的跳转界面。

4) 创建index.jsp文件

在webapp目录下创建一个index.jsp文件。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello1</title>
</head>
<body>
    <h1>Hello Struts2</h1>
</body>
</html>

2. 参数映射

2.1 基本参数类型的映射

1) 书写请求处理类

HelloAction2类中创建两个变量name与message,并书写对应的get,set方法。

作用: 用于接收参数,同时向页面返回数据。

set方法:会自动将前端对应的参数值设置到对应的属性中。

get方法:会自动将后端属性的值返回到前端。

package com.sunfeng.action;

import com.opensymphony.xwork2.Action;

public class HelloAction2 implements Action {
    // 创建两个变量,并书写对应的get,set方法
    private String name;
    private String message;
    @Override
    public String execute() throws Exception {
        System.out.println("接收到的name为:"+name);
        System.out.println("接收到的message为:"+message);
        message = "helloAction2";
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2)书写配置文件对应关系

<struts>
    <package name="default" extends="struts-default">
        ...
        <action name="hello2" class="com.sunfeng.action.HelloAction2">
            <result name="success">hello2.jsp</result>
        </action>
    </package>
</struts>

3)书写前端界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello2</title>
</head>
<body>
    <h1>Struts2</h1>
    <!-- 向后端发送数据 -->
    <form name="hello" method="post">
        <input name="name">
        <input type="submit" value="提交">
    </form>
    <!-- 获取后端返回数据 -->
    <p>${requestScope.message}</p>
</body>
</html>

4)测试

a)启动后前端界面

b)输入hello,提交后的后端输出

 

2.2 对象的映射

1)创建User对象(属性id,username)(get,set方法)(toString方法)

package com.sunfeng.pojo;

public class User {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                '}';
    }
}

2)将User对象作为属性书写在请求处理类HelloAction3中

package com.sunfeng.action;

import com.opensymphony.xwork2.Action;
import com.sunfeng.pojo.User;

public class HelloAction3 implements Action {
    private User user;
    @Override
    public String execute() throws Exception {
        System.out.println("对象user的信息为:"+ user);
        if (user!=null){
            System.out.println("接收到的用户ID为:"+ user.getId());
            System.out.println("接收到的用户名为:"+ user.getUsername());
        }
        return SUCCESS;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

3)书写配置文件对应关系

<struts>
    <package name="default" extends="struts-default">
        ...
        <action name="hello3" class="com.sunfeng.action.HelloAction3">
            <result name="success">hello3.jsp</result>
        </action>
    </package>
</struts>

4)书写前端界面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello3</title>
</head>
<body>
    <h1>Struts2</h1>
    <!-- 向后端发送数据 -->
    <form name="hello" method="post">
        id:<input name="user.id">
        username:<input name="user.username">
        <input type="submit" value="提交">
    </form>
</body>
</html>

3. struts.xml文件详解

3.1 constant标签

constant标签

功能: 用来配置常量,name属性是常量名,value属性是常量值。

作用: 可以改变Struts2的一些行为,比如UI标签的样式、编码格式等。

因为struts2默认的编码格式就是UTF-8,所以不用特意指定编码,中文也不会乱码。

<struts>
    <!-- 设置请求后缀 -->
    <constant name="struts.action.extension" value="do,html"></constant>
    <!-- 设置编码,解决中文乱码 -->
    <constant name="struts.i18n.encoding" value="utf-8"></constant>
    <!-- 设置struts标签主题 -->
    <constant name="struts.ui.theme" value="simple"></constant>
    ...
</struts>

注:请求后缀,指的是在请求路径的后边加的后缀(struts2默认的后缀是.action

例如: http://localhost:8080/hello请求路径,可以使用 http://localhost:8080/hello.action访问。

自定义后缀:如果我们定义了后缀,那么默认的后缀就会失效,并且页面请求路径后必须携带自定义的后缀才能访问。

默认后缀:带不带后缀页面都可以访问路径。

3.2 package标签

<struts>
    <package name="default" namespace="/" extends="struts-default">
        ...
    </package>
</struts>

Struts2的package与java中的package类似,可以把同一个业务模块的action和result集中到一个包中,方便管理。不同的是Struts2的包可以继承。比如商品有增删改查操作,订单也有增删该查操作,我们可以将商品和订单的action分别放两个package中方便管理。
name属性是包的名字,一个struts.xml中可以有很多个package,通过name属性进行区分。
namespace是命名空间,/代表的是根目录。namespace的作用类似于SpringMVC中在Controller类上加@RequestMapping注解。相当于此包中所有的action前都加一个父路径。如:

<struts>
    <package name="default" namespace="/user" extends="struts-default">
        ...
    </package>
</struts>

上面这个name=login的action,在访问的时候路径就是/user/hello,注意添加了命名空间,跳转的前端界面就要使用绝对路径从webapp(/)开始。

extends属性是继承,通常都会继承struts-default,在struts-default中定义了大量的struts特性,如拦截器和参数处理的功能,如果不继承struts-default,会遇到参数无法绑定或找不到action类。

3.3 action标签

<struts>
    <package name="default" extends="struts-default" namespace="/user">
        ...
        <action name="login" class="com.sunfeng.action.LoginAction">
            <result name="success">index.jsp</result>
            <result name="error">error.jsp</result>
            <result name="input">login.jsp</result>
        </action>
    </package>
</struts>

action标签用来处理请求和响应结果。
name属性是请求的名字,此处不需要加action。同一个package下的action不能重名。

class属性指定处理该请求的类,是类的全路径,默认的处理请求时会去类中找名为exeute的方法。如果不指定class,将默认ActionSupport为处理请求的类

result标签用来处理请求结果,name属性是Action类中返回的字符串。标签的值是要跳转的页面地址,name如果不写的话,默认是success。

4. Action类的配置

4.1 ActionSupport类

该类不仅实现了Action接口,还实现了如下图所示接口(数据校验,国际化),并提供了一些扩展方法,我们可以通过继承该类实现请求处理类。

ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {

4.2 自定义业务方法

在前面的学习中,Action类中只有一个exeute()方法,可不可以在一个Action类中定义多个业务方法呢? 答案是肯定的。
例如:用户有注册和登录两个功能,我们可以把这两个功能写进同一个Action类:

a)书写UserAction

package com.sunfeng.action;

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport {
    private String username;
    private String password;
    public String login(){
        System.out.println("login success");
        System.out.println("用户名:"+ username);
        System.out.println("密码:"+ password);
        return SUCCESS;
    }

    public String register(){
        System.out.println("register success");
        System.out.println("用户名:"+ username);
        System.out.println("密码:"+ password);
        return SUCCESS;
    }

    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;
    }
}

注: 

1. 继承ActionSupport可以书写自己的方法。

2. 自己书写的方法必须是public修饰,并且方法的返回值只能是String类型。

b)配置文件

怎么调用自己书写的方法?在配置文件的action标签中添加一个method属性。

<struts>
    <package name="default" extends="struts-default" namespace="/user">
        ...
        <action name="login" class="com.sunfeng.action.UserAction" method="login">
            <result name="success">/login.jsp</result>
        </action>
        <action name="register" class="com.sunfeng.action.UserAction" method="register">
            <result name="success">/register.jsp</result>
        </action>
    </package>
</struts>

method="login"表示要调用类中的login方法处理请求。如果找不到login()方法,Struts2会在类中查找doLogin()方法。如果都找不到,将报错。

注意:package有命名空间,跳转的前端界面前面要添加/

c)书写前端页面

login.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
    <h1>Struts2</h1>
    <!-- 向后端发送数据 -->
    <form name="login" method="post">
        用户名: <input name="username"><br>
        密&nbsp;&nbsp;码: <input name="password" type="password"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

register.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>register</title>
</head>
<body>
    <h1>Struts2</h1>
    <!-- 向后端发送数据 -->
    <form name="register" method="post">
        用户名: <input name="username"><br>
        密码: <input name="password" type="password"><br>
        <input type="submit" value="注册">
    </form>
</body>
</html>

d)测试

启动程序:

1) 访问http://localhost:8080/struts/user/login.do路径进入登录界面:

 填写信息登录,查看后端输出:

2) 访问http://localhost:8080/struts/user/register.do路径进入注册界面:

填写信息提交,查看后端输出:

4.2 动态方法调用

注:Struts2支持动态方法调用,但是不建议使用。仅做考点学习如果一个类中有多个业务方法,又不想给每个业务方法都配置一个action标签,可以使用动态方法调用。

语法:请求名!方法名.后缀

例:
当请求的格式是user!login.action时,代表调用UserAction中的login()方法处理当前请求。

当请求的格式是user!register.action时,代表调用UserAction中的register()方法处理当前请求。

缺点: 路径中有!和方法名,不安全。

a)开启动态调用

<struts>
    ...
    <!--允许调用动态方法-->
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>

    <package ...>...</package>
</struts>

b)添加允许调用的方法

<struts>
    ...
    <package name="default" extends="struts-default" namespace="/user">
        <!--允许动态调用的方法,新版里新增的设置,必须在所有action之前-->
        <global-allowed-methods>login,register</global-allowed-methods>
        
        <action ...> ... </action>
    </package>
</struts>

c)合并action

<struts>
    ...
    <package name="default" extends="struts-default" namespace="/user">
        <!-- name属性:设置统一的前缀,以user开口的请求都走这里 -->
        <action name="user" class="com.sunfeng.action.UserAction">
            <result name="success">/index.jsp</result><!--成功去首页-->
            <result name="error">/error.jsp</result><!--失败去错误-->
        </action>
    </package>
</struts>

d)修改前端页面内容

修改前端页面的form表单的action属性指向的方法

<!-- 登录界面修改 -->
<form name="login" method="post" action="user/user!login.do">

<!-- 注册界面修改 -->
<form name="register" method="post" action="user/user!register.do">

e)测试

1)访问http://localhost:8080/struts/user/user!login.do路径,直接跳转到index.jsp页面。

2)访问http://localhost:8080/struts/login.jsp路径,进入登录页面,输入登录,查看后端输出:

       

4.3 使用通配符

使用方法与上面一致,都需要先开启动态调用,再添加调用方法。

另一种减少action数量的方法是使用通配符:

<action name="*User" class="com.sunfeng.action.UserAction" method="{1}">
    <result name="success">/index.jsp</result>
    <result name="error">{1}.isp</result><!--失败了就返回原来的页面-->
</action>

User匹配所有以User结尾的请求,method="{1}"中的{1}的就是User前的*。

如果请求的地址是loginUser.action,那么{1}匹配的就是login,就会去类中调用login()方法,并返回相应的结果。

访问方法,例:http://localhost:8080/struts/user/loginUser.do路径

4.4 默认Action

如果在struts.xml中找不到匹配的action,将会报错。可以设置一个默认的action。当所有请求都不匹配时,将匹配默认action。

<!-- 需要放在<global-allowed-methods>标签前面 -->
<default-action-ref name="default"/>
...
<action name="default">
    <result>/error.jsp</result>
</action>

<default-action-ref>对当前的package有效
action标签的class省略将调用ActionSupport类。result的name省略将默认为success。注意default-action-ref必须在所有的action标签上面。也就是说default-action-ref出现在action标签之前,不然不符合DTD验证。

5. Result配置

常用结果有三种类型: dispatcher,redirect,redirectAction,chain

5.1 dispatcher

result默认的类型,一下两个标签是等价的:

<result name="success” type="dispatcher">index.jsp</result>

<result name="success">index.jsp</result>

dispatcher的结果等同于Servlet中的请求转发,

即:request.getRequestDispatcher("success.jsp").forward(request, response);

请求转发的意思:当前请求中的参数、属性在下一个页面或请求中仍然可以使用

5.2 redirect

redirect是重定向,重定向之后,当前请求中的参数和属性在下一个页面或请求中将不能使用

<result name="success" type="redirect">index.jsp</result>

相当于Servlet中的: response.sendRedirect("success.jsp");

5.3 redirectAction

redirectAction与redirect类似,不过redirectAction是重定向到某一个action

<action name="reg"class="action.UserAction" method="regist">
    <result name="success" type="redirectAction">login.action</result>
    <result name="error">regist.jsp</result>
</action>

如果要调用不同package下的action,需要在result中传参数:

<action name="login" class="com.sunfeng.action.UserAction" method="login">
    <result name="success" type="redirectAction">
        <!--调用不同package下的action-->
        <param name="namespace">/</param>
        <param name="actionName">hello.action</param>
        <!--传递其它参数-->
        <param name="username">123</param>
    </result>
    <result name="error">login.jsp</result>
</action>

5.4 chain

redirectAction不能共享request中的数据,如果想共享数据,可以将type设置为chain。

<action name="reg" class="com.sunfeng.action.UserAction" method="register">
    <!--注意chain的action后面没有后缀-->
    <result name="success" type="chain">login</result>
    <result name="error">register.jsp</result>
</action>

5.5 动态结果

private String username;
private String page;
//getter/setter方法略
public string login() {
    //参数和业务略
    System.out.print]n("我是登录");
    if ("admin".equals(username)) {//管理员去管理页
        page = "admin_page";
    } else {//其他人去用户页
        page = "user_page";
    }
    return SUCCESS;
}

result配置

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值