struts配置文件的主要元素

1. package元素

作用:

在struts2的配置文件中引入了面向对象的思想,使用了分包管理 。易于管理动作类。便于模块化开发动作类

属性:

name包的名称。必须写,且必须唯一
extends

一般情况下需要继承struts-default包,但不是必须的

不过如果不继承的话,将无法使用struts2提供的核心功能

struts-default.xml中定义这struts-default这个包

而struts-default.xml是在我们的struts.xml加载之前加载

abstract

把包声明为抽象包,如果为true则表示为抽象包

只要没有action标签元素的包,都可以被声明为抽象包,这一点和java类似

namespace

名称空间。[访问路径=名称空间+动作名称]

默认取值为""

namespace注意事项

注意:默认值不是/,写自定义的namespace时前面要加上/

下面这一例子的访问路径是   项目虚拟路径/user/hello

注意:需要在访问action前添加红色命令空间

注意:如果访问  项目虚拟路径/user/a/b/hello是可以访问到的

          如果访问  项目虚拟路径/a/b//user/hello是不可以访问到的

上面这种情况与namespace的查找规则有关


2. action元素

作用:

配置动作,处理请求路径

属性:

name:动作名称

class:动作类全名

method:动作类中的方法名称。默认是public String excute(){}

  方法的要求:

       1. public修饰

       2. 返回值必须是String

       3. 无参


动作类的第一种写法:

直接创建一个action类,不需要继承任何类,然后在struts.xml中配置

Action:

struts.xml

访问路径:http://localhost:8080/项目名/user/hello

动作类的第二种写法:

Action:

struts.xml:

访问路径为:http://localhost:8080/struts_1_war_exploded/user/hello1

Action接口中会有一些静态常量,如下图:

这些常量就是定义了一些固定的常用值,可以在implements了Action接口之后的action类里面使用

常量说明:

常量的变量名对应的值说明
SUCCESSsuccess动作方法执行一切ok
ERRORerror动作方法执行时遇到了异常
INPUTinput回显(提交表单,返回页面之后,继续显示之前所打的数据)
LOGINlogin一般转向登录页面
NONEnone不转向任何的视图

动作类的第三种写法:

写个 Action 类继承 ActionSuport 接口 [ 推荐使用这种方式 ]

ActionSupport 是实现 Action 接口的类,如果动作类方法体里面没有写excute方法,则会去父类Action中调用excute方法

import com.opensymphony.xwork2.ActionSupport;

public class HelloAction2 extends ActionSupport {

}
	<!--这个action没有配置method,默认会访问Action的excute()方法
			在HelloAction2里没有实现excute方法,找的是父类ActionSupport的excute()方法
		-->
		<action name="hello2" class="com.zr.web.action.HelloAction2">
			<result name="success">/success.jsp</result>
		</action>

默认的动作类

在struts-default.xml中定义了默认动作类和方法,当我们在action中没加class和method属性,那么会默认执行默认动作类

就是com.opensymphony.xwork2.ActionSupport这个类

<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />

 

我们自己也可以配置一个默认的动作类,在struts.xml中的package里面添加一个默认动作类,注意要将这个默认标签放在action标签前面,要不然会报错,也可以根据错误提示进行修改顺序

注意:一般很少修改

<default-class-ref class="com.opensymphony.xwork2.ActionSupport"></default-class-ref>

动作访问之通配符

*  通配符

Action的name属性如果写的是 * 表示自动填充输入的name名

Action的method属性如果写的是 {1} 表示前面的 * 所填充的name名

Action中的result标签中如果写的是 /{1}.jsp 表示前面的 * 所填充的name名

**  通配符

Action的name属性如果写的是 *_* 表示自动填充输入的name名

Action的method属性如果写的是 {1}{2} 表示前面的 *_* 所填充的name名

Action中的result标签中如果写的是 /{1}{2} .jsp 表示前面的 *_* 所填充的name名

比如创建一个UserAction,其中定义了一些方法,如deleteUser,addUser

当访问 delete_User,那么会自动填充上面的method中的1和2参数,自动去掉 _ ,为deleteUser,return一个值,查询result的name属性是否存在这个return的值,如果存在则,自动访问标签内部的路径,去掉_,自动填充1和2参数,则会自动访问deleteUser.jsp


动态方法的调用

写一个名为StudentAction的action类

import com.opensymphony.xwork2.ActionSupport;

public class StudentAction extends ActionSupport {
    public String addStudent(){

        return SUCCESS;
    }

    public String deleteStudent(){

        return SUCCESS;
    }

}

在struts.xml中配置动态调用方法的常量值为true,并且设置一个action,如下:

<struts>
	<!--配置常量-->
	<!--配置开发者模式-->
	<constant name="struts.devMode" value="true"></constant>
	<!--配置动态调用方法开启-->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	<package name="p1" extends="struts-default" namespace="/student">
		<action name="student" class="com.zr.web.action.StudentAction">
			<result name="success">/success.jsp</result>
		</action>
	</package>
</struts>

那么访问路径为:

http://localhost:8080/struts_1_war_exploded/student/student!addStudent

那么会调用StudentAction中的addStudent方法

3. result元素

作用:

为指定动作指定结果视图

属性:

name:逻辑视图的名称,对应着动作方法的返回值。默认值是success

type:结果类型,指的是用什么方式转到定义的页面。默认是dispatcher

resulttype的取值

result中type的取值有四种类型

dispatcher(默认值)使用请求转发,转向一个页面
redirect使用重定向,转向一个页面
chain

转发到另一个相同名称空间的动作

转发到不同名称空间的动作

redirectAction

重定向到另一个相同名称空间的动作

重定向到不同名称空间的动作

type的默认取值是dispatcher,转发

type的属性取值在struts-default.xml中定义着

 示例:

写一个DemoAction,继承 ActionSupport

import com.opensymphony.xwork2.ActionSupport;

public class DemoAction extends ActionSupport {

}

在struts.xml中这样写:

<package name="p2" extends="struts-default" namespace="/test"	>
	<action name="demo1" class="com.zr.web.action.DemoAction">
		<!--
			1. 注意这里面是可以不用写name的,默认是success
			2. type属性
				dispatcher:默认值,转发到一个页面
				redirect:重定向一个页面
				chain:
				redirectAction:
		-->
		<result name="success" type="dispatcher">/success.jsp</result>
	</action>
</package>

那么启动项目后,访问下面路径会转发到succes.jsp页面(路径不变)

http://localhost:8080/struts_1_war_exploded/test/demo1

注意这里面不写方法是因为action类继承了ActionSupport,在其中有已经实现的excute()方法,如果在result标签后面没有加上method标签,则会默认调用这一excute()方法

 

上面这个是result的type为dispatcher(转发时的示例),其他的三个可以自己尝试

chain:转发到同一个包或者不同包的其他的action中去

redirectAction:重定向到同一个包或者不同包的另外一个action

当chain用来转发到另外一个不同的包中时

<result name="success" type="chain">
   <param name="namespace">另外一个包的命名空间</param>
   <param name="actionName">另外一个包中的action的名字</param>
</result>

result元素中param子元素

在转发或者重定向到不同包下的动作时,都用到了result元素的子元素param

param元素的作用:依赖注入(Dependence Injection)思想

我们通过struts-default.xml中的resultTypes元素中配置可以看出,每个结果类型视图其实都是靠一个类来实现的

而param元素就是将配置的参数,注入到该类中

调用的是对应类的setter方法进行注入的

自定义结果类型

其实结果类型就是一个类,这些类都实现com.opensymphony.xwork2.Result接口

或者继承自该接口的实现类org.apache.struts.dispatcher.StrutsResultSupport

这些类都有一个doExcute方法,用于执行结果视图(查看源码各种结果类型的类结构)

struts的内部实现就是Servlet

上面这种自定义结果类型其实就是一个类,这些类可以实现Result接口,也可以继承自StrutsResultSupport(Result接口实现类)

综上所述自己写一个结果视图

例子:输出CAPTCHA图像的结果类型

CAPTCHA  即 验证码

步骤:

第一步:继承StrutsResultSupport或者实现Result接口

第二步:重写doExecute方法

package result;

import cn.dsna.util.images.ValidateCode;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;

import javax.servlet.http.HttpServletResponse;

/**
 * 验证码的结果类型
 */
public class CAPTCHAResult extends StrutsResultSupport {
    @Override
    protected void doExecute(String s, ActionInvocation actionInvocation) throws Exception {
        //生成验证码  这个方法需要导入一个名字叫做ValidateCode.jar的jar包
        //参数分别为 验证码图片的宽度、高度、验证码字符的个数、验证码的干扰条个数
        ValidateCode code=new ValidateCode(200,30,4,6);

        //利用response将这个结果返回给客户端
        HttpServletResponse response = ServletActionContext.getResponse();
        //响应给客户端面
        code.write(response.getOutputStream());
    }
}

第三步:配置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>
	<!--配置动态调用方法开启-->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<package name="p1" extends="struts-default" namespace="/result"	>
		<!--声明一个结果类型-->
		<result-types>
			<!--验证码的结果类型-->
			<result-type name="captcha" class="result.CAPTCHAResult"></result-type>
		</result-types>
		<!--配置action-->
		<action name="checkcode">
			<result type="captcha"></result>
		</action>
	</package>
</struts>

然后启动项目,访问如下路径,会在网页上返回一个验证码图片

http://localhost:8080/struts_1_war_exploded/result/checkcode

优化自定义结果类型

但是这样不能根据大小调整验证码宽度和高度,我们可以利用result中可以设置参数这一特点,在CAPTCHAResult类中添加两个变量 width和height,为其添加setter和getter

package result;

import cn.dsna.util.images.ValidateCode;
import com.opensymphony.xwork2.ActionInvocation;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;

import javax.servlet.http.HttpServletResponse;

/**
 * 验证码的结果类型
 */
public class CAPTCHAResult extends StrutsResultSupport {
    private int width; //验证码宽度
    private int height; //验证码高度

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    protected void doExecute(String s, ActionInvocation actionInvocation) throws Exception {
        //生成验证码  这个方法需要导入一个名字叫做ValidateCode.jar的jar包
        //参数分别为 验证码图片的宽度、高度、验证码字符的个数、验证码的干扰条个数
        ValidateCode code=new ValidateCode(width,height,4,6);

        //利用response将这个结果返回给客户端
        HttpServletResponse response = ServletActionContext.getResponse();
        //响应给客户端面
        code.write(response.getOutputStream());
    }
}

在struts.xml中result设置参数

<action name="checkcode">
	<result type="captcha">
		<param name="width">120</param>
		<param name="height">30</param>
	</result>
</action>

那么在这些param中name写为变量名,那么当执行此result时,就会把这些参数自动填充给相应的变量

全局视图和局部视图

前面所用到的result就可以称为结果视图,上面所用的所有这种视图是局部视图,只能作用于一个package中

那么如果想要一个result作用于所有package,即全局视图,就需要声明一个抽象包,可以被继承

如下面所示的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>
	<!--配置动态调用方法开启-->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>

	<package name="myDefault" extends="struts-default" abstract="true">
		<!--全局的结果视图配置:
			声明一个验证码的结果类型
		-->
		<result-types>
			<result-type name="captcha" class="result.CAPTCHAResult"></result-type>
		</result-types>
	</package>
	<package name="p1" extends="myDefault" namespace="/result1"	>
		<!--配置action-->
		<action name="checkcode">
			<result type="captcha">
				<param name="width">120</param>
				<param name="height">30</param>
			</result>
		</action>
	</package>
	<package name="p2" extends="myDefault" namespace="/result2"	>
		<!--配置action-->
		<action name="checkcode">
			<result type="captcha">
				<param name="width">120</param>
				<param name="height">30</param>
			</result>
		</action>
	</package>
</struts>

这里面注意:抽象包内没有action元素,只能用于继承

动作类中的Servlet api访问讲解

获取servlet api的方式

第一种方式:通过ServletActionContext获取

TestAction类



import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class TestAction extends ActionSupport {

    public String test(){
        //获取servlet api的方式
        //第一种方式:通过ServletActionContext获取
        //1. response
        HttpServletResponse response = ServletActionContext.getResponse();
        //2. request
        HttpServletRequest request = ServletActionContext.getRequest();
        //3. session
        HttpSession session = request.getSession();
        //4. application 即 ServletContext对象
        ServletContext application = ServletActionContext.getServletContext();
        /*
            org.apache.struts2.dispatcher.StrutsRequestWrapper@3aa7a9ee 属于struts的
            org.apache.catalina.connector.ResponseFacade@1a5a082d       属于tomcat
            org.apache.catalina.session.StandardSessionFacade@644e9268  属于tomcat
            org.apache.catalina.core.ApplicationContextFacade@3ddb7736  属于tomcat
        */
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
        System.out.println(application);
        return NONE;
    }
}

 struts.xml

<package name="test" extends="struts-default">
		<action name="testAction" class="com.zr.web.action.TestAction" method="test"></action>
</package>

第二种方式:通过实现接口让struts自动注入

 Test1Action类



import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.util.ServletContextAware;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Test1Action extends ActionSupport implements ServletRequestAware, ServletResponseAware, ServletContextAware {
    HttpServletResponse response;
    HttpServletRequest request;
    ServletContext application;
    public String test(){
        //获取servlet api的方式
        //第二种方式:通过实现接口让struts自动注入
        /**
         * Aware 注入,调用方法,注入参数
         * 实现两个接口 ServletRequestAware, ServletResponseAware
         * 那么访问该action的时候会自动调用下面的两个setServletRequest,setServletResponse方法
         * 会自动将 HttpServletRequest request 和 HttpServletResponse response 注入进来
         */
        return NONE;
    }


    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request=request;
    }

    @Override
    public void setServletResponse(HttpServletResponse response) {
        this.response=response;
    }

    @Override
    public void setServletContext(ServletContext application) {
        this.application=application;
    }
}

struts.xml

<package name="test" extends="struts-default">
      <action name="test1Action" class="com.zr.web.action.Test1Action" method="test"></action>
</package>

第二种注入方式的原理是因为struts有个拦截器servletConfig

            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>

 

再看看struts的架构图

在执行action之前会经过一些拦截器,在这些拦截器中就有一个servletConfig拦截器

在拦截器的源码中判断action中是否实现了ServletResponseAware,ServletRequestAware等接口,如果实现了,则setServletResponse()

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值