使用 grizzle 测试球衣网络资源的测试用例给我 404

Test case for testing a jersey web resource using grizzle is giving me 404

我试过下面的方法,效果很好

package test;

import static org.junit.Assert.assertEquals;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;

    import org.glassfish.jersey.server.ResourceConfig;
    import org.glassfish.jersey.test.DeploymentContext;
    import org.glassfish.jersey.test.JerseyTest;
    import org.glassfish.jersey.test.ServletDeploymentContext;
    import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
    import org.glassfish.jersey.test.spi.TestContainerException;
    import org.glassfish.jersey.test.spi.TestContainerFactory;
    import org.junit.Test;

    import com.mkyong.rest.HelloWorldService;

    public class HelloWorldServiceTest extends JerseyTest{

        @Path("hello")
        public static class HelloResource {
            @GET
            public String getHello() {
                return "Hello World!";
            }
        }

        @Override
        protected Application configure() {
            return new ResourceConfig(HelloResource.class);
        }

        @Override
        protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
            return new GrizzlyWebTestContainerFactory();
        }

        @Override
        protected DeploymentContext configureDeployment() {
            return ServletDeploymentContext.forPackages(
                    getClass().getPackage().getName()).build();
        }

        @Test
        public void testSingleNode() throws Exception {
            final String hello = target("hello").request().get(String.class);
            assertEquals("Hello World!", hello);
        }
        }

当我试图用这个测试之外的资源替换资源时class并像下面这样打包

   package test;

import static org.junit.Assert.assertEquals;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.DeploymentContext;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.ServletDeploymentContext;
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.junit.Test;

import com.mkyong.rest.HelloWorldService;

public class HelloWorldServiceTest extends JerseyTest{

    @Path("hello")
    public static class HelloResource {
        @GET
        public String getHello() {
            return "Hello World!";
        }
    }

    @Override
    protected Application configure() {
        return new ResourceConfig(HelloWorldService.class);
    }

    @Override
    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
        return new GrizzlyWebTestContainerFactory();
    }

    @Override
    protected DeploymentContext configureDeployment() {
        return ServletDeploymentContext.forPackages(
                getClass().getPackage().getName()).build();
    }

    @Test
    public void testSingleNode() throws Exception {
        final String hello = target("hello").path("Test").request().get(String.class);
        assertEquals("Jersey say : Test", hello);
    }
    }

HelloWorldService.java

package com.mkyong.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/hello")
public class HelloWorldService {

    @GET
    @Path("/{param}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getMsg(@PathParam("param") String msg) {

        String output = "Jersey say : " + msg;

        return Response.status(200).entity(output).build();

    }

}

RestApplication.java

      package rest;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import com.mkyong.rest.HelloWorldService;

public class RestApplication extends Application{

      @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> s = new HashSet<Class<?>>();

            s.add(HelloWorldService.class);
            return s;
        }


}

web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

     <servlet>
    <servlet-name>rs-servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>rest.RestApplication</param-value>
</init-param>
  </servlet>
  <servlet-mapping>
  <servlet-name>rs-servlet</servlet-name>
  <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

</web-app>

我有一个例外

   javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:917)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:770)
at org.glassfish.jersey.client.JerseyInvocation.access0(JerseyInvocation.java:90)
at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:671)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:423)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)
at test.HelloWorldServiceTest.testSingleNode(HelloWorldServiceTest.java:48) 

谁能指正我哪里错了...

看看这个

@Override
protected DeploymentContext configureDeployment() {
    return ServletDeploymentContext.forPackages(
            getClass().getPackage().getName()).build();
}

forPackages 表示要扫描 @Path@Provider 注释的 class 的包,并自动注册它们。它在第一个示例中起作用的原因是资源 class(用 @Path 注释的 class 在 getClass().getPackage().getName() 包中。

这个方法

@Override
protected Application configure() {
    return new ResourceConfig(HelloWorldService.class);
}

永远不会被调用,因为您覆盖了 getDeploymentContext()。通常,如果您不重写该方法,它会调用 configure 方法向部署上下文注册应用程序。但你永远不会这样做。

因此,您应该使用接受 Application class

ServletDeploymentContext.builder 方法之一,而不是 forPackages
return ServletDeploymentContext.builder(configure()).build()

return ServletDeploymentContext.builder(RestApplication.class).build();

@Override
public ResourceConfig configure() {
    return new ResourceConfig(HelloWorldService.class);
}

@Override
public ServletDeploymentContext configureDeployment() {
    return SerlvetDeploymentContext.forServlet(new ServletContainer(configure));
}

需要注意的一点是,如果您想设置一个 servlet 环境,您只需要覆盖 getTestContainerFactoryconfigureDeployment。也就是说,您需要在应用程序中使用 HttpServletRequestServletContext 等 servlet API。如果不需要 servlet 环境,只需覆盖 configure 即可。