将上下文属性传递给 ServerResource

Issue passing context attributes to ServerResource

我的应用程序尝试设置上下文属性:

    final Router router = new Router();
    router.attachDefault(HttpListener.class);

    org.restlet.Application myApp = new org.restlet.Application() {
        @Override
        public org.restlet.Restlet createInboundRoot() {
            getContext().getAttributes().put("mysharedobj", new MySharedObj());
            return router;
        };
    };
    Component component = new Component();
    component.getDefaultHost().attach("/", myApp);

    new Server(Protocol.HTTP, port, component).start();

在我的 HttpListener 中,我断言上下文不为空:

public class HttpListener extends ServerResource {

    public MySharedObj mysharedobj;

    public HttpListener() { }  

    @java.lang.Override
    public void init(Context context, Request request, Response response) {

        assert context != null;  // throws java.lang.AssertionError

        // my end goal is to pass a shared object to my listener
        mysharedobj = context.getAttributes().get("mysharedobj");
    }
    ...
}

但是,由于上下文为空,因此抛出 java.lang.AssertionError。我的最终目标是将共享对象传递给我的听众。还有其他方法吗?

我哪里错了?注意:我使用的是 Restlet 2.1.7。我的应用程序总是 运行 来自 android 应用程序,因此没有可用的服务器上下文。


更新:

我也尝试过使用应用程序上下文:

    final Router router = new Router();
    router.attachDefault(HttpListener.class);

    Component component = new Component();

    final Context ctx = component.getApplication().getContext().createChildContext();
    ctx.getAttributes().put("mysharedobj", new MySharedObj());

    org.restlet.Application myApp = new org.restlet.Application(ctx) {
        @Override
        public org.restlet.Restlet createInboundRoot() {
            return router;
        };
    };

还有..

public HttpListener() {
    Context ctx = getApplication().getContext();
    assert ctx.getAttributes().size() > 0;  // Throws AssertionError
    ...     
}

在这种方法中,我能够访问应用程序上下文,但由于某种原因未在其上设置属性。

从您的 更新的 部分删除 final,然后它将起作用。因为您只能在 constructoran initializer 中设置 final 变量。在常规方法中,不能更改声明为 final.

的变量的值

所以,您的代码将是

 Router router = new Router(); // Remove final from this.
    router.attachDefault(HttpListener.class);

    Component component = new Component();

    Context ctx = component.getApplication().getContext().createChildContext(); // Remove final
    ctx.getAttributes().put("mysharedobj", new MySharedObj());

    org.restlet.Application myApp = new org.restlet.Application(ctx) {
        @Override
        public org.restlet.Restlet createInboundRoot() {
            return router;
        };
    };

您可以从 here 找到完整的源代码。

资源Link:

  1. Restlet Framework – Hello World Example
  2. Restlet Authorization

更新 1:

Restlet documentation and sample code,我得到了一些有用的地方。希望对你有所帮助。

public class MyApiWithRoleAuthorization extends Application {
    @Override
    public Restlet createInboundRoot() {
        Router router = createRouter();
        return router;
    }
    private Router createRouter() {
        //Attach Server Resources to given URL
        Router router = new Router(getContext());
        router.attach("/resource1/", Resource1.class);
        router.attach("/resource2/", Resource2.class);
        return router;
    }
      public static void main(String[] args) throws Exception {
        //Attach application to http://localhost:9000/v1
        Component c = new Component();
        c.getServers().add(Protocol.HTTP, 9000);
        c.getDefaultHost().attach("/v1", new MyApiWithRoleAuthorization());
        c.start();
    }
}

资源 类,将它们命名为 Resource1, Resource2 等...并从此处复制粘贴它们的内容:

Resource0.java

public class Resource0 extends ServerResource{

    @Get
    public String represent() throws Exception {
        return this.getClass().getSimpleName() + " found !";
    }

    @Post
    public String add() {
        return this.getClass().getSimpleName() + " posted !";
    }

    @Put
    public String change() {
        return this.getClass().getSimpleName() + " changed !";
    }

    @Patch
    public String partiallyChange() {
        return this.getClass().getSimpleName() + " partially changed !";
    }

    @Delete
    public String destroy() {
        return this.getClass().getSimpleName() + " deleted!";
    }
}

我目前最好的解决方案是使用单例 java class 和工厂方法来创建我的对象,并使用单例 getter 来检索该对象,例如

final Router router = new Router();
router.attachDefault(HttpListener.class);

MySharedObj myobj = MySharedObj.newInstance();

org.restlet.Application myApp = new org.restlet.Application() {
    @Override
    public org.restlet.Restlet createInboundRoot() {
        return router;
    };
};
Component component = new Component();
component.getDefaultHost().attach("/", myApp);

new Server(Protocol.HTTP, port, component).start();

// in a different thread
MySharedObj myobj = MySharedObj.get();
myobj.doStuff()

在我的 HttpListner 中:

public HttpListener() {
    MySharedObj myobj = MySharedObj.get();
    myobj.doStuff()       
    ...     
}