一个项目中的Web.xml解读

贴了一个项目中的web.xml源码进行解说,增加对自己开发项目的理解,本人有一个毛病,就是自己做的事情就是喜欢无死角,所以这么个小东西也拿来扣一扣,有的地方没有扣全的欢迎补充。

 <?xml version="1.0" encoding="UTF-8"?>   <!--  标识为xml文件,并定义文件编码为UTF-8 -->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"   
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <!-- 获取命名空间XMLSchema-instance和javaee,获取模式地址,xsd:xml schema definition language。版本号3.0 -->
  <description>sell-mgmt</description>   <!-- 描述,无实际意义 -->
  <filter>  <!-- 配置拦截器1:编码拦截器,定义拦截器名,对应拦截器类,并初始化类中的encoding与forceEncoding两个成员变量属性 -->
    <filter-name>encodingFilter</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>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>    <!-- 配置拦截器2:SQL注入拦截器,为拦截器类注入初始化参数:invalidsql数组、error页面与是否debug -->
    <filter-name>PreventSqlInject</filter-name>
    <filter-class>com.sell.modules.platform.utils.filter.SqlInjectFilter</filter-class>
    <init-param>
      <param-name>invalidsql</param-name>
      <param-value>select insert delete from update create where union destory drop alter and or like exec count
                chr mid master truncate char declare ; - ' % | $ % @ &quot; + cr lf , . script document eval
            </param-value>
    </init-param>
    <init-param>
      <param-name>error</param-name>
      <param-value>/sqlerrors.shtml</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>false</param-value>
    </init-param>
  </filter>
  <filter-mapping>   <!-- 拦截器请求映射,所有匹配*.sql的请求将会被这个拦截器拦截 -->
    <filter-name>PreventSqlInject</filter-name>
    <url-pattern>*.sql</url-pattern>
  </filter-mapping>
  
  <!-- 防XSS跨站脚本攻击的拦截器 -->
  <filter>
    <filter-name>XSSFilter</filter-name>
    <filter-class>com.sell.modules.platform.utils.filter.XssFilter</filter-class>
  </filter>
  <filter-mapping>
	 <filter-name>XSSFilter</filter-name>
	 <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- druid拦截器 -->
  <filter>    <!-- 配置druid拦截器 -->
    <filter-name>DruidWebStatFilter</filter-name>
    <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
    <init-param>
      <!-- 经常需要排除一些不必要的url,比如.js,/jslib/等等。配置在init-param中 -->
      <param-name>exclusions</param-name>
      <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
    </init-param>
    <!-- 缺省sessionStatMaxCount是1000个。你可以按需要进行配置 -->
    <init-param>
      <param-name>sessionStatMaxCount</param-name>
      <param-value>1000</param-value>
    </init-param>
    <!-- druid 0.2.7版本开始支持profile,配置profileEnable能够监控单个url调用的sql列表 -->
    <init-param>
      <param-name>profileEnable</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>principalSessionName</param-name>
      <param-value>users.username</param-value>
    </init-param>
    <!-- 你可以关闭session统计功能
    <init-param>
        <param-name>sessionStatEnable</param-name>
        <param-value>true</param-value>
    </init-param> -->
  </filter>
  <filter-mapping>
    <filter-name>DruidWebStatFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <servlet>    <!-- 声明spring的DispatcherServlet(分配程序) -->
    <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- init-param的作用详见注释3 -->
    <!-- 初始化配置文件,使用文件地址定位文件,sell-servlet.xml(看下面的另一个配置)配置了一个json转换器,当使用@responsbody注解时返回值会自动转成json格式 -->
    <init-param>      
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:etc/sell-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>      <!-- 决定了Servlet的加载顺序,详见注释1 -->
  </servlet>
  <context-param>     <!-- 配置默认的环境为开发环境 --><!-- context-param的作用详见注释2 -->
    <param-name>spring.profiles.defualt</param-name>
    <param-value>development</param-value>
  </context-param>
  <servlet-mapping>     <!-- 配置spring分配程映射的url -->
    <servlet-name>springServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <context-param>     <!-- 加载配置文件applicationContext.xml,这样可以读取spring容器中配置的bean与其他applicationContext.xml中的配置 -->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:etc/applicationContext.xml</param-value>
  </context-param>
  <context-param>     <!-- 多环境配置文件激活属性,配置为生产,tomcat启动时自动加载对应的信息,目前没有看到有什么地方用到 -->
    <param-name>spring.profiles.active</param-name>
    <param-value>production</param-value>
  </context-param>
  <!-- 配置监听器,ContextLoaderListener它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法 -->
  <listener>      
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <context-param>     <!-- 定义logback日志配置文件地址 -->
    <param-name>logbackConfigLocation</param-name>
    <param-value>classpath:log/logback.xml</param-value>
  </context-param>
  <listener>      <!-- tomcat启动时会加载logback配置文件的配置 -->
    <listener-class>com.sell.modules.platform.log.LogbackConfigListener</listener-class>
  </listener>
  
  <servlet>     <!-- 加载一个自定义的Servlet,类的源码可以看下面的代码块 -->
    <servlet-name>InitSystemServlet</servlet-name>
    <servlet-class>com.sell.framework.base.InitSystemServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
  </servlet>

  <filter>      <!-- 加载shiro的filter,用于shiro的权限管理 -->
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
      <param-name>targetFilterLifecycle</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <mime-mapping>      <!-- mime-mapping用来指定对应的格式的浏览器处理方式,具体参考注释4 -->
    <extension>ico</extension>
    <mime-type>image/x-icon</mime-type>
  </mime-mapping>

  <servlet>     <!-- 配置druid的servlet,拦截druid自己的URL -->
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
  </servlet-mapping>

  <servlet>     <!-- 配置kaptcha的servlet,把验证码放到session里,并把验证码生成图片返回 -->
    <servlet-name>kaptcha</servlet-name>
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>kaptcha</servlet-name>
    <url-pattern>/static/images/kaptcha.jpg</url-pattern>
  </servlet-mapping>
  
  <!-- 自动化发布检查服务是否启动-->
	<servlet>      <!-- 用于处理自动化发布时处理/checkServer请求,如果启动成功将会返回一个200状态给自动化的发布程序 -->
		<servlet-name>checkServerServlet</servlet-name>
		<servlet-class>com.sell.modules.platform.controller.CheckServer</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>checkServerServlet</servlet-name>
		<url-pattern>/checkServer</url-pattern>
	</servlet-mapping>
  
  <!-- 配置session相关,这里配了一个超时时间30分钟 -->
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>

  <!-- 处理服务器端异常,返回对应的错误页面 -->
  <error-page>
    <error-code>404</error-code>
    <location>/404.shtml</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/500.shtml</location>
  </error-page>

  <!-- 在web项目中,当用户在浏览器中输入的URL不包含某个特定的Servlet、html、jsp页面时,web.xml中<welcome-file-list>标签元素就会指定显示的默认文件。 -->
  <welcome-file-list>
    <welcome-file>/login</welcome-file>
  </welcome-file-list>

  <!-- 配置jsp的taglib,加载这个配置时会加载<taglib-location>下的文件,在jsp中可以使用<taglib-uri>访问此文件。-->
  <!-- <jsp-config> 包括 <taglib> 和 <jsp-property-group> 两个子元素,具体参考连接http://janwer.iteye.com/blog/150217/ -->
  <jsp-config>    
    <taglib>    
        <taglib-uri>http://www.sellmgmt.com/functions</taglib-uri>    
        <taglib-location>/static/jstl/myJstl.tld</taglib-location>    
    </taglib>    
  </jsp-config>  
</web-app>

注释1:配置Servlet时< load-on-startup>标签有什么用?

贴一段英文原汁原味的解释如下:
Servlet specification:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.

翻译过来的意思大致如下:

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代表的是优先级,而非启动延迟时间。

注释2:< context-param>的作用:

web.xml的配置中< context-param>配置作用

  1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: < listener>< /listener> 和 < context-param>< /context-param>
  2. 紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文.
  3. 容器将< context-param>< /context-param>转化为键值对,并交给ServletContext.
  4. 容器创建< listener>< /listener>中的类实例,即创建监听.
  5. 在监听中会有contextInitialized(ServletContextEvent args)初始化方法,在这个方法中获得ServletContext = ServletContextEvent.getServletContext();
    context-param的值 = ServletContext.getInitParameter(“context-param的键”);
  6. 得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.
    换句话说,这个时候,你对< context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行.
  7. 举例.你可能想在项目启动之前就打开数据库.
    那么这里就可以在< context-param>中设置数据库的连接方式,在监听类中初始化数据库的连接.
  8. 这个监听是自己写的一个类,除了初始化方法,它还有销毁方法.用于关闭应用前释放资源.比如说数据库连接的关闭.

注释3:context-param和init-param区别

web.xml里面可以定义两种参数:
(1)application范围内的参数,存放在servletcontext中,在web.xml中配置如下:

 <context-param>
           <param-name>context/param</param-name>
           <param-value>avalible during application</param-value>
</context-param>

(2)servlet范围内的参数,只能在servlet的init()方法中取得,在web.xml中配置如下:

<servlet>
    <servlet-name>MainServlet</servlet-name>
    <servlet-class>com.wes.controller.MainServlet</servlet-class>
    <init-param>
       <param-name>param1</param-name>
       <param-value>avalible in servlet init()</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

在servlet中可以通过代码分别取用:

package com.wes.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class MainServlet extends HttpServlet ...{
    public MainServlet() ...{
        super();
     }
    public void init() throws ServletException ...{
         System.out.println("下面的两个参数param1是在servlet中存放的");
         System.out.println(this.getInitParameter("param1"));
         System.out.println("下面的参数是存放在servletcontext中的");
        System.out.println(getServletContext().getInitParameter("context/param"));
      }
}

context-param参数在servlet里面可以通过getServletContext().getInitParameter(“context/param”)得到
init-param参数只能在servlet的init()方法中通过this.getInitParameter(“param1”)取得.

注释4:< mime-mapping>作用

我们用浏览器打开文件的时候会发现如果是doc文件, 会用记事本打开,出现乱码, 但是如果在web.xml里面配置了类型,浏览器就会根据配置的类型自动调用相应的程序打开,避免直接使用浏览器打开出现错误。如下:

<mime-mapping>  
    <extension>doc</extension>  
    <mime-type>application/vnd.ms-word</mime-type>  
</mime-mapping> 

最后,附上web.xml中使用的filter类与配置的源码
防止sql注入的SqlInjectFilter :

package com.sell.modules.platform.utils.filter;

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SqlInjectFilter implements Filter {
    private static List<String> invalidsql = new ArrayList<String>();
    private static String error = "/sqlerrors.jsp";
    private static boolean debug = false;

    public void destroy() {

    }

    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain fc) throws IOException, ServletException {
        //防sql关键字注入
        if (debug) {
            System.out.println("prevent sql inject filter works");
        }
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        Map<String, String[]> params = request.getParameterMap();
        Set<String> keys = params.keySet();
        for (String key : keys) {
            String value = request.getParameter(key);
            if (debug) {
                System.out.println("process params <key, value>: <" + key + ", " + value + ">");
            }
            for (String word : invalidsql) {
                if (word.equalsIgnoreCase(value) || value.contains(word)) {
                    if (value.contains("<")) {
                        value = value.replace("<", "<");
                    }
                    if (value.contains(">")) {
                        value = value.replace(">", ">");
                    }
                    if (value.contains("(")) {
                        value = value.replace("(", "(");
                    }
                    if (value.contains(")")) {
                        value = value.replace(")", ")");
                    }
                    request.getSession().setAttribute("sqlInjectError", "您输入的参数值  \"" + value + "\" 中包含关键字: \"" + word + "\"");
                    response.sendRedirect(request.getContextPath() + error);
                    return;
                }
            }
        }
        fc.doFilter(req, res);
    }

    public void init(FilterConfig conf) throws ServletException {
        String sql = conf.getInitParameter("invalidsql");
        String errorpage = conf.getInitParameter("error");
        String de = conf.getInitParameter("debug");
        if (errorpage != null) {
            error = errorpage;
        }
        if (sql != null) {
            //invalidsql = Arrays.asList(sql.split(" "));
            String[] sqlarr = sql.split(" ");
            for (String sqlword : sqlarr) {
                invalidsql.add(sqlword);
            }
            invalidsql.add("<");
            invalidsql.add(">");
            invalidsql.add("(");
            invalidsql.add(")");
        }
        if (de != null && Boolean.parseBoolean(de)) {
            debug = true;
            System.out.println("PreventSQLInject Filter staring...");
            System.out.println("print filter details");
            System.out.println("invalid words as fllows (split with blank):");
            for (String s : invalidsql) {
                System.out.print(s + " ");
            }
            System.out.println();
            System.out.println("error page as fllows");
            System.out.println(error);
            System.out.println();
        }
    }
}

防止xss跨站攻击的XssFilter:

package com.sell.modules.platform.utils.filter;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;


public class XssFilter implements Filter {
    FilterConfig filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    public void destroy() {
        this.filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
    }
}

sell-servlet.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>text/plain;charset=UTF-8</value>
            </list>
        </property>
    </bean> 
</beans>

logback的listener:

package com.sell.modules.platform.log;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class LogbackConfigListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
        LogbackWebConfigurer.initLogging(event.getServletContext());
    }

    public void contextDestroyed(ServletContextEvent event) {
        LogbackWebConfigurer.shutdownLogging(event.getServletContext());
    }
}

初始化关键字的InitSystemServlet:

package com.asset.framework.base;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
 * 初始化web系统环境
 */
public class InitSystemServlet extends HttpServlet {

    /**
     * 序列号
     */
    private static final long serialVersionUID = 1L;
   // private static Log logger = LogFactory.getLog(InitSystemServlet.class);

    @Override
    public void init() throws ServletException {
       // String webRealPath = getServletContext().getRealPath("/");
        //ConfigHelper helper = ConfigHelper.getInstance(webRealPath);
        // 加载关键字初始化缓存
        // KeywordFilter keywordFilter = new KeywordFilter();
        // keywordFilter.init();
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值