SSH开发模式——Struts2(第二小节)
上一小节已经学会了如何去搭建Struts2的开发环境,该篇博客我们继续深入Struts2,了解Struts2框架的拦截器。
首先对我们在web.xml文件配置的过滤器进行一个源码的分析。
在StrutsPrepareAndExecuteFilter源码中,有一个init()方法,它调用方法获得了一个Dispatcher对象,这就是我们要分析的关键了。进入到它的源码,在其init()方法中调用了init_TraditionalXmlConfigurations()方法,该方法的源码如下:
private void init_TraditionalXmlConfigurations() {
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split("\\s*[,]\\s*");
for (String file : files) {
if (file.endsWith(".xml")) {
if ("xwork.xml".equals(file)) {
configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false));
} else {
configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException("Invalid configuration file name");
}
}
}
注意了,在这个方法里有这样一句代码,configPaths = DEFAULT_CONFIGURATION_PATHS; ,关键就是这个字段,我们继续跟进。
private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
看到这里你总该明白了吧,为什么新建的struts2的配置文件名字必须为struts.xml?为什么struts2的配置文件中package标签要继承struts-default?相信应该不用我解释了。
其实,过滤器的作用有很多,之前也有介绍,但是,如果把所有的任务都交给过滤器处理,那过滤器的负担将会非常重,过滤器的代码会非常多,也不符合我们低耦合,高内聚的设计思想。
我们假设要实现一个功能,在一个类中将该功能分为几个步骤。
class aa{
第一步:
第二步:
第三步:
第四步:
}
但是我们现在这样设计实现。
class a1{
第一步:
}
class a2{
第二步:
}
class a3{
第三步:
}
class a4{
第四步:
}
每个类只实现一步,然后直接调用四个类的方法即可。
这样有什么好处呢?这样四个步骤都不会相互影响,想单独调用某个步骤你可以很容易地实现。这就是分离关注的思想。把要处理的问题,分别用一个类来完成,每个类只完成一个功能。这样的一个类就叫 拦截器。
那拦截器和过滤器有什么区别呢?
相同点:都是起拦截作用的。
不同点:过滤器是J2EE的标准,任何的一个程序都可以使用。
拦截器是struts2框架的标准,不能离开struts2框架,必须依赖struts2框架使用。
过滤器拦截的是web.xml配置文件,其它的拦截工作都交给了拦截器。
执行顺序为过滤器先执行,拦截器后执行。
在struts-default.xml文件中,定义了很多的拦截器。
<!--
interceptors:定义了struts2框架的拦截器
*name:拦截器的名称,是唯一的
*class:拦截器对应的Action类的完整路径
-->
<interceptors>
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
<interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
<interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
<interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" />
<interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" />
<interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
<interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
<interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
<interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
<interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
<interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
<interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
<interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
<interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
<interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
<interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
<interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
<interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
<interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
<interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" />
<interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
<interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" />
<interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" />
<interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" />
</interceptors>
拦截器非常的多,其中也有很多我们眼熟的关键字吧,cookie、params、i18n等等。
在拦截器定义的下面,又定义了很多的interceptor-stack标签,这些标签定义的是拦截器栈。它们有什么作用呢?
这里我只贴出一个默认的拦截器栈作讲解。
<!--
interceptor-stack:拦截器栈
*存放了上面定义的拦截器,拦截器栈相当于list集合,在这里存放的拦截器是有先后顺序的
按照声明的顺序先后执行
-->
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
</interceptor-stack>
至于它是否真的有执行顺序呢?我就不带大家验证了,大家可以找几个拦截器,然后在对应的类中打上断点,然后运行验证即可。
需要注意的是,程序默认执行的是defaultStack拦截器栈,那有没有人想为什么程序默认执行的是该拦截器栈,因为它的名字是defaultStack,所以就会执行它吗?显然,这里面是有原因的。我们往下阅读源码,找到了这样一句配置:<default-interceptor-ref name="defaultStack"/> ,它就是用来配置默认执行的拦截器栈的。
拦截器就先介绍到这里。
之前算是一个对Struts2框架的入门,有很多地方大家可能都不太理解,因为要让大家能够迅速地了解这个框架,所以没有更深层次地去介绍,只是讲述了它的冰山一角。接下来,我们就要对Struts2框架进行一个系统的学习,敬请期待吧。
SSH开发模式——Struts2(第二小节)的更多相关文章
- SSH开发模式——Struts2(第一小节)
在制定了学习计划的学习过程中,我感觉学习还是很有效率的.很短的时间内,我便学习完了JavaWeb的连接池.DbUtils框架及其一些工具类的使用. 学无止境,学习这些知识还远远不够,所以,在接下来的时 ...
- SSH开发模式——Struts2(第三小节)
struts2框架的知识点,虽然分了几个小节,感觉内容还是挺多的,但是你仅仅是入门了而已,想要进一步地提升自己,你得有一颗持之以恒的学习的心,最后的内容我都将在这篇博客中讲到,所以篇幅可能会有点长,希 ...
- SSH开发模式——Struts2进阶
在之前我有写过关于struts2框架的博客,好像是写了三篇,但是之前写的内容仅仅是struts2的一些基础知识而已,struts2还有很多有趣的内容等待着我们去发掘.我准备再写几篇关于struts2的 ...
- SSH框架之Struts2第二篇
1.2 知识点 1.2.1 Struts2的Servlet的API的访问 1.2.1.1 方式一 : 通过ActionContext实现 页面: <h1>Servlet的API的访问方式一 ...
- WEB开发模式浅析
WEB技术随着互联网的崛起而崛起,又随着移动互联网的发展而呈现更加多样化的趋势. 黑暗时代:大约在2005年以前,所谓的WEB开发主要还是美工的活,HTML/CSS占主导,Dreamwaver做为页面 ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:SSH框架(Struts2+Spring+Hibernate)搭建整合详细步骤
在实际项目的开发中,为了充分利用各个框架的优点,通常都会把 Spring 与其他框架整合在一起使用. 整合就是将不同的框架放在一个项目中,共同使用它们的技术,发挥它们的优点,并形成互补.一般而言,在进 ...
- Struts2开发模式漏洞
当Struts2中的devMode模式设置为true时,存在严重远程代码执行漏洞.如果WEB服务以最高权限运行时,可远程执行任意命令,包括远程控制服务器. 如果为受影响的版本,建议修改配置文件stru ...
- struts2的DevMode(开发模式)模式
本文转自:http://blog.csdn.net/q1054261752/article/details/48687119 在实际应用开发或者是产品部署的时候,对应着两种模式: ① 开发模式(dev ...
- Struts2第二篇【开发步骤、执行流程、struts.xml讲解、defalut-struts讲解】
前言 我们现在学习的是Struts2,其实Struts1和Struts2在技术上是没有很大的关联的.Struts2其实基于Web Work框架的,只不过它的推广没有Struts1好,因此就拿着Stru ...
随机推荐
- 【CYH-02】NOIp考砸后虐题赛:成绩:题解
这道题挺送水了吧... 两种做法. 其实空间都不需要那么大,我来提交界面一看一堆MLE的,于是还是良心的放开了时限. 这么简单,就不做解释了. 下面放出几种代码. 代码: 两个数组: #include ...
- 洛谷P1396 营救 题解
题目:https://www.luogu.org/problemnew/show/P1396 分析: 这其实一看就是一个最短路的近似模板的题目,但我们要注意到两个区之间可能会有多条道路,所以说我们只需 ...
- bzoj2431 || 洛谷P1521 求逆序对
考虑一下插⼊法 n<=100n<=100n<=100 f[i][j]f[i][j]f[i][j]表⽰111~iii的全排列有j个逆序对的⽅案数 f[i][j]=Σf[i−1][j−k ...
- 个人永久性免费-Excel催化剂功能第100波-透视多行数据为多列数据结构
在数据处理过程中,大量的非预期格式结构需要作转换,有大家熟知的多维转一维(准确来说应该是交叉表结构的数据转二维表标准数据表结构),也同样有一些需要透视操作的数据源,此篇同样提供更便捷的方法实现此类数据 ...
- 个人永久性免费-Excel催化剂功能第79波-自动及手动备份功能,比Onedrive还好用
在OFFICE365里,有个自动保存功能,可惜保存的地址是在Onedrive里,在中国国情下,备份十分卡顿,近乎难以忍受的慢.虽然现在收费性的网盘部分是可以有文件版本的备份功能,但也是繁琐且最要命的是 ...
- [vue折线图] 记录SpringBoot+Vue3.0折线图订单信息展示
因公司业务需求,需要做一份订单相关的折线图, 如果其中有一天没有订单的话,这一天就是空缺的,在绘制折线图的时候是不允许的,所有要求把没有订单数据的日期也要在图表显示. 使用技术vue3.0+sprin ...
- 在vue中创建自定义指令
原文:https://dev.to/ratracegrad/creating-custom-directives-in-vue-58hh 翻译:心上有杨 指令是带有 v- 前缀的特殊属性.指令的作用是 ...
- Web安全之CSRF攻击(转载)
CSRF是什么? CSRF(Cross Site Request Forgery),中文是跨站点请求伪造.CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任, ...
- RocketMQ中NameServer的启动
在RocketMQ中,使用NamesrvStartup作为启动类 主函数作为其启动的入口: public static void main(String[] args) { main0(args); ...
- 5.源码分析---SOFARPC调用服务
我们这一次来接着上一篇文章<4. 源码分析---SOFARPC服务端暴露>讲一下服务暴露之后被客户端调用之后服务端是怎么返回数据的. 示例我们还是和上篇文章一样使用一样的bolt协议来讲: ...