初步学习Struts2

一、struts2介绍

Apache Struts2 是流行和成熟的基于MVC设计模式的Web应用程序框架。它成功地结合了 WebWork和Struts1.x 两种 web 框架。使用OGNL表达式和Struts2标签来解决应用程序数据。通过Struts2可以减少使用MVC模式开发Web应用程序时间.

二、第一个struts2程序

1.下载struts2相关jar包.

地址:http://struts.apache.org/

2.struts2引入最少包,如下(若缺少会报错)

struts2

3.实现Action类

import com.opensymphony.xwork2.ActionSupport;

public class UserAction extends ActionSupport {
	private Logger log = Logger.getLogger(UserAction.class);
	@Override
	public String execute() throws Exception {
		
		/*  
		 *  接收请求
		 *  执行业务处理
		 *  返回响应
		 */
		log.debug("执行添加用户操作 >>>>>>");
		
		return SUCCESS;
	}
}

4.核心配置文件struts.xml

   <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<package name="student" namespace="/" extends="struts-default">

		<action name="user" class="com.ittx.strutsproject.action.UserAction">
			<result name="success">/sucess.jsp</result>
		</action>

	</package>
</struts>

5.配置web.xml

  <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>strutsdemo</display-name>
	<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>

	<welcome-file-list>
		<welcome-file>login.jsp</welcome-file>
	</welcome-file-list>
</web-app>

6. 执行请求

result1

三、struts2工作原理

s1

一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码:https://github.com/apache/struts):

1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin) 
3 接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来决定这个请是否需要调用某个Action 
4 如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给ActionProxy 
5 ActionProxy通过Configuration Manager询问框架的配置文件struts.xml,找到需要调用的Action类 
6 ActionProxy创建一个ActionInvocation的实例。
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 
8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper

内容目录

一、struts核心文件
   1.struts.properties文件struts2常量定义
   2.struts.xml核心文件结构
二、Action搜索顺序
三、动态方法调用
  1:Action的method属性完成动态方法调用 
  2:感叹号方式 !<h2>
  3:通配符方式 
四、struts2接收参数的几种形式
  1. 用Action的属性
  2. 使用DomainModel
  3.使用ModelDriven

四、struts核心文件

1.struts.properties文件struts2常量定义

#是否开启开发模式 
struts.devMode=true
#所有匹配*.action的请求都由struts2处理
struts.action.extension=do
#struts配置文件改动后,是否重新加载 
struts.configuration.xml.reload=true
#请求参数的编码方式
struts.i18n.encoding=UTF-8
#每次HTTP请求系统都重新加载资源文件,有助于开发
struts.i18n.reload=true
#文件上传最大值
struts.multipart.maxSize=102400
#设置上传文件临时目录 set place to fileupload of tempfile 
struts.multipart.saveDir=d:/temp
#让struts2支持动态方法调用
struts.enable.DynamicMethodInvocation=true
#允许标签中使用表达式语法
struts.tag.altSyntax=true

2.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>
   
    <package name="packageName" namespace="/test" extends="struts-default">
		<action name="actionName" class="com.ittx.struts.action.UserAction" method="methodName">
			<result>/sucess.jsp</result>
			<result name="ADD">/result.jsp</result>
		</action>

    </package>

</struts>
1>package标签 package提供了将多个Action组织为一个模块的方式。
   name:package名称
   extends:继承的父package名称
   namespace:定义package命名空间 该命名空间影响到url的地址,例如此命名空间为/test那么访问是的地址为   http://localhost:8080/struts2/test/actionName.action

2>action标签  定义访问的action名称,类,方法及返回jsp等模板页
   name:action名称
   class:action类
   method:方法名
3>result标签  指定响应类型和响应页面

struts.xml文件详细示例:

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

    <!-- include节点是struts2中组件化的方式 可以将每个功能模块独立到一个xml配置文件中 然后用include节点引用 -->
    <include file="struts-default.xml"></include>
    
    
    <!--
        package提供了将多个Action组织为一个模块的方式
        package的名字必须是唯一的, package可以扩展 当一个package扩展自
        另一个package时该package会在本身配置的基础上加入扩展的package
        的配置 父package必须在子package前配置 
        name:package名称
        extends:继承的父package名称
        abstract:设置package的属性为抽象的 抽象的package不能定义action 值true:false
        namespace:定义package命名空间 该命名空间影响到url的地址,例如此命名空间为/test那么访问是的地址为http://localhost:8080/struts2/test/XX.action
     -->
    <package name="com.kay.struts2" extends="struts-default" namespace="/test">
        <interceptors>
            <!-- 定义拦截器 
                name:拦截器名称
                class:拦截器类路径
             -->
            <interceptor name="timer" class="com.kay.timer"></interceptor>
            <interceptor name="logger" class="com.kay.logger"></interceptor>
            <!-- 定义拦截器栈 -->
            <interceptor-stack name="mystack">
                <interceptor-ref name="timer"></interceptor-ref>
                <interceptor-ref name="logger"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        
        <!-- 定义默认的拦截器 每个Action都会自动引用
         如果Action中引用了其它的拦截器 默认的拦截器将无效 -->
        <default-interceptor-ref name="mystack"></default-interceptor-ref>
        
        
        <!-- 全局results配置 -->
        <global-results>
            <result name="input">/error.jsp</result>
        </global-results>
        
        <!-- Action配置 一个Action可以被多次映射(只要action配置中的name不同)
             name:action名称
             class: 对应的类的路径
             method: 调用Action中的方法名
        -->
        <action name="hello" class="com.kay.struts2.Action.LoginAction">
            <!-- 引用拦截器
                name:拦截器名称或拦截器栈名称
             -->
            <interceptor-ref name="timer"></interceptor-ref>
        
            <!-- 节点配置
                name : result名称 和Action中返回的值相同
                type : result类型 不写则选用superpackage的type struts-default.xml中的默认为dispatcher
             -->
         <result name="success" type="dispatcher">/talk.jsp</result>
         <!-- 参数设置 
             name:对应Action中的get/set方法 
         -->
         <param name="url">http://www.sina.com</param>
        </action>
    </package>
</struts>

五、Action搜索顺序

新建一个struts2项目,命名为struts2。按照如下XML文件配置一个Action:

<package name="hello" namespace="/test" extends="struts-default">
    <action name="helloworld" class="com.ittx.struts.action.HelloWorldAction" method="execute">
            <result name="success">/hello.jsp</result>
    </action>
</package>

将应用部署,访问如下路径:http://localhost:8080/struts2/test/sdf/dsf/32/d/helloworld.action 依然可以访问到Action。
这主要是因为Struts2对Action名称的搜索是按照一定顺序进行的。以上面的情况为例:


1.struts2首先搜索命名空间为/test/sdf/dsf/32/d的包是否存在,存在的情况下,是否有helloworld这个Action;
2.搜索命名空间为/test/sdf/dsf/32的包是否存在,存在的情况下,是否有helloworld这个Action;
3.搜索命名空间为/test/sdf/dsf的包是否存在,存在的情况下,是否有helloworld这个Action;
4.搜索命名空间为/test/sdf的包是否存在,存在的情况下,是否有helloworld这个Action;
5.搜索命名空间为/test的包是否存在。在这种情况下能够搜索到,因此,可以访问到helloworld这个Action。
此外,如果按照这种搜索顺序搜索,发现所有的包均不存在,那么struts2则会到命名空间为””(默认命名空间)的包下面去找helloworld这个Action。

六、动态方法调用

动态方法调用指的就是为了解决一个Action对应多个请求的处理,以免Action太多。
动态方法调用有3中方法,分别为:
1、Action的method属性
2、感叹号方式 !
3、通配符方式

下面将分别进行介绍。

第一种:Action的method属性完成动态方法调用

只需要改两个地方,第一个是在Action类中添加其他的方法。例如:在本例中就是添加了add()和update()方法。

public class UserAction extends ActionSupport {
	public String add() {
		log.debug("执行add添加用户操作 >>>>>>");
		return "ADD";
	}
	
	public String update(){
		log.debug("执行update用户操作 >>>>>>");
		return "UPDATE";
	}
	
<action name="userAdd" class="com.ittx.strutsproject.action.UserAction"
			method="add">
			<result name="ADD">/add_student.jsp</result>
		</action>

		<action name="userUpdate" class="com.ittx.strutsproject.action.UserAction"
			method="update">
			<result name="UPDATE">/update_student.jsp</result>
		</action>
访问添加方法执行如下路径:http://localhost:8080/struts2/userAdd.action
访问修改方法执行如下路径http://localhost:8080/struts2/userUpdate.action

第二种:感叹号方式 !

这种使用method属性的方式来实现动态方法有一个不好的地方在于:如果只有几个方法需要被调用,这样还好,我们只需要在struts.xml文件中,写几个类似下面的代码段。但是,如果有几百个方法需要被动态调用,那么用这种方法可能就不适合了,这样代码冗余太大,也不便于管理。因此就有了下面的两种方法:!、通配符的使用,这里介绍第一种。

<action name="user" class="com.ittx.strutsproject.action.UserAction">
			<result>/sucess.jsp</result>
			<result name="ADD">/add_student.jsp</result>
			<result name="UPDATE">/update_student.jsp</result>
		</action>
访问添加方法执行如下路径:http://localhost:8080/struts2/user!add.action
访问修改方法执行如下路径http://localhost:8080/struts2/user!update.action
在struts.xml文件中最下面一行代码特别要注意:这是开启感叹号可应用于动态方法调用。
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
适配struts2.5感叹号通配符调用无效的问题:在pakcage标签下添加如下标签
<global-allowed-methods>regex:.*</global-allowed-methods>

第三种:通配符方式

<package name="student" namespace="/student" extends="struts-default">
		<!-- 解决struts2.5 通配符调用无效的问题 -->
		<global-allowed-methods>regex:.*</global-allowed-methods>
		
		<action name="user_*" class="com.ittx.strutsproject.action.UserAction" method="{1}">
			<result>/sucess.jsp</result>
			<result name="ADD">/add_student.jsp</result>
			<result name="UPDATE">/update_student.jsp</result>
		</action>

	</package>
访问添加方法执行如下路径:http://localhost:8080/struts2/user_add.action
访问修改方法执行如下路径http://localhost:8080/struts2/user_update.action

七、struts2接收参数的几种形式

1. 用Action的属性

在action 里面定义要接收的参数,并提供相应的setter,getter,和提交参数的名称一致,并不用做数据类型的转换。
相应提交方式可以用get 和post,如:testAction? name=admin
如:
jsp:

<form action="./user_add.do" method="post">
		 姓名:<input type="text" name="username"/><br>
		 密码:<input type="text" name="password"/><br>
		 <input type="submit" value="提交"/><br>
	</form> 

java:

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

2. 使用DomainModel

在Action 里面不用很多的属性,而是用Model 层用到的模型,保存它的一个对象。相应提交方式可以用get 和post,
jsp:

<form action="./user_add.do" method="post">
		 姓名:<input type="text" name="user.username"/><br>
		 密码:<input type="text" name="user.password"/><br>
		 <input type="submit" value="提交"/><br>
	</form> 

java action:

public class TestAction extends ActionSupport{
//错误的写法,不能自己实例化,struts会自动实例化private Users users = new Users();
private Users users;
public Users getUsers(){
   return users;
}
public void setUsers(Users users){
  this.users=users;
}

entity:

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

3.使用ModelDriven:

在创建Action 的时候,Action 实现了ModelDriven 接口,去调用接口的getModel()方法,取到了相关对象。
jsp:

<form action="./user_add.do" method="post">
		 姓名:<input type="text" name="username"/><br>
		 密码:<input type="text" name="password"/><br>
		 <input type="submit" value="提交"/><br>
	</form> 

java:

public class sysAction extends ActionSupport implements ModelDriven<User>{    
    private User user = new User(); //手动实例化   
      
    public User getModel() {        
        return user; //返回实例   
    }     
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值