引导 JAX-RS (RESTEasy)

Kev*_*Day 5 java jax-rs resteasy

我在嵌入式 Web 服务器(Jetty)中运行 RESTEasy。

我的资源需要访问支持数据存储,其配置是在用于启动我们的应用程序的命令行上传递的。

理想情况下,我将在资源的构造函数中注入支持数据存储资源:

@Path("/")    
public class MappingService{
    private final RecordManager recman;

    public MappingService(RecordManager recman) {
        this.recman = recman;
    }

    @PUT
    @Path("/mapping/{key}")
    @Produces({MediaType.APPLICATION_JSON, "application/*+json"})
    public Response createMapping(@PathParam("key") String key, @QueryParam("val") String val) {
                // do stuff with recman ...
           }
    }
Run Code Online (Sandbox Code Playgroud)

理想情况下,我会在应用程序的其他位置配置 RecordManager 对象,然后将其提供给 MappingService 构造函数。

我发现我可以使用 Application 对象返回特定的单例实例。但看起来 RESTEasy 自己构造了应用程序对象 - 所以我没有看到任何将配置对象传递到应用程序单例的方法。

那么:如何将外部实例化的对象传递到我的资源处理程序中?


我发现这篇文章(在 JAX-RS 请求之间共享变量)描述了如何使用上下文侦听器将对象添加到上下文并将其拉入资源处理程序中 - 但这太可怕了 - 我必须采用 POJO突然间我让它高度依赖于它的容器。请告诉我有更好的方法!

Kev*_*Day 3

好的 - 我已经弄清楚了 - 在这里记录以防其他人遇到这个问题。

诀窍在于利用 @Context 注入来注入我想要的资源,而不是获取对 servlet 上下文的引用。如果您对 RestEASY 引导过程有一定的控制,则可以完成此操作(我们以编程方式注册上下文侦听器,而不是使用从 web.xml 中指定的类名构造的上下文侦听器进行引导)。

我使用 Jetty 作为我的 servlet 容器。这是我的主要方法:

public static void main(String[] args) throws Exception {
    final RecordManager recman = createRecordManager(args);

    Server server = new Server(DEFAULT_HTTP_PORT);
    try {

        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setContextPath("/");
        webAppContext.setWar(WAR_LOCATION);

        webAppContext.addEventListener(new org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap(){
            @Override
            public void contextInitialized(ServletContextEvent event) {
                super.contextInitialized(event);
                deployment.getDispatcher().getDefaultContextObjects().put(RecordManager.class, recman);
            }
        });

        webAppContext.addServlet(org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.class, "/*");

        webAppContext.setServer(server);
        server.setHandler(webAppContext);

        server.start();

    } catch (Exception e) {
        logger.error("Error when starting", e);
        server.stop();
    } 
}
Run Code Online (Sandbox Code Playgroud)

然后我的资源处理程序看起来像这样:

@Path("/")
public class MappingResource {

    private final RecordManager recman;

    public MappingResource(@Context RecordManager recman) { //<-- sweet! resource injection
        this.recman = recman;
    }


    @PUT
    @Path("/mapping/{key}")
    @Produces({MediaType.APPLICATION_JSON, "application/*+json"})
    public Response createMapping(@PathParam("key") String key, @QueryParam("val") String val) {
        // do something with recman, key and val
    }
}
Run Code Online (Sandbox Code Playgroud)

为了彻底起见,这里是 web.xml 条目(这只是通用的 Resteasy 配置内容):

<context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>my.package.MappingService</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)