项目架构分析-web.xml文件解读
来源:互联网 发布:网络攻防大赛 编辑:程序博客网 时间:2024/06/12 23:06
利用闲暇时间多刚刚结束的项目进行总结,这是一个普惠系统。支持业务员进件、审核、流转,同时支持管理员对员工、权限等进行管理。项目采用dubbo框架,前台用了freemarker+bootstrap。这里开始分析系统架构,从web.xml开始。
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app 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" version="2.5"> <display-name>Manage Server</display-name> <!--在tomcat下部署两个或多个项目时,web.xml文件中最好定义webAppRootKey参数,如果不定义,将会缺省为“webapp.root”--> <context-param> <param-name>webAppRootKey</param-name> <param-value>Manage-Server.root</param-value> </context-param> <!-- 添加日志监听器 --> <!--logbackConfigLocation以及下面的监听是logback相关配置--> <context-param> <param-name>logbackConfigLocation</param-name> <param-value>classpath:logback.xml</param-value> </context-param> <listener> <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class> </listener> <!--contextConfigLocation参数定义了需要装入spring的配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring/applicationContext-*.xml classpath:spring/dubbo-consumer-parent.xml </param-value> </context-param> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <listener> <listener-class> com.myph.manage.common.listener.CustomContextLoaderListener </listener-class> </listener> <filter> <filter-name>SetCharacterEncoding</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SetCharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>*.htm</url-pattern> </filter-mapping> <filter> <filter-name>sessionFilter</filter-name> <filter-class>com.myph.common.filter.SessionFilter</filter-class> <init-param> <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>sessionFilter</filter-name> <url-pattern>*.htm</url-pattern> </filter-mapping> <filter> <filter-name>AntiXssFilter</filter-name> <filter-class>com.myph.manage.common.util.AntiXssFilter</filter-class> </filter> <filter-mapping> <filter-name>AntiXssFilter</filter-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.html</url-pattern> <url-pattern>*.htm</url-pattern> <url-pattern>/</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>ERROR</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring/spring-app-mvc.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <session-config> <session-timeout>420</session-timeout> </session-config> <welcome-file-list> <welcome-file>login.htm</welcome-file> </welcome-file-list> <!-- Error Page定义 --> <error-page> <error-code>404</error-code> <location>/error/404.html</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/500.html</location> </error-page></web-app>
WEB工程加载web.xml过程
web工程在启动时,会先读取web.xml配置文件中的配置,当这一步正确完成时,项目才能被正常启动起来。
1、启动项目时,首先会读取<listener>
节点和<context-param>
节点。
2、创建一个ServletContext(servlet上下文),这个web项目的所有部分都共享这个上下文。
3、容器将<context-param>
转换键值对,并交给servletContext。
4、容器将创建<listener>
中的类实例,创建监听。
web.xml中,各个元素的加载顺序是一定的,与各元素即使在文件中顺序无关。
servletContext–context-param–listener–filter–servlet。
需要注意的是,同一元素的加载是按顺序加载的,例如filter与filter-mapping,必须先定义filter,才能正确解析对应名字的filter-mapping。
webAppRootKey
web项目配置webAppRootKey 获得根目录。
Spring通过 org.springframework.web.util.WebAppRootListener 这个监听器来压入项目路径。但是如果在web.xml中已经配置了 ch.qos.logback.ext.spring.web.LogbackConfigListener这个监听器,则不需要配置WebAppRootListener了。因为Log4jConfigListener已经包含了WebAppRootListener的功能。
contextConfigLocation
contextConfigLocation参数定义了需要装入spring的配置文件。
IntrospectorCleanupListener
在服务器运行过程中,Spring不停的运行的计划任务和OpenSessionInViewFilter,使得Tomcat反复加载对象而产生框架并用时可能产生的内存泄漏,则使用IntrospectorCleanupListener作为相应的解决办法。
spring中的提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器。它主要负责处理由 JavaBeans Introspector的使用而引起的缓冲泄露。spring中对它的描述如下:它是一个在web应用关闭的时候,清除JavaBeans Introspector的监听器.web.xml中注册这个listener.可以保证在web 应用关闭的时候释放与掉这个web 应用相关的class loader 和由它管理的类如果你使用了JavaBeans Introspector来分析应用中的类,Introspector 缓冲中会保留这些类的引用.结果在你的应用关闭的时候,这些类以及web 应用相关的class loader没有被垃圾回收.不幸的是,清除Introspector的唯一方式是刷新整个缓冲.这是因为我们没法判断哪些是属于你的应用的引用.所以删除被缓冲的introspection会导致把这台电脑上的所有应用的introspection都删掉.需要注意的是,spring 托管的bean不需要使用这个监听器.因为spring它自己的introspection所使用的缓冲在分析完一个类之后会被马上从javaBeans Introspector缓冲中清除掉.应用程序中的类从来不直接使用JavaBeans Introspector.所以他们一般不会导致内部查看资源泄露.但是一些类库和框架往往会产生这个问题。
CustomContextLoaderListener
这是我们项目自己实现的监听,由于项目采用dubbo框架,dubbo默认使用log4j作为日志输出,而我们项目是采用logback来输出日志。
因此通过监听,设置切换成slf4j。
public class CustomContextLoaderListener extends ContextLoaderListener { static{ //设置dubbo使用slf4j来记录日志 System.setProperty("dubbo.application.logger","slf4j"); }}
CharacterEncodingFilter
这是spring MVC提供的字符集过滤器,防止乱码。
shiroFilter
项目中用了shiro来管理权限,这里用了代理来注入spring bean,先filter中加入DelegatingFilterProxy类,”targetFilterLifecycle”指明作用于filter的所有生命周期。
原理是,DelegatingFilterProxy类是一个代理类,所有的请求都会首先发到这个filter代理,然后再按照”filter-name”委派到spring中的这个bean。
关于shiro,稍后再总结。
在Spring中配置的bean的name要和web.xml中的<filter-name>
一样,在项目中是这样配置的:
<!--shiro过滤器配置,bean的id值须与web中的filter-name的值相同--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login.htm"/> <property name="successUrl" value="/index.htm"/> <!-- 登陆成功之后跳转的页面 --> <property name="unauthorizedUrl" value="/unauthorized.htm"/> <property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> <entry key="concurrentlogin" value-ref="concurrentLoginControlFilter"/> </map> </property> <property name="filterChainDefinitions"> <value> /css/** = anon /js/** = anon /images/** = anon /commom/** = anon /unauthorized.htm = anon /login.htm=anon /sendLoginSmsCode.htm=anon /dologin.htm=anon /**/*.htm=authc,concurrentlogin </value> </property> </bean>
此外,spring bean实现了Filter接口,但默认情况下,是由spring容器来管理其生命周期的(不是由tomcat这种服务器容器来管理)。如果设置”targetFilterLifecycle”为True,则spring来管理Filter.init()和Filter.destroy();若为false,则这两个方法失效。
sessionFilter
用于检查用户是否登录了系统,如果未登录,则重定向到指的登录页面。
http://blog.csdn.net/buster2014/article/details/42082141
这里看了这篇文章,觉得我们的这个过滤器没有起作用。
AntiXssFilter
这是我们项目自己定义的校验html、sql特殊字符的过滤器。
核心代码:
/** * 判断是否包含html特殊字符 getIncludeHtmlSpecialCharsFlag */ public static boolean getIncludeHtmlSpecialCharsFlag(String s) throws UnsupportedEncodingException { boolean res = false; s = replaceSpecialChars(s); if ( // XSS黑名单 s.indexOf("javascript:") != -1 || s.indexOf("document.cookie") != -1 || s.indexOf("<script") != -1 || s.indexOf("<iframe") != -1 || s.indexOf("\"><script") != -1 || s.indexOf("<style") != -1 || s.indexOf("<img") != -1 || s.indexOf("onclick=") != -1 || s.indexOf("\"><style") != -1 || s.indexOf(")//") != -1 || s.indexOf("\">") != -1 || s.indexOf("<body") != -1 || s.indexOf("/xss/") != -1 || s.indexOf("onfocus") != -1 || s.indexOf("alert") != -1 // || s.indexOf(";") != -1 || s.indexOf("fromcharcode") != -1 || s.indexOf("eval") != -1 || s.indexOf("<a") != -1 || s.indexOf("cookie") != -1 || s.indexOf("document.write") != -1 || s.indexOf(">@import ") != -1) { res = true; } return res; } /** * 判断是否包含sql特殊字符 getIncludeSqlSpecialCharsFlag */ public static boolean getIncludeSqlSpecialCharsFlag(String str) { // 过滤掉的sql关键字,可以手动添加 String badStr = "'|and |exec |execute |insert |select |delete |update |count |trim|" + "char|declare|sitename|net user|xp_cmdshell|like |create |drop |" + "table |from |grant |use |group_concat|column_name|" + "information_schema.columns|table_schema|union |where |order |by |" + "chr|mid|master|truncate |or "; String[] badStrs = badStr.split("\\|"); for (int i = 0; i < badStrs.length; i++) { if (str.indexOf(badStrs[i]) >= 0) { return true; } } return false; }
load-on-startup
1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2)它的值必须是一个整数,表示servlet应该被载入的顺序
3)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
4)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
5)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
6)当值相同时,容器就会自己选择顺序来加载。
所以,<load-on-startup>x</load-on-startup>
,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。
- 项目架构分析-web.xml文件解读
- web.xml文件解读
- web.xml文件分析
- spring框架的web.xml文件解读
- 基于IntelliJ IDEA上创建Maven Spring MVC项目web.xml文件解读
- web项目修改xml文件
- Java web.xml配置解读与加载分析
- web.xml解读
- 慢慢解读web.xml
- web.xml解读
- Tomcat----解读web.xml
- 深度解读web.xml
- web.xml详细解读
- MVP架构-Android官方MVP项目和响应式MVP-RxJava项目架构分析对比解读
- MVP架构-Android官方MVP项目和响应式MVP-RxJava项目架构分析对比解读
- MVP架构-Android官方MVP项目和响应式MVP-RxJava项目架构分析对比解读
- AndroidManifest.xml文件解读
- AndroidManifest.xml文件解读
- 代码:GAT代管车辆(1)
- Wireshark 使用教程
- 架构设计:系统间通信(15)——服务治理与Dubbo 上篇
- 浅析Apache Spark Caching和Checkpointing
- Spring security实现权限管理
- 项目架构分析-web.xml文件解读
- Linux df du的区别
- IOS项目集成Weex
- [leetcode-二叉树后序遍历]--145. Binary Tree Postorder Traversal
- JS中call()和apply()的目的及用法
- display和visibility的用法区别
- 如何利用fleet单元文件为CoreOS集群创建高灵活性服务
- js计算两个日期相差天数
- window下安装redis cluster 集群