我有一个简单的资源:
@Path("/")
public class RootResource {
@Context WebConfig wc;
@PostConstruct
public void init() {
assertNotNull(wc);
}
@GET
public void String method() {
return "Hello\n";
}
}
我正在尝试使用JerseyTest(2.x,而非1.x)和GrizzlyTestContainerFactory。
我无法解决在配置方面需要做的事情,以便注入WebConfig对象。
答案 0 :(得分:5)
我通过创建GrizzlyTestContainerFactory的子类并显式加载Jersey servlet解决了这个问题。这会触发WebConfig对象的注入。代码如下所示:
public class ExtendedGrizzlyTestContainerFactory implements TestContainerFactory {
private static class GrizzlyTestContainer implements TestContainer {
private final URI uri;
private final ApplicationHandler appHandler;
private HttpServer server;
private static final Logger LOGGER = Logger.getLogger(GrizzlyTestContainer.class.getName());
private GrizzlyTestContainer(URI uri, ApplicationHandler appHandler) {
this.appHandler = appHandler;
this.uri = uri;
}
@Override
public ClientConfig getClientConfig() {
return null;
}
@Override
public URI getBaseUri() {
return uri;
}
@Override
public void start() {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, "Starting GrizzlyTestContainer...");
}
try {
this.server = GrizzlyHttpServerFactory.createHttpServer(uri, appHandler);
// Initialize and register Jersey Servlet
WebappContext context = new WebappContext("WebappContext", "");
ServletRegistration registration = context.addServlet("ServletContainer", ServletContainer.class);
registration.setInitParameter("javax.ws.rs.Application",
appHandler.getConfiguration().getApplication().getClass().getName());
// Add an init parameter - this could be loaded from a parameter in the constructor
registration.setInitParameter("myparam", "myvalue");
registration.addMapping("/*");
context.deploy(server);
} catch (ProcessingException e) {
throw new TestContainerException(e);
}
}
@Override
public void stop() {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.log(Level.INFO, "Stopping GrizzlyTestContainer...");
}
this.server.stop();
}
}
@Override
public TestContainer create(URI baseUri, ApplicationHandler application) throws IllegalArgumentException {
return new GrizzlyTestContainer(baseUri, application);
}
请注意,Jersey Servlet配置是从ApplicationHandler加载的,它使用内部Application对象的类名称作为参数传入(ResourceConfig是Application的子类)。因此,您还需要创建ResourceConfig的子类,以使此方法起作用。这个代码非常简单:
package com.example;
import org.glassfish.jersey.server.ResourceConfig;
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
super(MyResource.class);
}
}
这假设您正在测试的资源是MyResource。您还需要在测试中覆盖几个方法,如下所示:
public class MyResourceTest extends JerseyTest {
public MyResourceTest() throws TestContainerException {
}
@Override
protected Application configure() {
return new MyResourceConfig();
}
@Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new ExtendedGrizzlyTestContainerFactory();
}
@Test
public void testCreateSimpleBean() {
final String beanList = target("test").request().get(String.class);
Assert.assertNotNull(beanList);
}
}
最后,为了完整性,这里是MyResource的代码:
@Path("test")
public class MyResource {
@Context WebConfig wc;
@PostConstruct
public void init() {
System.out.println("WebConfig: " + wc);
String url = wc.getInitParameter("myparam");
System.out.println("myparam = "+url);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Collection<TestBean> createSimpleBean() {
Collection<TestBean> res = new ArrayList<TestBean>();
res.add(new TestBean("a", 1, 1L));
res.add(new TestBean("b", 2, 2L));
return res;
}
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public TestBean roundTrip(TestBean s) {
return s;
}
}
运行测试的输出显示已加载WebConfig并且init param现在可用:
WebConfig: org.glassfish.jersey.servlet.WebServletConfig@107d0f44
myparam = myvalue
答案 1 :(得分:0)
来自@ametke的解决方案运行良好,但没有拿起我的ExceptionMapper类。为了解决这个问题,我将start()
方法简化为:
@Override
public void start() {
try {
initParams.put("jersey.config.server.provider.packages", "my.resources;my.config");
this.server = GrizzlyWebContainerFactory.create(uri, initParams);
} catch (ProcessingException | IOException e) {
throw new TestContainerException(e);
}
}
这是基于Problems running JerseyTest when dealing with HttpServletResponse