spring – 为嵌入式tomcat指定自定义web.xml

有没有办法在使用嵌入式tomcat实例时从标准WEB-INF / web.xml中指定不同的web.xml?

我想在我的src / test / resources(或其他一些区域)中放置一个web.xml,并在启动嵌入式tomcat时引用该web.xml.

这是我现有的启动tomcat实例的代码

tomcat = new Tomcat();
String baseDir = ".";
tomcat.setPort(8080);
tomcat.setBaseDir(baseDir);
tomcat.getHost().setAppBase(baseDir);
tomcat.getHost().setAutoDeploy(true);
tomcat.enableNaming();

Context ctx = tomcat.addWebApp(tomcat.getHost(),"/sandBox-web","src\\main\\webapp");
File configFile = new File("src\\main\\webapp\\meta-inf\\context.xml");
ctx.setConfigFile(configFile.toURI().toURL());

tomcat.start();

我从tomcat实例启动此服务器,我想在运行单元测试时执行以下操作

>关闭contextConfigLocation
>指定一个自定义ContextLoaderListener,用于设置嵌入式tomcat的父ApplicationContext.

可以像这样指定此文件

File webXmlFile = new File("src\\test\\resources\\embedded-web.xml");

编辑

经过多次挫折之后,我意识到无论我做什么,我都无法说服tomcat在WEB-INF中查找web.xml.看来我必须完全忽略web.xml并以编程方式在web.xml中设置项目.

我最终得到了这个配置:

用于配置测试的cucumber.xml

spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    Box.ApplicationContextProvider"/>

    BoxDataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close">
        sqldb.jdbcDriver" />
        sqldb:mem:testdb;shutdown=true;" />
        figuration -->
    figuration -->
    factorybean"
        lazy-init="true">
        Box" />    
        BoxDataSource" />
        vendorAdapter">
            vendor.HibernateJpavendorAdapter">
                sql_SERVER" />
                sql" value="true" />
                sspath:meta-inf/applicationContext-core.xml" />
    sspath:meta-inf/applicationContext-web.xml" />

applicationContext-core.xml – 配置服务的位置

spring-beans-3.2.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd"
    default-autowire="byName">

    figurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        sspath*:meta-inf/fms-local.properties" />
        stemPropertiesModeName">
            stem_PROPERTIES_MODE_OVERRIDEsspath scanning to load all the service classes
  -->
    required" isolation="DEFAULT"/>
        fig proxy-target-class="true">
        pointcut id="icosServiceMethods" expression="execution(* ca.statcan.icos..*.service.*.*(..))" />
        pointcut-ref="icosServiceMethods" />
    fig>

自定义ContextLoaderListener

public class EmbeddedContextLoaderListener extends ContextLoaderListener {

    @Override
    protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
        GenericWebApplicationContext context = new GenericWebApplicationContext(sc);
        context.setParent(ApplicationContextProvider.getApplicationContext());
        return context;
    }

    @Override
    protected ApplicationContext loadParentContext(ServletContext servletContext) {
        return ApplicationContextProvider.getApplicationContext();
    }
}

修改嵌入式Tomcat包装器

public class EmbeddedTomcat {
    /** Log4j logger for this class. */
    @SuppressWarnings("unused")
    private static final Logger LOG = LoggerFactory.getLogger(EmbeddedTomcat.class);

    private Tomcat tomcat;

    public void start() {
        try {
            tomcat = new Tomcat();
            String baseDir = ".";
            tomcat.setPort(8080);
            tomcat.setBaseDir(baseDir);
            tomcat.getHost().setAppBase(baseDir);
            tomcat.getHost().setDeployOnStartup(true);
            tomcat.getHost().setAutoDeploy(true);
            tomcat.enableNaming();

            Context context = tomcat.addContext("/sandBox-web","src\\main\\webapp");
            Tomcat.initWebappDefaults(context);
            configureSimulatedWebXml(context); 

            LOG.info("Starting tomcat in: " + new File(tomcat.getHost().getAppBase()).getAbsolutePath());

            tomcat.start();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
    }

    public void stop() {
        try {
            tomcat.stop();
            tomcat.destroy();
            FileUtils.deleteDirectory(new File("work"));
            FileUtils.deleteDirectory(new File("tomcat.8080"));
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void deploy(String appName) {
        tomcat.addWebapp(tomcat.getHost(),"/" + appName,"src\\main\\webapp");
    }

    public String getApplicationUrl(String appName) {
        return String.format("http://%s:%d/%s",tomcat.getHost().getName(),tomcat.getConnector().getLocalPort(),appName);
    }

    public boolean isRunning() {
        return tomcat != null;
    }

    private void configureSimulatedWebXml(final Context context) {
        // Programmatically configure the web.xml here

        context.setdisplayName("SandBox Web Application");

        context.addParameter("org.apache.tiles.impl.BasicTilesContainer.DEFinitioNS_CONfig","/WEB-INF/tiles-defs.xml,/WEB-INF/tiles-sandBox.xml");

        final FilterDef struts2Filter = new FilterDef();
        struts2Filter.setFilterName("struts2");
        struts2Filter.setFilterClass("org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter");
        struts2Filter.addInitParameter("actionPackages","ca.statcan.icos.sandBox.web");
        context.addFilterDef(struts2Filter);    

        final FilterMap struts2FilterMapping = new FilterMap();
        struts2FilterMapping.setFilterName("struts2");
        struts2FilterMapping.addURLPattern("/*");
        context.addFilterMap(struts2FilterMapping);

        context.addApplicationListener("org.apache.tiles.web.startup.TilesListener");
        context.addApplicationListener("ca.statcan.icos.sandBox.EmbeddedContextLoaderListener");

        context.addWelcomeFile("index.jsp");
    }
}

步骤定义

public class StepDefs {

    @Autowired
    protected EmployeeEntityService employeeEntityService;

    @Given("^the following divisions exist$")
    public void the_following_divisions_exist(DataTable arg1) throws Throwable {
        final Employee employee = new Employee(3,"Third","John",null,"613-222-2223");
        employeeEntityService.persistemployee(employee);
    }

    @Given("^there are no existing surveys$")
    public void there_are_no_existing_surveys() throws Throwable {
    }

    @When("^I register a new survey with the following information$")
    public void I_register_a_new_survey_with_the_following_information(DataTable arg1) throws Throwable {
        Capabilities capabilities = DesiredCapabilities.htmlUnit();
        final HtmlUnitDriver driver = new HtmlUnitDriver(capabilities);

        driver.get("http://localhost:8080/sandBox-web/myFirst");
    }

    @Then("^the surveys are created$")
    public void the_surveys_are_created() throws Throwable {
        // Express the Regexp above with the code you wish you had
        throw new PendingException();
    }

    @Then("^a confirmation message is displayed saying: \"([^\"]*)\"$")
    public void a_confirmation_message_is_displayed_saying(String arg1) throws Throwable {
        // Express the Regexp above with the code you wish you had
        throw new PendingException();
    }
}

动作类

@Results({ @Result(name = "success",location = "myFirst.page",type = "tiles") })
@ParentPackage("default")
@Breadcrumb(labelKey = "ca.statcan.icos.sandBox.firstAction")
@SuppressWarnings("serial")
public class MyFirstAction extends HappyfActionSupport {

    private Listirst","613-222-2222");
            employeeEntityService.persistemployee(employee1);

            final Employee employee2 = new Employee(2,"Second","613-222-2223");
            employeeEntityService.persistemployee(employee2);

            employees = employeeEntityService.getAllEmployee();
        }
        return SUCCESS;
    }

    public List

有了这个,嵌入式tomcat正确启动,似乎一切顺利,直到我尝试导航到一个网页.在StepDefs类中,正确注入EmployeeEntityService.但是,在Action类中,不会注入EmployeeEntityservice(它保持为null).

据我所知,我正在为嵌入式Tomcat正确设置父ApplicationContext.那么为什么服务器不使用父上下文来获取EmployeeEntityService呢?

最佳答案
我遇到了类似的问题,使用替代web.xml的解决方案比人们敢想的更简单:

2行:

Context webContext = tomcat.addWebapp("/yourcontextpath","/web/app/docroot/");
webContext.getServletContext().setAttribute(Globals.ALT_DD_ATTR,"/path/to/custom/web.xml");

瞧!魔术发生在org.apache.catalina.startup.ContextConfig#getWebXmlSource

免责声明:在Tomcat 7.0.42上测试

相关文章

这篇文章主要介绍了spring的事务传播属性REQUIRED_NESTED的原...
今天小编给大家分享的是一文解析spring中事务的传播机制,相...
这篇文章主要介绍了SpringCloudAlibaba和SpringCloud有什么区...
本篇文章和大家了解一下SpringCloud整合XXL-Job的几个步骤。...
本篇文章和大家了解一下Spring延迟初始化会遇到什么问题。有...
这篇文章主要介绍了怎么使用Spring提供的不同缓存注解实现缓...