有没有办法在使用嵌入式tomcat实例时从标准WEB-INF / web.xml中指定不同的web.xml?
我想在我的src / test / resources(或其他一些区域)中放置一个web.xml,并在启动嵌入式tomcat时引用该web.xml.
这是我现有的启动tomcat实例的代码
@H_404_9@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.
可以像这样指定此文件:
@H_404_9@File webXmlFile = new File("src\\test\\resources\\embedded-web.xml");
编辑
经过多次挫折之后,我意识到无论我做什么,我都无法说服tomcat在WEB-INF中查找web.xml.看来我必须完全忽略web.xml并以编程方式在web.xml中设置项目.
我最终得到了这个配置:
用于配置测试的cucumber.xml
@H_404_9@Box.ApplicationContextProvider"/>
BoxDataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource" destroy-method="close">
sqldb.jdbcDriver" />
sqldb:mem:testdb;shutdown=true;" />
factorybean"
lazy-init="true">
Box" />
BoxDataSource" />
sql_SERVER" />
sql" value="true" />
Meta-INF/applicationContext-core.xml" />
Meta-INF/applicationContext-web.xml" />
applicationContext-core.xml – 配置服务的位置
@H_404_9@Meta-INF/fms-local.properties" />
required" isolation="DEFAULT"/>
自定义ContextLoaderListener
@H_404_9@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包装器
@H_404_9@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");
}
}
步骤定义
@H_404_9@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();
}
}
动作类
@H_404_9@@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 List
有了这个,嵌入式tomcat正确启动,似乎一切顺利,直到我尝试导航到一个网页.在StepDefs类中,正确注入EmployeeEntityService.但是,在Action类中,不会注入EmployeeEntityservice(它保持为null).
据我所知,我正在为嵌入式Tomcat正确设置父ApplicationContext.那么为什么服务器不使用父上下文来获取EmployeeEntityService呢?
2行:
@H_404_9@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上测试