使用以下依赖项(Gradle):
org.glassfish.jersey.containers:jersey-container-servlet:2.22.2
org.eclipse.jetty:jetty-servlet:9.3.2.v20150730
我有一个嵌入式Jetty服务器,带有一个Jersey servlet容器......就像这样......
package mypkg.rest.jersey;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.servlet.ServletContainer;
import se.transmode.tnm.alarm.api.AlarmRetrieval;
import mypkg.rest.RestServer;
import mypkg.rest.jersey.serviceImpl.ModelAdapter;
public class JerseyBasedRestServer implements RestServer {
public static final int INITIALIZE_ON_USE = 0;
private Server server;
private final ServletContextHandler context;
private final ServletHolder servlet;
private final ModelAdapter modelAdapter;
public JerseyBasedRestServer(BusinessObjects businessObjects) {
this.modelAdapter = new ModelAdapter(businessObjects); //I want this instance to somehow be available for my ServletContainer to use.
context = new ServletContextHandler(ServletContextHandler.SESSIONS);
servlet = context.addServlet(ServletContainer.class, "/*");
servlet.setInitOrder(INITIALIZE_ON_USE);
servlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "mypackage.jersey.generated.api.service");
servlet.setInitParameter(ServerProperties.MEDIA_TYPE_MAPPINGS, "json : application/json");
context.setContextPath("/");
}
private void startServlet() {
try {
servlet.start();
servlet.initialize();
} catch (Exception e) {
log.error("Failed to initialize servlet. {}", e.getMessage());
}
}
@Override
public void init(int port) {
server = new Server(port);
server.setHandler(context);
try {
server.start();
server.join();
startServlet();
} catch (Exception e) {
log.error("Failed to start jetty server for rest interface");
} finally {
server.destroy();
}
}
Jersey容器将运行使用Swagger代码生成工具生成的服务器代码和模型
https://github.com/swagger-api/swagger-codegen#getting-started
提供生成的模型,JacksonJsonProvider
和RestApi
类:
package mypackage.jersey.generated.api.service
Path("/")
public class RestApi {
private final RestApiService delegate = new RestApiServiceImpl(); //Integration point of the generated code
@GET
@Path("/list/")
@Consumes({ "application/json" })
@Produces({ "application/json" })
public Response retrieveAlarmList(@Context SecurityContext securityContext) throws NotFoundException {
return delegate.retrieveAlarmList(securityContext);
}
}
为了整合生成的代码,我们将自己实现RestApiServiceImpl
。
ModelAdapter
的工作是将业务对象转换为生成的休息模型。
所以问题是如何创建我们的业务对象的适配器实例,在这种情况下ModelAdapter
,它位于Jersey servlet上下文的上下文之外,可用于RestApi
类或者更确切地说是RestApiServiceImpl
?
我从阅读过去的24小时了解到,我需要通过Jetty,Jersey或其他一些库来使用某种Context Dependency Injection(Weld似乎看起来很多),并尝试了{的各种组合{1}},@Inject
等等,但得出结论我不知道我在做什么......我甚至不确定我对这种情况有足够的了解问题正确。
可根据要求提供更多信息。
感谢任何帮助。
编辑:在https://github.com/englishbobster/JersetAndJetty
添加了一个链接使用@peeskillets建议,但仍无效。
答案 0 :(得分:2)
你需要让DI工作的第一件事是AbstractBinder
。这是您可以注入对象的地方。
class Binder extends AbstractBinder {
@Override
protected void configure() {
bind(modelAdapter).to(ModelAdapter.class);
}
}
然后你需要在Jersey上注册活页夹。最简单的方法是在Jersey的ResourceConfig
注册。在您的情况下,您没有使用它。您正在配置“web.xml”中的所有内容。为此,您应该查看this post。
如果您想更改配置以使用{I}个人使用的ResourceConfig
,您可以执行此操作
package com.some.pkg;
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("mypackage.jersey.generated.api.service");
property(ServerProperties.MEDIA_TYPE_MAPPINGS, "json : application/json");
register(new Binder());
}
}
然后使用Jetty配置它,你可以
servlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS,
"com.some.pkg.JerseyConfig");
现在你可以摆脱其他两个init-params,因为你在ResourceConfig
内配置它。
另一种没有任何init-params的方法就是
ResourceConfig config = new JerseyConfig();
ServletHolder jerseyServlet = new ServletHolder(ServletContainer(config));
context.addServlet(jerseyServlet, "/*");
查看最后一个代码段的完整示例here。
现在你可以在泽西岛的任何地方注入ModelAdapter
在一个字段中
@Inject
private ModelAdapter adapter;
或者在构造函数中
@Inject
public RestApi(ModelAdapter adapter) {
this.adapter = adapter;
}
或方法参数
@GET
public Response get(@Context ModelAdapter adapter) {}