Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件


Struts2 动态方法调用
动态方法调用就是为了解决一个Action对应多个请求的处理,以免Action太多.
1.指定method属性
2.感叹号方式
3.通配符方式


Demo结构图

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第1张图片

web.xml标准配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	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_2_5.xsd">
  
  
  <!-- 配置Struts2 过滤器 -->
  <filter>
  	<filter-name>Struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>Struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
  
  	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>


先来看普通的,使用method 调用方法

HelloWorldAction.java

package com.struts2.action;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{

	private static final long serialVersionUID = 1L;
	private static final String SUCCESS = "success";
	private static final String Add = "add";
	private static final String UPDATE = "update";
	
	public String add(){
		System.out.println("执行add方法");
		return Add;
	}
	
	public String update(){
		System.out.println("执行update方法");
		return UPDATE;
	}
	
	@Override
	public String execute() throws Exception {
		System.out.println("执行Action");
		return SUCCESS;
	}

	
	
}

然后就是核心文件,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.enable.DynamicMethodInvocation" value="false" />
    
    <!-- 把它设置为开发模式,发布时要设置为false -->
    <constant name="struts.devMode" value="true" />

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

		<action name="helloWorld" class="com.struts2.action.HelloWorldAction">
			<result name="success">/result.jsp</result>
		</action>
		
		<action name="helloWorldAdd" class="com.struts2.action.HelloWorldAction" method="add">
			<result name="add">/add.jsp</result>
		</action>
		
		<action name="helloWorldUpdate" class="com.struts2.action.HelloWorldAction" method="update">
			<result name="update">/update.jsp</result>
		</action>
		
    </package>

</struts>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
  </head>
  
  <body>
    <a href="helloWorld.action">helloWorld</a><br>
    <a href="helloWorldAdd.action">addAction</a><br>
    <a href="helloWorldUpdate.action">updateAction</a><br>
  </body>
</html>

其他几个跳转的jsp页面就不写,只是用来区分跳转结果的....

然后就可以部署发布了...

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第2张图片

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第3张图片



------------------------------------------------华丽丽的分割线------------------------------------------------



好了,然后来说 感叹号方式动态调用

struts2 官方并不推荐使用,但是了解一下 还是需要的....

使用感叹号动态调用需要在struts.xml配置文件中,添加一个配置参数

    <!-- 是否支持动态调用 (使用感叹号来调用) -->
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
该属性设置Struts2是否支持动态方法调用,该属性的默认值是true,如果需要关闭动态方法调用,则可设置该属性为false。使用这个设置后可以这样调用:action!method

web.xml不用做修改,HelloWorldAction.java文件也不用做修改...

只要修改struts.xml配置文件就好了...

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.enable.DynamicMethodInvocation" value="true" />
    
    <!-- 把它设置为开发模式,发布时要设置为false -->
    <constant name="struts.devMode" value="true" />

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

		<action name="helloWorld" class="com.struts2.action.HelloWorldAction">
			<result name="success">/result.jsp</result>
			<result name="add">/add.jsp</result>
			<result name="update">/update.jsp</result>
		</action>
		
    </package>

</struts>
注意看 这个struts.xml 和 上面一个使用method 的 struts.xml 有什么不同哦.....


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
  </head>
  
  <body>
    <a href="helloWorld!add.action">动态调用方法Add</a><br>
    <a href="helloWorld!update.action">动态调用方法Update</a><br>
  </body>
</html>

然后部署运行吧...

仔细看url链接地址....

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第4张图片

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第5张图片


OK.....


------------------------------------------------华丽丽的分割线------------------------------------------------


接下来是使用通配符进行动态跳转

别忘记了,将 <constant name="struts.enable.DynamicMethodInvocation" value="true" /> 中的 true,改为false

主要也是修改.. 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.enable.DynamicMethodInvocation" value="false" />
    
    <!-- 把它设置为开发模式,发布时要设置为false -->
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">
		
		<!-- 
			使用通配符来调用
				 name="helloWorld_*",中的"_" 是用来分隔的,"*"就是对应后面的 method中的"{1}"
				 如果 name="helloWorld_*_*" ,那么 method="{1}{2}"
		-->
		 <action name="helloWorld_*" method="{1}" class="com.struts2.action.HelloWorldAction"> 
		<!--<action name="helloWorld" class="com.struts2.action.HelloWorldAction">-->
			<result name="success">/result.jsp</result>
			<result name="add">/{1}.jsp</result>
			<result name="update">/{1}.jsp</result>
		</action>
		
    </package>

</struts>


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
  </head>
  
  <body>
    <a href="helloWorld_add.action">通配符add</a><br>
    <a href="helloWorld_update.action">通配符Update</a><br>
  </body>
</html>

部署运行....

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第6张图片

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第7张图片



------------------------------------------------华丽丽的分割线------------------------------------------------

OK....三种调用方式都结束了......


Struts2 的工作原理

先来看下这张经典的Struts2流程图


Struts2 工作原理

	Struts2 在web.xml文件中进行配置过滤器(org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter);
	配置过滤器之后,当WEB项目启动之后,过滤器就会生效.
	
	注:旧版本用的是FilterDispatcher过滤器 , 新版本用的StrutsPrepareAndExecuteFilter过滤器
	
		用户通过HttpServletReuqest(用户请求)发送过来,经过一些核心过滤器(比如:FilterDispatcher过滤器);
		然后到达ActionMapper,比如你在struts2.xml 配置文件中拦截的是".action"后缀的请求,那么,只有".action"后缀的请求,才会到ActionMapper,然后根据请求参数
	去查找,ActionMapper中,有没有指定的action;
		如果ActionMapper确定需要调用某个action,FilterDispatcher过滤器,会将控制权交给ActionProxy;
		ActionProxy会读取struts.xml配置文件,找到具体需要调用的action类;
		然后通过ActionProxy代理创建一个ActionInvoaction的实例;
		然后再经过一系列的其他拦截器之后,再到Action,执行相关的代码;
		然后返回result,也就是一个字符串对象,字符串对象,对应的也就是一个视图(jsp);
		然后再经过一系列的其他拦截器,将数据视图打包,通过HttpServletResponse,将数据返回给用户,最后呈现出来.
		
可能叙述的不是很清楚,可以 参考这篇博文:  http://blog.csdn.net/csh624366188/article/details/7490638

Struts核心文件:

Struts2核心文件

	web.xml : 任何MVC框架都需要和Web应用整合,这就不得不借助于web.xml文件,只有配置在web.xml文件中,Servlet才会被应用加载.
	通常,所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts2框架而言,需要加载StrutsPrepareAndExecuteFilter,只要Web应用负责加载StrutsPrepareAndExecuteFilter,
StrutsPrepareAndExecuteFilter就会加载Struts2框架.

	struts.xml(核心配置文件)
		struts.xml是Strus2的核心配置文件,在开发过程中利用率最高.
		该文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等.
		struts.xml中包含的内容:
			1.全局属性
			2.用户请求 和 响应Action之间的对应关系
			3.Action可能用到的参数和返回结果
			4.各种拦截器配置.
	
	struts.properties
		struts2框架的全局属性文件,自动加载.(可有可无)
		

Struts2 Action的搜索顺序

Struts2 Action搜索顺序
	url : http://localhost:8088/Struts2Demo/path1/path2/path3/helloWorld.action
	1.判断package是否存在,如 : /path1/path2/path3/ (就是判断package/命名空间是否存在)
		存在:
			2.判断action是否存在:
				如果存在,就去对应的package下,寻找是否有对应的action;
					如果有那就直接去执行了;
					如果没有直接报错;
				如果不存在,则去默认namespace的package里面寻找action
	
		不存在:
			2.检查上一级路径的package是否存在(直到默认namespace),重复第一步


在Struts.xml中有一些配置参数解释下:

	<constant name="struts.enable.DynamicMethodInvocation" value="false" />
		该属性设置Struts2是否支持动态方法调用,该属性的默认值是true,如果需要关闭动态方法调用,则可设置该属性为false。
		使用这个设置后可以这样调用:action!method
		(动态方法调用)具体: http://blog.csdn.net/itmyhome1990/article/details/9265909
	
	<constant name="struts.devMode" value="true" />
		把它设置为开发模式,发布时要设置为false
		true时,表示为 开发模式 ,开发模式下使用,这样可以打印出更详细的错误信息
		
    <include file="struts_xml/*.xml" />(uboss中的例子:struts_xml文件夹下所有 .xml结尾的配置文件)
    	引入其他的Struts2文件,便于分类管理



------------------------------------------------华丽丽的分割线------------------------------------------------


如果项目中action配置太多,需要创建好多个struts.xml, 那么该如何引用?

Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件_第8张图片

结构是这样子的.....

struts.xml 下面 引用 其他模块的 struts.xml配置文件....

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>

	
	<include file="struts_xml/*.xml"></include>

	<!-- 是否支持动态调用 (使用感叹号来调用) -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    
    <!-- 把它设置为开发模式,发布时要设置为false -->
    <constant name="struts.devMode" value="true" />

</struts>

helloWorld.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="default" namespace="/" extends="struts-default">
		
		<!-- 
			使用通配符来调用
				 name="helloWorld_*",中的"_" 是用来分隔的,"*"就是对应后面的 method中的"{1}"
				 如果 name="helloWorld_*_*" ,那么 method="{1}{2}"
		-->
		 <action name="helloWorld_*" method="{1}" class="com.struts2.action.HelloWorldAction"> 
		<!--<action name="helloWorld" class="com.struts2.action.HelloWorldAction">-->
			<result name="success">/result.jsp</result>
			<!--  
			<result name="add">/add.jsp</result>
			<result name="update">/update.jsp</result>
			-->
			
			<result name="add">/{1}.jsp</result>
			<result name="update">/{1}.jsp</result>
			
		</action>
		
		<!-- 
		<action name="helloWorldAdd" class="com.struts2.action.HelloWorldAction" method="add">
			<result name="add">/add.jsp</result>
		</action>
		
		<action name="helloWorldUpdate" class="com.struts2.action.HelloWorldAction" method="update">
			<result name="update">/update.jsp</result>
		</action>
		 --> 
		
    </package>


</struts>

就像这样子,就可以按照模块不同,配置多个struts.xml文件了

配置默认action方法以后,如果有人输入了错误的URL以后,会统一跳转一个地址,不会出现500 等用户体验不好的错误.

<!-- 
默认action方法
-->
<default-action-ref name="index"></default-action-ref>

<action name="index">
<result>/error.jsp</result>
</action>



你可能感兴趣的:(Struts2 简单实例 / 工作原理 / 动态调用 / 多个配置文件)