Struts2 学习笔记 (二)

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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • 目录 1. 什么是Struts2 2. Struts2下载 3. Struts2的目录结构 4. Struts2中...
    深海鱼Q阅读 976评论 0 16
  • 概述 Struts就是基于mvc模式的框架!(struts其实也是servlet封装,提高开发效率!) Strut...
    奋斗的老王阅读 2,931评论 0 51
  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,249评论 0 50
  • 本文包括: 1、Struts 2 概述2、Struts 2 快速入门3、Struts 2 的执行流程4、配置 st...
    廖少少阅读 2,950评论 3 13
  • 一节晚自修 她从水房接水回来,莫名觉得教室里气氛与先前有些不同。像是受到不自觉的吸引,她的目光找到了原因。斜前方新...
    静心即可阅读 317评论 4 3