成绩查询系统--框架篇--配置文件--web.xml
2015-06-17 21:55
351 查看
上篇文章中,准备好了jar包,接下来就是写配置文件了.(说明一下,使用的IDE是eclipse,而建立的项目是动态web项目).其实不一定要准备好所有的jar,才开始写配置文件,如准备好hibernate的jar之后,就可以写hibernate的配置文件,并写测试代码,测试hibernate是否可用了.
这配置文件共4个,分别是,web.xml,spring-mvc.xml以及applicationContext.xml,hibernate.cfg.xml.一般是放在项目的WEB-INF文件中,比较安全.其中,web.xml中配置一些监听器和过滤器,在tomcat启动时,读取web.xml,再根据配置在web.xml的配置,去读取spring-mvc.xml,applicationContext.xml.
而applicationContext.xml是spring的配置文件,用来配置sessionFactory以及事务,这里用的是声明式事务.还有spring-mvc.xml配置的spring-mvc的,主要配置视图解析器,还有扫描包,设置注解驱动,以及配置解除mvc对资源的拦截.
现在依次介绍4个xml文件.
该配置文件,从上到下,依次配置了4个点,context-param上下文参数节点,listener监听器节点,servlet节点,和filter过滤节点.从比较简单的开始介绍.
filter过滤器节点,在这里是配置了一个编码的过滤器,将所有的(/*)的POST请求都拦截下来,强制设置为utf-8的编码,防止编码不一致的乱码,不过只对post请求起作用. 而这个编码的类,是spring-web自己就提供的一个类.
反编译出来的代码,我给添加了注释.看了源码之后,就更加明白,为什么要那么配置characterEncodingFilter了.
监听器节点也是用的spring-web中的一个类
反编译出来是这样的效果,本类中的代码,很少,基本上都是去调用父类中的方法.
下面是我从网上找到的,可能更方便理解.
Web.xml配置详解之context-param
context-param的作用是声明应用范围内的上下文初始化参数,范围是整个WEB项目。
初始化过程介绍:
1.在启动Web项目时,容器(比如Tomcat)会读web.xml配置文件中的两个节点<listener>和<contex-param>。
2.接着容器会创建一个ServletContext(上下文),应用范围内即整个WEB项目都能使用这个上下文。
3.接着容器会将读取到<context-param>转化为键值对,并交给ServletContext。
4.容器创建<listener></listener>中的类实例,即创建监听(备注:listener定义的类可以是自定义的类但必须需要继承ServletContextListener)。
5.在监听的类中会有一个contextInitialized(ServletContextEvent event)初始化方法,在这个方法中可以通过event.getServletContext().getInitParameter("contextConfigLocation")来得到context-param
设定的值。在这个类中还必须有一个contextDestroyed(ServletContextEvent event)销毁方法.用于关闭应用前释放资源,比如说数据库连接的关闭。
6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早。
7.由上面的初始化过程可知容器对于web.xml的加载过程是context-param>> listener >> fileter >> servlet.
所以根据上面的说法,这个上下文参数的配置的作用,就是将参数名为contextConfigLocation的,参数值为/WEB-INF/applicationContext.xml初始化到上下文参数中,并且该参数的作用范围为整个应用程序.
那段初始化的代码,是这样子的。
其实写完注释,我也没大懂,就只知道大概的东西.还有contextConfigLocation,是上下文的初始化参数.
DispatcherServlet是spring-webmvc下的一个类.
DispatcherServlet是前端控制器设计模式的实现,提供Spring
Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。
DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:
1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);
3、 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
4、通过ViewResolver解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。
从配置中可以看出,主要是拦截(/)所有请求,然后用DispatcherServlet进行职责调度.
在容器(Tomcat)启动时,启动自己配置的初始化参数/WEB-INF/spring-mvc.xml,/WEB-INF/applicationContext.xml作为初始化的上下文,而这个上下文的作用范围是只对spring
web mvc的bean有效,如controller.而在context-param的init-param的作用范围是整个应用程序共享的.
以上就是web.xml中的配置的一些解释,以前也没这么研究过,还是有很多不明白的,自己也没懂. 不过觉得看源码是很有用的.
这配置文件共4个,分别是,web.xml,spring-mvc.xml以及applicationContext.xml,hibernate.cfg.xml.一般是放在项目的WEB-INF文件中,比较安全.其中,web.xml中配置一些监听器和过滤器,在tomcat启动时,读取web.xml,再根据配置在web.xml的配置,去读取spring-mvc.xml,applicationContext.xml.
而applicationContext.xml是spring的配置文件,用来配置sessionFactory以及事务,这里用的是声明式事务.还有spring-mvc.xml配置的spring-mvc的,主要配置视图解析器,还有扫描包,设置注解驱动,以及配置解除mvc对资源的拦截.
现在依次介绍4个xml文件.
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"> <!-- 上下文初始化参数,找到spring的配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 找到spring-mvc的配置文件和spring的配置文件 --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-mvc.xml,/WEB-INF/applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 配置编码过滤器,防止乱码 --> <filter> <filter-name>characterEncodingFilter</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-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
该配置文件,从上到下,依次配置了4个点,context-param上下文参数节点,listener监听器节点,servlet节点,和filter过滤节点.从比较简单的开始介绍.
1.filter过滤器节点
<!-- 配置编码过滤器,防止乱码 --> <filter> <filter-name>characterEncodingFilter</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-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
filter过滤器节点,在这里是配置了一个编码的过滤器,将所有的(/*)的POST请求都拦截下来,强制设置为utf-8的编码,防止编码不一致的乱码,不过只对post请求起作用. 而这个编码的类,是spring-web自己就提供的一个类.
反编译出来的代码,我给添加了注释.看了源码之后,就更加明白,为什么要那么配置characterEncodingFilter了.
package org.springframework.web.filter; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CharacterEncodingFilter extends OncePerRequestFilter { //属性,接收编码和是否强制编码 private String encoding; private boolean forceEncoding = false; //设置编码 public void setEncoding(String encoding) { this.encoding = encoding; } //设置强制编码 public void setForceEncoding(boolean forceEncoding) { this.forceEncoding = forceEncoding; } protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //只要请求中设置了编码,或者只要设置了编码,并且强制编码为ture,就执行下面的 if ((this.encoding != null) && ((this.forceEncoding) || (request.getCharacterEncoding() == null))) { //请求就设置编码 request.setCharacterEncoding(this.encoding); //如果是强制编码 if (this.forceEncoding) { //则响应也设置编码 response.setCharacterEncoding(this.encoding); } } //到过滤器链的下一个过滤器 filterChain.doFilter(request, response); } }
2.listener
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
监听器节点也是用的spring-web中的一个类
反编译出来是这样的效果,本类中的代码,很少,基本上都是去调用父类中的方法.
package org.springframework.web.context; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; //ContextLoaderListener监听器,继承ContextLoader,实现了ServletContextListener的两个接口 //contextInitialized和contextDestroyed public class ContextLoaderListener extends ContextLoader implements ServletContextListener { //构造方式 public ContextLoaderListener() { } //带参数的构造方法,传递参数WebApplicationContext,web应用的上下文 public ContextLoaderListener(WebApplicationContext context) { super(context); } //上下文初始化 public void contextInitialized(ServletContextEvent event) { //调用父类的initWebApplicationContext,初始化web应用上下文方法 initWebApplicationContext(event.getServletContext()); } //销毁上下文 public void contextDestroyed(ServletContextEvent event) { //调用父类的关闭wen应用上下文 closeWebApplicationContext(event.getServletContext()); //以及另一个监听器的清除属性的方法 ContextCleanupListener.cleanupAttributes(event.getServletContext()); } }但是从代码中还是可以看出,主要功能就是接收到web应用中的上下文,将其初始化,或者销毁.而WebApplicationContext ,则是context-param中配置的,所以context-param和listener节点应该是配合使用的.
下面是我从网上找到的,可能更方便理解.
Web.xml配置详解之context-param
context-param的作用是声明应用范围内的上下文初始化参数,范围是整个WEB项目。
初始化过程介绍:
1.在启动Web项目时,容器(比如Tomcat)会读web.xml配置文件中的两个节点<listener>和<contex-param>。
2.接着容器会创建一个ServletContext(上下文),应用范围内即整个WEB项目都能使用这个上下文。
3.接着容器会将读取到<context-param>转化为键值对,并交给ServletContext。
4.容器创建<listener></listener>中的类实例,即创建监听(备注:listener定义的类可以是自定义的类但必须需要继承ServletContextListener)。
5.在监听的类中会有一个contextInitialized(ServletContextEvent event)初始化方法,在这个方法中可以通过event.getServletContext().getInitParameter("contextConfigLocation")来得到context-param
设定的值。在这个类中还必须有一个contextDestroyed(ServletContextEvent event)销毁方法.用于关闭应用前释放资源,比如说数据库连接的关闭。
6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早。
7.由上面的初始化过程可知容器对于web.xml的加载过程是context-param>> listener >> fileter >> servlet.
3.context-param节点
<!-- 上下文初始化参数,找到spring的配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param>
所以根据上面的说法,这个上下文参数的配置的作用,就是将参数名为contextConfigLocation的,参数值为/WEB-INF/applicationContext.xml初始化到上下文参数中,并且该参数的作用范围为整个应用程序.
那段初始化的代码,是这样子的。
public class ContextLoader { //感觉父类中没用上 public static final String CONTEXT_ID_PARAM = "contextId"; public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey"; private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties"; private static final Properties defaultStrategies; //这个是map private static final Map<ClassLoader, WebApplicationContext> currentContextPerThread = new ConcurrentHashMap(1); //这个是多线程时的web应用上下文,具体不懂 private static volatile WebApplicationContext currentContext; //initWebApplicationContext方法,就是在给这个属性,赋值; private WebApplicationContext context; private BeanFactoryReference parentContextRef; public ContextLoader() { } public ContextLoader(WebApplicationContext context) { this.context = context; } //初始化web应用上下文,根据servlet上下文 public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { //如果上下文中"根web应用上下文属性"不为空,则抛错 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!"); } //记录日志 Log logger = LogFactory.getLog(ContextLoader.class); servletContext.log("Initializing Spring root WebApplicationContext"); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); } //记录当前时间,用来放在日志中,记录时间 long startTime = System.currentTimeMillis(); //作用,给context(web应用上下文)赋上值 try { //如果web应用上下文属性为空,就创建一个web应用上下文 if (this.context == null) { this.context = createWebApplicationContext(servletContext); } //如果是可配置的web应用上下文类型的 if ((this.context instanceof ConfigurableWebApplicationContext)) { //就强转成可配置的web应用上下文类型 ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context; //判断若不是活动状态的 if (!cwac.isActive()) { //并且可配置的web应用上下文的parent属性是空的 if (cwac.getParent() == null) { //加载父上下文,应用上下文 ApplicationContext parent = loadParentContext(servletContext); //并且给可配置的web应用上下文的parent属性赋上值 cwac.setParent(parent); } //然后配置并且刷新一下web应用上下文,根据可配置的web应用上下文和servlet上下文 configureAndRefreshWebApplicationContext(cwac, servletContext); } } //给servlet上下文的"根web应用上下文属性"设置值,值就是context servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); //从当前线程中获取类加载器 ClassLoader ccl = Thread.currentThread().getContextClassLoader(); //若该类加载和上下文加载器的类加载器是一样的 if (ccl == ContextLoader.class.getClassLoader()) { //就将web应用上下文,给当前上下文 currentContext = this.context; } //若当前线程中,没有类加载器, else if (ccl != null) { //则将类加载器和web应用上下文,作为key,value放到当前上下文之前的线程的map中 currentContextPerThread.put(ccl, this.context); } //记录bug级别的日志 if (logger.isDebugEnabled()) { logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); } //记录info级别的日志,并记录时间 if (logger.isInfoEnabled()k) { long elapsedTime = System.currentTimeMillis() - startTime; logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); } //该初始化的方法,最后会返回准备好的web应用上下文context return this.context; } catch (RuntimeException ex) { //出错的话,就记录下来 logger.error("Context initialization failed", ex); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); throw ex; } catch (Error err) { //出错的话,就记录下来 logger.error("Context initialization failed", err); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err); throw err; } } //配置并刷新web应用上下文 protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { //获取servlet上下文中的初始化参数contextId String idParam = sc.getInitParameter("contextId"); //不为null的话,这就是可配置的web应用上下文对象的id了 if (idParam != null) { wac.setId(idParam); } else { //否则,就用路径来做id wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc .getContextPath())); } } //设置可配置的web应用上下文对象的servletContext wac.setServletContext(sc); //获取servlet上下文中的初始化参数contextConfigLocation,这个就是xml中配置的 String configLocationParam = sc.getInitParameter("contextConfigLocation"); //有值的话,这就是可配置的web应用上下文对象的ConfigLocation了 if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); } //获取可配置环境 ConfigurableEnvironment env = wac.getEnvironment(); //初始化属性资源 if ((env instanceof ConfigurableWebEnvironment)) { ((ConfigurableWebEnvironment)env).initPropertySources(sc, null); } customizeContext(sc, wac); //可配置的web应用上下文对象,刷新一下 wac.refresh(); } //其他代码都省略 }
其实写完注释,我也没大懂,就只知道大概的东西.还有contextConfigLocation,是上下文的初始化参数.
4.servlet节点
<!-- 找到spring-mvc的配置文件和spring的配置文件 --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-mvc.xml,/WEB-INF/applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>在servlet节点中配置了servlet-name为action,其实改为springmvc会更好理解,action是struts中的,而我们的框架是springmvc.
DispatcherServlet是spring-webmvc下的一个类.
DispatcherServlet是前端控制器设计模式的实现,提供Spring
Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。
DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:
1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);
3、 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
4、通过ViewResolver解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。
从配置中可以看出,主要是拦截(/)所有请求,然后用DispatcherServlet进行职责调度.
在容器(Tomcat)启动时,启动自己配置的初始化参数/WEB-INF/spring-mvc.xml,/WEB-INF/applicationContext.xml作为初始化的上下文,而这个上下文的作用范围是只对spring
web mvc的bean有效,如controller.而在context-param的init-param的作用范围是整个应用程序共享的.
以上就是web.xml中的配置的一些解释,以前也没这么研究过,还是有很多不明白的,自己也没懂. 不过觉得看源码是很有用的.
相关文章推荐
- I/O ACTIONS
- Linux 命令 wget
- Android开机广播android.intent.action.BOOT_COMPLETED
- poj 1141 Brackets Sequence(区间dp)
- 关于vs2010 error: LNK1123: failure during conversion to COFF: file invalid or corrupt 错误的解决...
- chrome内核浏览器缓存资源找回方法
- 一级二级域名设置测试txt记录(spf记录)pass
- 黑马程序员------File及IO流
- awk应用-支票簿的结算
- java tcp
- 第二次冲刺——第3天
- 易买网之smartupload实现文件上传
- Apache Phoenix开发实践(1)
- centos7设置IP
- 第二次冲刺——第2天
- 黑马程序员------内部类
- 推荐系统笔记
- 2015061704 - 方法返回值状态码
- HBase简述
- Spring 总结