CXF/Jetty 相当于以下 Jersey/Jetty 代码
CXF/Jetty equivalent of the following Jersey/Jetty code
我有一些 Jersey (2.7) 和 Jetty (9.2.5.v2014112) 的测试代码,我正在尝试移植到 CXF (3.0.x) 和 Jetty(相同版本) .有一部分我想不通,相当于下面的 rc.register(resource)
行:
ServletContextHandler sch = new ServletContextHandler();
sch.setContextPath("/xxx");
resource = new TheResource();
ResourceConfig rc = new ResourceConfig();
rc.register(resource);
ServletContainer sc = new ServletContainer(rc);
ServletHolder holder = new ServletHolder(sc);
sch.addServlet(holder, "/*");
Server server = new Server(port);
server.setHandler(sch);
server.start();
server.join();
对于 CXF/Jetty 案例,我知道我需要做类似的事情:
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet();
// EQUIVALENT OF:
// ResourceConfig rc = new ResourceConfig();
// rc.register(myresource)
// SOMETHING.setResourceConfig(rc)
ServletHolder holder = new ServletHolder(context);
ServletContextHandler handler = new ServletContextHandler("/restroot");
handler.addServlet(holder, "/*");
// Using ContextHandlerCollection cos my jetty needs to serve more
// than just this REST service
ContextHandlerCollection collection = new ContextHandlerCollection();
collection.addHandler(handler);
Server server = new Server(8080);
server.setHandler(collection);
server.start();
server.join();
有人知道how/if这是可能的吗?
只是为了澄清我在这里尝试做的事情:我正在尝试在嵌入式 Jetty 实例上发布 JAX-RS 服务,我需要 完全控制 JAX-RS bean 的生命周期。
马丁
查看 CXFNonSpringJaxrsServlet 的源代码,它是通过 web.xml 中的初始化参数配置的。但是,您当然可以自由覆盖该功能
我已经通过以下方式让一些东西正常工作:
- 扩展
CXFNonSpringJaxrsServlet
- 覆盖
getResourceProviders()
- 提供我自己的实现
ResourceProvider
看起来有点复杂,我觉得在CXF中应该有一个标准API,但无论如何,这是我的解决方案:
public class TheApp {
private static final Logger LOG = LoggerFactory.getLogger(TheApp.class);
TheResource resource;
public static class BeanResourceProvider implements ResourceProvider {
private final Object theBean;
public BeanResourceProvider(Object theBean) {
this.theBean = theBean;
}
@Override
public Object getInstance(Message m) {
return theBean;
}
@Override
public void releaseInstance(Message m, Object o) {
}
@Override
public Class<?> getResourceClass() {
return theBean.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
};
public TheApp(int port) throws Exception {
resource = new TheResource();
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet() {
public void configureSingleton(Object o) {
LOG.info("configureSingleton() called");
}
public Map<Class<?>, ResourceProvider>
getResourceProviders(ServletConfig servletConfig,
Map<Class<?>, Map<String, List<String>>> resourceClasses) throws ServletException {
LOG.info("getResourceProviders called");
Map<Class<?>, ResourceProvider> map = new HashMap<Class<?>, ResourceProvider>();
for (Map.Entry<Class<?>, Map<String, List<String>>> entry : resourceClasses.entrySet()) {
Class<?> c = entry.getKey();
LOG.info("getting provider for {}", c.getName());
map.put(c, new BeanResourceProvider(resource));
}
return map;
}
};
ServletHolder holder = new ServletHolder(context);
holder.setInitParameter("jaxrs.serviceClasses", "com.test.cxfjetty.TheResource");
ServletContextHandler handler = new ServletContextHandler();
handler.addServlet(holder, "/*");
handler.setContextPath("/theroot");
Server server = new Server(port);
server.setHandler(handler);
server.start();
server.join();
}
public static void main(String[] args) throws Exception {
TheApp app = new TheApp(8122);
}
}
有趣的练习,这是...
从 CXF 版本 3.0.4 开始,CXFNonSpringJaxrsServlet
上有额外的构造函数,使这更容易:
public SNAPSHOTApp(int port) throws Exception {
resource = new TheResource();
Set<Object> resourceSingletons = new HashSet<>();
resourceSingletons.add(resource);
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet(resourceSingletons);
ServletHolder servlet = new ServletHolder(context);
ServletContextHandler handler = new ServletContextHandler();
handler.addServlet(servlet, "/*");
handler.setContextPath("/snapshot");
Server server = new Server(port);
server.setHandler(handler);
server.start();
server.join();
}
非常感谢@Sergey Beryozkin 根据我在 CXF 用户邮件列表中的问题添加了此内容。
我有一些 Jersey (2.7) 和 Jetty (9.2.5.v2014112) 的测试代码,我正在尝试移植到 CXF (3.0.x) 和 Jetty(相同版本) .有一部分我想不通,相当于下面的 rc.register(resource)
行:
ServletContextHandler sch = new ServletContextHandler();
sch.setContextPath("/xxx");
resource = new TheResource();
ResourceConfig rc = new ResourceConfig();
rc.register(resource);
ServletContainer sc = new ServletContainer(rc);
ServletHolder holder = new ServletHolder(sc);
sch.addServlet(holder, "/*");
Server server = new Server(port);
server.setHandler(sch);
server.start();
server.join();
对于 CXF/Jetty 案例,我知道我需要做类似的事情:
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet();
// EQUIVALENT OF:
// ResourceConfig rc = new ResourceConfig();
// rc.register(myresource)
// SOMETHING.setResourceConfig(rc)
ServletHolder holder = new ServletHolder(context);
ServletContextHandler handler = new ServletContextHandler("/restroot");
handler.addServlet(holder, "/*");
// Using ContextHandlerCollection cos my jetty needs to serve more
// than just this REST service
ContextHandlerCollection collection = new ContextHandlerCollection();
collection.addHandler(handler);
Server server = new Server(8080);
server.setHandler(collection);
server.start();
server.join();
有人知道how/if这是可能的吗?
只是为了澄清我在这里尝试做的事情:我正在尝试在嵌入式 Jetty 实例上发布 JAX-RS 服务,我需要 完全控制 JAX-RS bean 的生命周期。
马丁
查看 CXFNonSpringJaxrsServlet 的源代码,它是通过 web.xml 中的初始化参数配置的。但是,您当然可以自由覆盖该功能
我已经通过以下方式让一些东西正常工作:
- 扩展
CXFNonSpringJaxrsServlet
- 覆盖
getResourceProviders()
- 提供我自己的实现
ResourceProvider
看起来有点复杂,我觉得在CXF中应该有一个标准API,但无论如何,这是我的解决方案:
public class TheApp {
private static final Logger LOG = LoggerFactory.getLogger(TheApp.class);
TheResource resource;
public static class BeanResourceProvider implements ResourceProvider {
private final Object theBean;
public BeanResourceProvider(Object theBean) {
this.theBean = theBean;
}
@Override
public Object getInstance(Message m) {
return theBean;
}
@Override
public void releaseInstance(Message m, Object o) {
}
@Override
public Class<?> getResourceClass() {
return theBean.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
};
public TheApp(int port) throws Exception {
resource = new TheResource();
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet() {
public void configureSingleton(Object o) {
LOG.info("configureSingleton() called");
}
public Map<Class<?>, ResourceProvider>
getResourceProviders(ServletConfig servletConfig,
Map<Class<?>, Map<String, List<String>>> resourceClasses) throws ServletException {
LOG.info("getResourceProviders called");
Map<Class<?>, ResourceProvider> map = new HashMap<Class<?>, ResourceProvider>();
for (Map.Entry<Class<?>, Map<String, List<String>>> entry : resourceClasses.entrySet()) {
Class<?> c = entry.getKey();
LOG.info("getting provider for {}", c.getName());
map.put(c, new BeanResourceProvider(resource));
}
return map;
}
};
ServletHolder holder = new ServletHolder(context);
holder.setInitParameter("jaxrs.serviceClasses", "com.test.cxfjetty.TheResource");
ServletContextHandler handler = new ServletContextHandler();
handler.addServlet(holder, "/*");
handler.setContextPath("/theroot");
Server server = new Server(port);
server.setHandler(handler);
server.start();
server.join();
}
public static void main(String[] args) throws Exception {
TheApp app = new TheApp(8122);
}
}
有趣的练习,这是...
从 CXF 版本 3.0.4 开始,CXFNonSpringJaxrsServlet
上有额外的构造函数,使这更容易:
public SNAPSHOTApp(int port) throws Exception {
resource = new TheResource();
Set<Object> resourceSingletons = new HashSet<>();
resourceSingletons.add(resource);
CXFNonSpringJaxrsServlet context = new CXFNonSpringJaxrsServlet(resourceSingletons);
ServletHolder servlet = new ServletHolder(context);
ServletContextHandler handler = new ServletContextHandler();
handler.addServlet(servlet, "/*");
handler.setContextPath("/snapshot");
Server server = new Server(port);
server.setHandler(handler);
server.start();
server.join();
}
非常感谢@Sergey Beryozkin 根据我在 CXF 用户邮件列表中的问题添加了此内容。