【问题标题】:Embedded jetty for automated tests用于自动化测试的嵌入式码头
【发布时间】:2013-12-16 08:24:23
【问题描述】:

我正在尝试使用嵌入式码头对 Web 服务进行自动化测试。但是,当我尝试访问该服务时,我不断收到错误 404。

这是我的 src/main/webapp/WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Snafucator</display-name>

<session-config>
    <session-timeout>60</session-timeout>
</session-config>

<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>Snafucator</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:snafucator.service.xml</param-value>
</context-param>

<servlet>
    <servlet-name>jaxws-servlet</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>jaxws-servlet</servlet-name>
    <url-pattern>/Snafucator</url-pattern>
</servlet-mapping>

我还希望我的 src/test/resources 位于类路径中,因为它们包含 DAO 的设置和实现该服务的其他组件。服务所需的所有 bean 都在 snafucator.service.xml 中配置。这主要是通过加载几个弹簧上下文文件来实现的。这些是来自较低层的文件和定义服务绑定和实现的 snafucator.context.xml:

<import resource="classpath*:setup.context.xml" />
<import resource="classpath*:core.context.xml" />
<import resource="classpath*:snafucator.context.xml" />

此外,我需要类路径上的目标/类,因为它包含 snafucator.context.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://jax-ws.dev.java.net/spring/core
http://jax-ws.dev.java.net/spring/core.xsd
http://jax-ws.dev.java.net/spring/servlet
http://jax-ws.java.net/spring/servlet.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- enable autowiring by annotations -->
<context:annotation-config />

<wss:binding url="/Snafucator">
    <wss:service>
        <ws:service bean="#snafucatorWs" />
    </wss:service>
</wss:binding>
<bean id="snafucatorWs" class="com.snafu.SnafucatorWSImpl" />

这就是我开始码头的方式:

    server = new Server(iPort);
WebAppContext root = new WebAppContext();
root.setExtraClasspath("target/classes/,src/test/resources/");
root.setDescriptor("src/main/webapp/WEB-INF/web.xml");
root.setResourceBase("src/main/webapp");    
root.setWar("src/main/webapp");
root.setContextPath("/");    
root.setServer(server);
root.setParentLoaderPriority(true);
server.setHandler(root);

System.out.println("Starting jetty server on port:" + iPort);
server.start();
System.out.println("Jetty server is started!");

当我访问"http://localhost:8082" 时,我看到了 WEB-INF 和 META-INF 目录,因此 Jetty 正在运行。当我尝试"http://localhost:8082/Snafucator" 时,我收到错误 404 并且命令行显示“JAX-WS-Servlet Initialized”。当我访问"http://localhost:8082" 下的任何其他 url 时,我得到的 404 格式略有不同。所以我假设发生了一些 WS 处理。 我还在开发一个 Web 应用程序,该服务旨在成为其中的一部分。当我将 snafucator.context.xml 包含到该应用程序的上下文中并使用 jetty eclipse 插件启动应用程序时,一切正常。但是对于自动化测试,我需要独立启动服务。

顺便说一句,我使用的是 Jetty 7.6.14。

我做错了什么?

【问题讨论】:

  • 我不确定 root.setWar() 在这种情况下是否有效。如果您有兴趣,我可以在没有 WAR 的情况下发布我的嵌入式 Jetty 方式,它非常适合测试并使用 spring。
  • 嗨 JosefN,我已经在不同的地方看到了 setWar 的这种用法,比如这里的 stackoverflow.com/questions/3718221/… 或这里的 today.java.net/pub/a/today/2007/04/12/…,其中 setWar 由 WebAppContext 的构造函数调用。但我不在乎它是如何工作的,只要它有效 :-) 所以如果你有一个正在运行的示例,我很乐意尝试一下。

标签: java spring testing jetty


【解决方案1】:

抱歉耽搁了。我使用没有 WAR 的嵌入式码头。下面是 Jetty 的简单包装器。您可以通过启动上下文或使用手动在测试中启动它

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "path/testContext.xml" })

包装类

public class JettyWrapper extends Server implements ApplicationContextAware {
        private ApplicationContext appContext;

@Override
protected void doStart() throws Exception {

    final ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    final GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext();
    webApplicationContext.setServletContext(context.getServletContext());
    webApplicationContext.setParent(appContext);
    context.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webApplicationContext);
    webApplicationContext.refresh();
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    dispatcherServlet.setContextConfigLocation("classpath:servlet-context.xml");
    context.addServlet(new ServletHolder(dispatcherServlet), "/*");
    context.setContextPath("/");
    setHandler(context);
    super.doStart();
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.appContext = applicationContext;
}

在上下文中:

<bean id="webServer" class="package.JettyWrapper"
    destroy-method="stop" init-method="start">
    <property name="connectors">
        <list>
            <bean id="Connector" class="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <property name="port" value="${jetty-port}" />
            </bean>
        </list>
    </property>

希望对你有帮助

【讨论】:

    【解决方案2】:

    很遗憾,您的解决方案对我不起作用。我认为这不是我想要的。特别是,我想从现有的 web.xml 开始。无论如何谢谢。但是,我找到了适合我的解决方案:

      @Override
      public void start() throws Exception {
        // Set up the handler for the web application context.
        WebAppContext root = new WebAppContext();
        root.setExtraClasspath(extraClassPath);
        root.setDescriptor(new File(appDir, "WEB-INF/web.xml").getAbsolutePath());
        root.setWar(new File(appDir).getAbsolutePath());
        root.setContextPath(contextPath);
        root.setParentLoaderPriority(true);
        server.setHandler(root);
        server.start();
        System.out.println("Jetty server is started!");
      }
    

    我认为唯一改变的是我没有设置资源库。现在效果很好。

    干杯

    【讨论】:

      猜你喜欢
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-23
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多