Struts2 学习笔记 (二)

作者: HikariCP | 来源:发表于2017-11-06 01:56 被阅读8次

GitHub 地址

访问GitHub下载最新源码:https://github.com/JYG0723/Struts2_Action

访问 Servlet Api


Struts2 不再与 Servlet Api 进行耦合,但任提供了三种方式去访问 Servlet Api

  • ActionContext :上下文的类,通过它获取相关的对象。Map 方式
  • Aware :实现 Aware 接口。
  • ServletActionContex:与 ActionContext 类似。

Action 的搜索顺序


  • url:http://127.0.0.1:8080/struts2/path1/path2/student.action
  • 首先根据 url 路径判断namespace/path1/path2的 package 是否存在。
    • 存在:判断 action 是否存在,如果不存在则去默认namespace的 package 里寻找。及namespace/的 package 下。如果还不存在则报错。
    • 不存在:检查上一级路径的 package 是否存在(直到默认 namespace),即 namespacepath1的 package。如果没有报错。

动态方法调用


动态方法调用为了解决一个 Action 对应多个请求的处理。以免 Action 太多,Struts2 对其有三种实现方式:

  • 指定method属性。容易出现太多 xml文件中出现太多 action,不推荐
  • 感叹号方式。官方不推荐,这里不写例子了。(请求写的和屎一样)
    • 需要配置常量。并且配置 package 标签的strict-method-invocation="false"
  • 通配符方式,相比较而言推荐
    • 需要配置 package 标签的strict-method-invocation="false"

指定method属性

struts.xml
<package name="default" namespace="/" extends="struts-default">
    <action name="helloworld" class="action.HelloWorldAction">
        <!-- action 的 method 属性默认 execute -->
        <!-- result 的 name 属性默认 success -->
        <result>/result.jsp</result>
    </action>

    <action name="add" class="action.HelloWorldAction" method="add">
        <!-- result 的 name 属性默认 success -->
        <result>/add.jsp</result>
    </action>
</package>
HelloWorldAction
public class HelloWorldAction extends ActionSupport {

    public String add() {
        return SUCCESS;
    }

    @Override
    public String execute() throws Exception {
        System.out.println("执行Action");
        return SUCCESS; //  = "success"
    }
}

url:http://localhost:8080/struts2/add.action

通配符方式

struts.xml
<package name="default" namespace="/" extends="struts-default" strict-method-invocation="false">
    <action name="helloworld_*" method="{1}" class="action.HelloWorldAction">
        <!-- 默认 success -->
        <result>/result.jsp</result>
        <result name="add">/{1}.jsp</result>
        <result name="update">{1}.jsp</result>
    </action>
</package>
HelloWorldAction
public class HelloWorldAction extends ActionSupport {
  
    public String add() {
        return "add";
    }

    public String update() {
        return "update";
    }
        
    @Override
    public String execute() throws Exception {
        System.out.println("执行Action");
        return SUCCESS; //  = "success"
    }
}

url:http://localhost:8080/struts2/helloworld_update.action

多配置文件


helloworld.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>
    <package name="default" namespace="/" extends="struts-default" strict-method-invocation="false">
        <action name="helloworld_*" method="{1}" class="action.HelloWorldAction">
            <!-- 默认 success -->
            <result>/result.jsp</result>
            <result name="add">/{1}.jsp</result>
            <result name="update">/{1}.jsp</result>
        </action>
        <!--
                <action name="add" class="action.HelloWorldAction" method="add">
                    <result>/add.jsp</result>
                </action>
        -->
    </package>
</struts>

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>

    <include file="helloworld.xml"></include>

</struts>

默认 Action


默认 Action,即如果用户输入的路径有误,找不到对应的 Action,就可以用该 Action 来向用户展示默认页面。防止出现 404 影响用户体验。

<package name="default" namespace="/" extends="struts-default" strict-method-invocation="false">

    <default-action-ref name="index"></default-action-ref>
    
    <action name="index">
        <!-- 默认 success -->
        <result>/error.jsp</result>
    </action>
</package>

url:http://localhost:8080/struts2/***.action

Struts2 后缀


struts.xml

<struts>

    <include file="helloworld.xml"></include>

    <constant name="struts.action.extension" value="html"></constant>
    
</struts>

url:http://localhost:8080/struts2/helloworld_add.html

<struts>

    <include file="helloworld.xml"></include>
    
</struts>

url:http://localhost:8080/struts2/helloworld_add

注意:

比较有趣的一点是。默认 Struts2 访问 Action 不加.action后缀也是可以根据名称访问到对应 Action 的。但是如果配置了该struts.action.extension常量,并且 value 设值了,那么不添加后缀是访问不到的。如果该 value 没有设值,那么任然可以继续不带尾缀访问对应 Action。

struts.propertis

### 指定后缀为 .action 形式的请求可被 Struts2 处理,默认为action。可配置多个请求后缀,用 , 隔开
struts.action.extension=action,do,struts2,

web.xml

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
        <param-name>struts.action.extension</param-name>
        <param-value>do</param-value>
    </init-param>
</filter>

接受参数


Struts2 的 Action 是如何接收参数的:

  • 使用 Action 的属性接收参数
  • 使用 DomainModel 接受参数
  • 使用 ModelDriven 接受参数

Action 的属性接收

LoginAction
public class LoginAction extends ActionSupport {

    private String username;
    private String password;

    public String login() {
        System.out.println(username + ":" + password);
        return SUCCESS;
    }
    
    // getter/setter
}    
struts.xml
<action name="LoginAction" method="login" class="action.LoginAction">
    <!-- 默认 success -->
    <result>/success.jsp</result>
</action>
login.jsp
<form action="LoginAction.action" method="post">
    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
</form>

DomainModel 接受

LoginAction
public class LoginAction extends ActionSupport {

    private User user;

    public String login() {
        System.out.println(user.getUsername()+ ":" + user.getPassword());
        return SUCCESS;
    }
  
    public User getUser() {
        return user;
    }

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

    private String username;
    private String password;
    
    getter/setter
}
login.jsp
<form action="LoginAction.action" method="post">
    用户名: <input type="text" name="user.username">
    密码: <input type="password" name="user.password">
        <input type="submit" value="提交">
</form>

ModelDriven 方式接收

LoginAction
public class LoginAction extends ActionSupport implements ModelDriven<User>{

    private User user = new User();

    public String login() {
        System.out.println(user.getUsername()+ ":" + user.getPassword());
        return SUCCESS;
    }

    @Override
    public User getModel() {
        return user;
    }
}
login.jsp
<form action="LoginAction.action" method="post">
    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
    <input type="submit" value="提交">
</form>

复杂参数请求

User
public class User {

    private String username;
    private String password;
    private List<User> userList;
 
    // getter/setter
}
login.jsp
<form action="LoginAction.action" method="post">
    用户名: <input type="text" name="username">
    密码: <input type="password" name="password">
    用户名1:<input type="text" name="userList[0].username">
    用户名2:<input type="text" name="userList[1].username">
    用户名3:<input type="text" name="userList[2].username">
    <input type="submit" value="提交">
</form>
LoginAction
public class LoginAction extends ActionSupport implements ModelDriven<User> {

    private User user = new User();

    public String login() {
        System.out.println(user.getUsername() + ":" + user.getPassword() + ": 用户名1:"
                + user.getUserList().get(0).getUsername() + ": 用户名2:"
                + user.getUserList().get(1).getUsername());
        return SUCCESS;
    }

    @Override
    public User getModel() {
        return user;
    }
}

处理结果类型


LoginAction

public class LoginAction extends ActionSupport{
  
    ···
}

ActionSupport

public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
  
    ···
}

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:Action 正确的执行完成。返回相应的视图,success 是 name 属性默认值
  • NONE:表示 Action 正确的执行完成,但并不返回任何视图
  • ERROR:表示 Action 执行失败,返回到错误处理视图
  • LOGIN:Action 因为用户没有登录的原因没有正确执行,将返回该登录视图,要求用户进行登录验证
  • INPUT :Action 的执行,需要从前段页面获取参数,INPUT 就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果验证没有通过,将自动返回到该视图。

INPUT 用法示例

struts.xml
<action name="LoginAction" method="login" class="action.LoginAction">
    <!-- 默认 success -->
    <result>/success.jsp</result>
    <result name="input">/login.jsp</result>
</action>
login.jsp
<%@ taglib prefix="s" uri="/struts-tags" %>>

···

<form action="LoginAction.action" method="post">
    用户名: <input type="text" name="username"><s:fielderror name="username"></s:fielderror>
    密码: <input type="password" name="password">
    用户名1:<input type="text" name="userList[0].username">
    用户名2:<input type="text" name="userList[1].username">
    年龄:<input type="text" name="age">
    <input type="submit" value="提交">
</form>
LoginAction
public class LoginAction extends ActionSupport implements ModelDriven<User> {
  
    ···
      
    @Override
    public void validate() {
        if (user.getUsername() == null || "".equals(user.getUsername())) {
            this.addFieldError("username", "用户名不能为空");
        }
    }
}

注意:

这里的addFieldError方法的username参数对应 jsp 页面<S:>标签的 name 属性。

result 标签

<result name = "" type = ""> </result> 这里的 type 属性默认是 dispatcher 即转发。页面是通过请求转发调度过去,支持 jsp 引擎。

<result-types>
    <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
    <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/>
    <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
    <result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/>
    <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>
    <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>
    <result-type name="stream" class="org.apache.struts2.result.StreamResult"/>
    <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/>
    <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
    <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" />
    <result-type name="postback" class="org.apache.struts2.result.PostbackResult" />
</result-types>

相关文章

  • structs2

    一、学习方法:做好笔记。Struts2内容比较多,比较杂。多做实验,证明结论。二、Servlet PK Filte...

  • Struts2学习笔记(核心组件详解)

    [toc] Struts2学习笔记(核心组件详解) @(_1每日记录) 返回到JQuery学习笔记@达内lang笔...

  • Struts2 学习笔记 (二)

    GitHub 地址 访问GitHub下载最新源码:https://github.com/JYG0723/Strut...

  • Struts2学习笔记(二)

    一、ServletAPI 获取方式 第一种:通过ServletActionContext获取 【推荐使用】 第二种...

  • Struts2学习笔记 | 值栈和OGNL

    1.值栈(ValueStack) 引入值栈 在部署第一个Struts2时,Struts2学习笔记 | 部署第一个S...

  • Struts2笔记

    Struts2笔记——Struts2的模型驱动(ModelDriven) 1. 模型驱动: 模型驱动是使用...

  • Struts2学习笔记

    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,St...

  • Struts2学习笔记

    struts2框架简介; 运行原理: Servlet Filters、Struts核心模块、拦截器、用户实现部分 ...

  • Struts2学习笔记

    一. Struts2开发步骤: 1. 引入struts的jar包。 commons-fileupload-1.2....

  • structs2相关

    Struts2第一天 Struts2的学习路线 今天的课程内容 案例一:使用Struts2框架完成登录功能 需求分...

网友评论

    本文标题:Struts2 学习笔记 (二)

    本文链接:https://www.haomeiwen.com/subject/ysjkmxtx.html