一、Action与MVC
struts2是一个基于MVC的web应用框架,它将应用程序分为三个组件:模型,视图,控制器。
模型:包含了应用程序的业务逻辑和业务数据,由封装数据和处理业务的javaBean组成。
视图:封装了应用程序的输出形式,也就是页面,如jsp,html。
控制器:负责接收用户的http请求,再调用模型中响应的方法来处理业务,然后调用响应的视图作为显示。
三者共同协同处理响应客户端的请求。

在struts2中控制器分为两部分:
1.核心控制器:它就是在web.xml中配置的StrutsPrepareAndExecuteFilter负责过滤用户的所有请求,根据请求不同,分发不同的Action处理。
2.业务控制器:也就是Action,负责调用模型来实现请求的业务,并把结果交给视图层。

二、Action接收参数
在action中接收用户从jsp传入的参数有三种方式:
1.属性方式
2.JavaBean方式
3.ModelDriven方式

1.属性方式:

在action 里面定义要接收的参数,并提供相应的setter,getter方法。注:Action中定义的属性需和提交参数的名称一致。

在Action类中定义与请求参数同名的属性,struts2便能自动接收请求参数并赋予给同名的属性。

<form action="testAction!login" method="post">
用户名:&nbsp;<input type="text" name="username"/><br/>
密码:&nbsp;<input type="password" name="password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>
package com.lxx.action;
import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport { private String username;
private String password; 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;
} public String execute() {
return "index";
} public String login(){
System.out.println("用户名:"+username + "-----------------"+"密码:"+password);
return "index";
}
}

说明:
(1)在form表单中的用户名和密码的<input>标签中的name属性username和password,和action中的定义的成员变量username和password相同,在提交表单时struts会把值赋为名字相同的字段名。
(2)如果参数包含中文,则action接收可能存在乱码,可以修改struts.xml文件,添加<constant name="struts.i18n.encoding" value="utf-8">

2.JavaBean的方式

(1)、定义User对象实体类,并添加username,password和相应的get,set方法

package com.lxx.model;

public class User {
private String username;
private String password; 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;
} }

(2)、添加JavaBean的action,添加User类型的成员变量user和get,set方法。

package com.lxx.action;
import com.lxx.model.User;
import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport { private User user;
  //错误的写法,不能自己实例化,struts会自动实例化
  //private User user = new User();   public User getUser() {
return user;
} public void setUser(User user) {
this.user = user;
} public String execute() {
return "index";
} public String login(){
System.out.println("用户名:"+user.getUsername() + "-----------------"+"密码:"+user.getPassword());
return "index";
}
}

获取Bean属性的原理:
Struts2首先通过反射技术调用User的默认构造器创建user的实例,然后再通过反射技术调用user中与请求参数同名的属性的setter方法,来获取请求参数数值。

(3)、form表单中添加页面代码:

<form action="testAction!login" method="post">
用户名:&nbsp;<input type="text" name="user.username"/><br/>
密码:&nbsp;<input type="password" name="user.password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>

说明:
(1).在提交form表单时会将属性值通过User实体属性传递给Action,但必须保持前后属性的一致性。
(2).在jsp页面中,<input>标签的name属性需要添加对象,即“对象名.属性名”这种形式,如name="user.username"。

3.ModelDriven方式接收参数
在action中实现ModelDriven接口来接收客户端上传的参数,这种方式仍然需要实体User。
它的运行过程是:Struts2调用ModelDriven接口中的getModel()方法取得Action中的user对象,再把上传的用户名密码存入user对象。

package com.lxx.action;
import com.lxx.model.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven; public class TestAction extends ActionSupport implements ModelDriven<User> {
//手动实例化
private User user = new User(); public User getModel() {
//返回实例
return user;
} public String execute() {
return "index";
} public String login(){
System.out.println("用户名:"+user.getUsername() + "-----------------"+"密码:"+user.getPassword());
return "index";
}
}
<form action="testAction!login" method="post">
用户名:&nbsp;<input type="text" name="username"/><br/>
密码:&nbsp;<input type="password" name="password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>

说明:
使用ModelDriven方式接收页面参数,name属性不需要添加对象,即name="username";

总结:

Struts2中Action接收参数的方法主要有以下三种:
1.使用Action的属性接收参数:
    a.定义:在Action类中定义属性,创建get和set方法;
    b.接收:通过属性接收参数,如:userName;
    c.发送:使用属性名传递参数,如:user1!add?userName=Magci;
2.使用DomainModel接收参数:
    a.定义:定义Model类,在Action中定义Model类的对象(不需要new),创建该对象的get和set方法;
    b.接收:通过对象的属性接收参数,如:user.getUserName();
    c.发送:使用对象的属性传递参数,如:user2!add?user.userName=MGC;
3.使用ModelDriven接收参数:
    a.定义:Action实现ModelDriven泛型接口,定义Model类的对象(必须new),不需要提供该对象的get和set方法,通过getModel方法返回该对象;
    b.接收:通过对象的属性接收参数,如:user.getUserName();
    c.发送:直接使用属性名传递参数,如:user2!add?userName=MGC

三、Struts.xml中<action>标签中method属性的用法

1.在<action>的配置代码中method属性默认调用action类的execute()方法,但是在实际应用中一个action需要处理很多方法,就可以添加method="不同的方法名"来调用acton中对应的方法。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="utf-8" />
<package name="default" namespace="/" extends="struts-default"> <action name="login" class="com.demo.action.UserAction" method="login">
<result type="chain">all</result>
<result name="input">login.jsp</result>
</action> <action name="all" class="com.demo.action.DeptAction" method="getDept">
<result>list.jsp</result>
</action> </package>
</struts>

上面<action>标签中定义method='login'和method='getDept'方法,就会请求Action类中方法名为login和getDept的方法。

2.动态方法调用

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="utf-8" /> <package name="default" namespace="/" extends="struts-default">
<action name="login" class="com.demo.action.UserAction">
<result name="input">login.jsp</result>
</action>
</package>
</struts>

不难发现上面的方法并没有指定具体调用哪个方法,这是因为在下面的form表单中指定。

<form action="login!userLogin" method="post">
用户名:&nbsp;<input type="text" name="user.username"/><br/>
密码:&nbsp;<input type="password" name="user.password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>

在form表单中的action="login!userLogin"会调用Action类中的userLogin方法。
不难发现动态调用的语法是:actionName!methodName.action,其中.action可以省略,但是值得注意的是,动态方法调用可能会带了安全隐患,暴露业务方法给用户,官方也不推荐这样用,不过可以在struts.xml中添加<constant name="struts.enable.DynamicMethodInvocation" value="false"/>来禁用动态方法调用。

四、使用通配符简化struts.xml中<action>标签的配置
1.在<action>中使用通配符简化配置
struts.xml中配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="utf-8" /> <package name="default" namespace="/" extends="struts-default">
<action name="house_*" class="com.demo.action.HouseAction" method="{1}">
<result>list_{1}.jsp</result>
</action>
</package>
</struts>

以上的配置在jsp页面的<form action="house_add"></form>或者<form action="house_update"></form>都会得到响应的请求,也就是action属性是house_任意字符都会得到请求,返回result中的list_任意字符的jsp页面,也就是house_后面的字符和{1}是一样的匹配。

问题:当有多个<action>匹配的时候会匹配哪个?
假如有下配置会匹配哪个呢:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.i18n.encoding" value="utf-8" /> <package name="default" namespace="/" extends="struts-default">
<action name="house_add" class="com.demo.action.HouseAction" method="add">
<result name="success">add.jsp</result>
</action> <action name="house_*" class="com.demo.action.HouseAction" method={1}>
<result>{1}.jsp</result>
</action>
</package>
</struts>

答案:如果有完全匹配的就优先使用完全匹配的,没有完全匹配的使用通配符匹配,如果有多个通配符匹配的,按照先后顺序优先使用在前的匹配。

struts2进阶篇(2)的更多相关文章

  1. struts2进阶篇(5)

    一.OGNL简介 OGNL (Object-Graph Navigation Language)的缩写,简称对象图导航语言. OGNL表达式的特特点: >能够取对象的属性,也能调用对象的方法. ...

  2. struts2进阶篇(4)

    一.使用ActionContext访问Servlet API strtus2提供了一个ActionContext类,该类别称为Action上下文或者Action环境,Action可以通过该类来访问最常 ...

  3. Struts2进阶(一)运行原理及搭建步骤

    Struts2进阶(一)运行原理 Struts2框架 Struts2框架搭建步骤 致力于web服务,不可避免的涉及到编程实现部分功能.考虑使用到SSH框架中的Struts2.本篇文章只为深入理解Str ...

  4. SSH开发模式——Struts2进阶

    在之前我有写过关于struts2框架的博客,好像是写了三篇,但是之前写的内容仅仅是struts2的一些基础知识而已,struts2还有很多有趣的内容等待着我们去发掘.我准备再写几篇关于struts2的 ...

  5. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  6. idea 插件的使用 进阶篇

    CSDN 2016博客之星评选结果公布    [系列直播]零基础学习微信小程序!      "我的2016"主题征文活动   博客的神秘功能 idea 插件的使用 进阶篇(个人收集 ...

  7. 2. web前端开发分享-css,js进阶篇

    一,css进阶篇: 等css哪些事儿看了两三遍之后,需要对看过的知识综合应用,这时候需要大量的实践经验, 简单的想法:把qq首页全屏另存为jpg然后通过ps工具切图结合css转换成html,有无从下手 ...

  8. windows系统快捷操作の进阶篇

    上次介绍了windows系统上一些自带的常用快捷键,有些确实很方便,也满足了我们的一部分需求.但是我们追求效率的步伐怎会止步于此?这一次我将会进一步介绍windows上提升效率的方法. 一:运行 打开 ...

  9. python 面向对象(进阶篇)

    上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

随机推荐

  1. shell实现两个数的相加

    刚开始的时候写,一直写不对:看似简单的功能,但是一定要小心:函数的定义: funciton functionName {.....}在functionName和{之间一定有空格啊! 我就是没加空格,就 ...

  2. asp.net mvc中应用缓存依赖文件(xml)的一个小demo

    最近项目中加了一个通用模块,就是根据一些特殊的tag,然后根据处理这些tag在同一个视图中加载不同的model(个人觉得此功能无任何意义,只是把不同的代码放在了同一个View中). 我的处理思路是这样 ...

  3. Pycharm设置

    File->settings->Editor->File and Code Templates->Python Script #!/usr/bin/env python # e ...

  4. 轻松搞定C语言中复杂的声明

    参考资料: [1] <C专家编程> 第3章 分析C语言的声明,p64-66

  5. Leetcode 221. Maximal Square

    本题用brute force超时.可以用DP,也可以不用. dp[i][j] 代表 以(i,j)为右下角正方形的边长. class Solution(object): def maximalSquar ...

  6. linux永久更改eth0的ip地址后仍然ping不通过

    编辑文件/etc/sysconfig/network-scripts/ifcfg-eth0 引用:DEVICE=eth0 //设备名称,不要修改 BOOTPROTO=static //不要修改 BRO ...

  7. BZOJ1912 [Apio2010]patrol 巡逻

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  8. BZOJ2426 [HAOI2010]工厂选址

    Description 某地区有m座煤矿,其中第i号矿每年产量为ai吨,现有火力发电厂一个,每年需用煤b吨,每年运行的固定费用(包括折旧费,不包括煤的运费)为h元,每吨原煤从第i号矿运到原有发电厂的运 ...

  9. 使用Guava来计算笛卡尔积

    以前做项目的时候计算笛卡尔积的时候,总是使用各种for循环来嵌套,最后往往在Sonar代码检查的时候总是会报警说for循环嵌套过深. 今天才知道Guava原来已经为我们提供了优雅的计算笛卡尔积的方法. ...

  10. Linux命令点滴积累

    1.批量删除当前目录及子目录中指定类型的文件: [root@localhost logs]# find ./ -name *.bak | xargs rm -rf [root@localhost lo ...