如何通过properties文件配置web.xml中的参数

目录
  • 前言
  • 实现思路
    • web.xml中需要修改的部分
    • filter.properties文件
    • PropUtils工具类
    • 查看web.xml参数
  • 启动服务器进行测试
    • web.xml

前言

因为公司项目需要,目前有本地环境、测试环境、开发环境。每次在将项目打包成war包的时候,都需要修改多处的配置,而使用maven的profile打包项目的时候,可以根据执行打包命令时所带的参数来进行自动修改。

但是这种方式只对properties文件生效,即可以自动修改properties中的参数,但是公司的项目有一个web.xml中的配置参数也需要修改,这时候就要考虑如何通过properties文件动态修改web.xml中的参数了。

实现思路

web.xml中需要修改的部分

<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_3_0.xsd"
    version="3.0" metadata-complete="true">
    <!--用maven创建的web-app需要修改servlet的版本为3.1 -->
    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
    <!--配置DispatcherServlet -->
    <servlet>
        <servlet-name>mypage-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置SpringMVC 需要配置的文件 spring-dao.xml,spring-service.xml,spring-web.xml
            Mybites -> spring -> springMvc -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-*.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mypage-dispatcher</servlet-name>
        <!--默认匹配所有请求 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>testFilter</filter-name>
        <filter-class>com.solr.filter.StringFilter</filter-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>
            com.sgm.tac.tid.common.action;
            </param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>testFilter</filter-name>
        <url-pattern>*.*</url-pattern>
    </filter-mapping>
</web-app>

这里需要改动的是45行,这是过滤器的初始化参数。不同的环境这里的参数是不一样的,开始的思路是能否像application.xml中加载的properties文件一样,通过${username}这种方式获取properties中username对应的value。但是后来发现在web.xml中貌似是不好实现的。

在这样的需求下,web.xml就需要以编码的方式来实现配置。spring4.0以上的版本支持web.xml的编码配置。实现AbstractAnnotationConfigDispatcherServletInitializer接口,在servlet3.0中web.xml启动时会检测该接口实现类,从能够在实现类中去配置filter。

需要注意的是以上的实现,依赖servlet-api-3.0.jar和spring-webmvc-4.0以上版本jar包。

配置web.xml的类

package com.solr.filter;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.solr.util.PropUtils;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
         // 系统启动时注册filter
        FilterRegistration testFilter = servletContext.addFilter("testFilter", StringFilter.class);
        // 设置init param, param可以从properties文件中读取或其他方式获取,提供一个想法
        testFilter.setInitParameter("jersey.config.server.provider.packages", PropUtils.getValueByKey("FILTER.NAME"));
        testFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class) , true, "*.*");
        super.onStartup(servletContext);
    }
    @Override
    protected Dynamic registerServletFilter(ServletContext servletContext, Filter filter) {
        // TODO Auto-generated method stub
        return super.registerServletFilter(servletContext, filter);
    }
}

在继承AbstractAnnotationConfigDispatcherServletInitializer的时候onStartup和registerServletFilter两个方法没有自动添加进来,需要自己手动override。

其中onStartup在服务器启动的时候会根据配置修改web.xml,此处通过addFilter添加了一个叫做testFilter的过滤器,通过setInitParameter向过滤器中设置参数。而这里PropUtils是自己写的一个读取properties文件的工具类,这样就实现了将properties中的值动态添加到web.xml中了,最后打包修改properties的时候就可以修改web.xml了。

filter.properties文件

FILTER.NAME=HHH

PropUtils工具类

此工具类使用ResourceBundle读取properties文件,此工具类是java.util中的方法,其中还有一些stringUtils的方法,用来判断字符串是否为空,将字符串转换成大写等功能,就不写在上面了。

package com.solr.util;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.log4j.Logger;
public class PropUtils {
    private static final String URL_RESOURCE_FILE_PATH = "props/filter";
    private static final Logger LOG = Logger.getLogger(PropUtils.class);
    private static final ResourceBundle rb = ResourceBundle.getBundle(URL_RESOURCE_FILE_PATH, Locale.getDefault(),PropUtils.class.getClassLoader());
    /**
     * @param key 对应properties内的key
     * @return properties对应字符串
     */
    public static String getValueByKey(String key){
        return getValueByKey(key,null);
    }
    /**
     * @param key 对应properties内的key
     * @param param 参数下标0开始依次排列
     * @return properties内填入对应参数的字符串
     */
    public static String getValueByKey(String key,Object [] param){
        String value = "";
        try {
            value = rb.getString(StringUtils.toUpper(key));
        } catch (Exception e) {
            LOG.info(e,e);
        }
        if (StringUtils.isBlank(value)){
            return key;
        }
        String strReturn = "";
        if (param == null || param.length == 0){
            strReturn = MessageFormat.format(value, param);
        }else {
            strReturn = value;
        }
        return strReturn.trim();
    }
}

查看web.xml参数

在启动服务器的时候,会对过滤器进行初始化,我们可以在初始化的时候查看刚才配置的web.xml是否成功。

package com.solr.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class StringFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("init");
        Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
            String param = (String) initParameterNames.nextElement();
            System.out.println(param + ":" + filterConfig.getInitParameter(param));
        }
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        System.out.println("dofilter");
    }
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("destroy");
    }
}

启动服务器进行测试

启动服务器的时候报错了:

八月 17, 2018 2:48:27 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1241)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:300)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:444)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:758)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:705)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1702)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1692)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1249)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:819)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    ... 6 more

错误的意思大概是加载组件遇到了问题。这个问题是在想通过编码的方式来实现配置web.xml的时候出现的,即在之前是没有遇到这个问题的,实现继承AbstractAnnotationConfigDispatcherServletInitializer,并向web.xml中添加过滤器的时候遇到此问题的。

最终原因是通过编码添加的过滤器名称为testFilter,而web.xml中原先就有这个名称的过滤器,两个过滤器名称冲突,造成服务器启动失败。

解决方式:删除web.xml中原先的过滤器配置,通过编码添加此过滤器。

web.xml

<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_3_0.xsd"
    version="3.0" metadata-complete="true">
    <!--用maven创建的web-app需要修改servlet的版本为3.1 -->
    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
    <!--配置DispatcherServlet -->
    <servlet>
        <servlet-name>mypage-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置SpringMVC 需要配置的文件 spring-dao.xml,spring-service.xml,spring-web.xml
            Mybites -> spring -> springMvc -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-*.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mypage-dispatcher</servlet-name>
        <!--默认匹配所有请求 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • JavaWeb工程web.xml基本配置过程解析

    这篇文章主要介绍了JavaWeb工程web.xml基本配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.理论准备 先说下我记得xml规则,必须有且只有一个根节点,大小写敏感,标签不嵌套,必须配对. web.xml是不是必须的呢?不是的,只要你不用到里面的配置信息就好了,不过在大型web工程下使用该文件是很方便的,若是没有也会很复杂. 那么web.xml能做的所有事情都有那些?其实,web.xml的模式(Schema)文件中定义了多

  • Java开发中读取XML与properties配置文件的方法

    相关阅读: 使用Ajax进行文件与其他参数的上传功能(java开发) 1. XML文件: 什么是XML?XML一般是指可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. 2.XML文件的优点: 1)XML文档内容和结构完全分离. 2)互操作性强. 3)规范统一. 4)支持多种编码. 5)可扩展性强. 3.如何解析XML文档: XML在不同的语言中解析XML文档都是一样的,只不过实现的语法不一样,基本的解析方式有两种,一种是SAX方式,是按照XML文件的顺序一

  • 详解SpringMVC加载配置Properties文件的几种方式

    最近开发的项目使用了SpringMVC的框架,用下来感觉SpringMVC的代码实现的非常优雅,功能也非常强大, 网上介绍Controller参数绑定.URL映射的文章都很多了,写这篇博客主要总结一下SpringMVC加载配置Properties文件的几种方式 1.通过context:property-placeholde实现配置文件加载 1.1.在spring.xml中加入context相关引用 <?xml version="1.0" encoding="UTF-8&

  • JavaWeb读取配置文件的四种方法

    方式一:采用ServletContext读取 获取配置文件的realpath,然后通过文件流读取出来或者通过方法getReasurceAsStream(). 因为是用ServletContext读取文件路径,所以配置文件可以放入在WEB-INF的classes目录中,也可以在应用层级及WEB-INF的目录中.文件存放位置具体在eclipse工程中的表现是:可以放在src下面,也可放在WEB-INF及Web-Root下面等.因为是读取出路径后,用文件流进行读取的,所以可以读取任意的配置文件包括xm

  • 如何通过properties文件配置web.xml中的参数

    目录 前言 实现思路 web.xml中需要修改的部分 filter.properties文件 PropUtils工具类 查看web.xml参数 启动服务器进行测试 web.xml 前言 因为公司项目需要,目前有本地环境.测试环境.开发环境.每次在将项目打包成war包的时候,都需要修改多处的配置,而使用maven的profile打包项目的时候,可以根据执行打包命令时所带的参数来进行自动修改. 但是这种方式只对properties文件生效,即可以自动修改properties中的参数,但是公司的项目有

  • SpringMVC xml文件路径在web.xml中的配置方式

    目录 SpringMVC xml文件路径在web.xml中的配置 SpringMVC 修改配置文件路径 1.1.Classpath 1.2.Classpath* 1.3.Classpath是什么 1.4.Classpath和classpath*的区别 SpringMVC xml文件路径在web.xml中的配置 正常情况下springmvc的xml文件应放在WEB-INF下,命名规则为[name]-servlet.xml, "-servlet"这个字段是必不可少的 [name]你可以随便

  • 基于springMVC web.xml中的配置加载顺序

    目录 springMVC web.xml中的配置加载顺序 1.Spring上下文环境的配置文件 2.SpringMVC配置文件 加载顺序是 web.xml加载顺序及Spring包扫描注意 1.web.xml文件中配置文件加载顺序 2.SpringMVC配置事务管理时 springMVC web.xml中的配置加载顺序 在这里就不详细说web.xml的文件中的具体配置,就简单说明一下其中配置信息的加载顺序: 在web.xml文件中元素的加载顺序与它们在 web.xml 文件中的先后顺序无关. 加载

  • Spring在web.xml中的配置详细介绍

    Spring在web.xml中的配置详细介绍 前言      在实际项目中spring的配置文件applicationcontext.xml是通过spring提供的加载机制自动加载到容器中.在web项目中,配置文件加载到web容器中进行解析.目前,spring提供了两种加载器,以供web容器的加载:一种是ContextLoaderListener,另一种是ContextLoaderServlet.这两种在功能上完全相同,只是前一种是基于Servlet2.3版本中新引入的Listener接口实现,

  • web.xml中Maven占位符不生效问题记录分析

    目录 问题背景 问题分析 Resources插件有三个目标: 问题定位 问题解决 问题背景 开发反馈,一个spring mvc的web项目,在web.xml配置的占位符不生效,编译后还是没有替换成配置的属性,如下: <context-param> <param-name>logbackConfigLocation</param-name> <param-value>classpath:${loagback.xml.path:logback.xml}</

  • web.xml中如何设置配置文件的加载路径实例详解

    web.xml中如何设置配置文件的加载路径实例详解 web应用程序通过Tomcat等容器启动时,会首先加载web.xml文件,通常我们工程中的各种配置文件,如日志.数据库.spring的文件等都在此时被加载,下面是两种常用的配置文件加载路径,即配置文件可以放到 SRC目录下或者可以放到WEB-INF根目录下 第一种在web.xml中这样配置: <context-param> <param-name >contextConfigLocation </param-name >

  • web.xml中servlet, bean, filter, listenr 加载顺序_动力节点Java学院整理

    web.xml 文件中一般包括 servlet, spring, filter, listenr的配置.那么他们是按照一个什么顺序加载呢?加载顺序会影响对spring bean 的调用. 比如filter需要用到 bean ,但是加载顺序是 先加载filter 后加载spring,则filter中初始化操作中的bean为null:首先可以肯定 加载顺序与他们在web.xml 文件中的先后顺序无关. web.xml 中 listener 和 serverlet 的加载顺序为 先 listener

  • IDEA创建Servlet并配置web.xml的实现

    module与project区别 IntelliJ IDEA 中,project相当于eclipse的WorkSpace,module相当于eclipse的project: IntelliJ中一个 Project  可以包括多个  Module : Eclipse中一个 Workspace  可以包括多个  Project.  创建module 创建一个 module 选择Java项目 输入项目名称,选择存储空间,点击 finish 完成创建 添加框架 选中创建的module,右键选择Add F

  • JSP取得在WEB.XML中定义的参数

    在WEB.XML文件中设置参数: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> &

  • 解析web.xml中在Servlet中获取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>  </contex

随机推荐