繁体   English   中英

发出将上下文属性传递给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中,我声明上下文不是null:

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是因为上下文为null。 我的最终目标是将共享对象传递给我的侦听器。 还有其他方法可以做到这一点吗?

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


更新:

我也尝试过使用Application Context:

    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
    ...     
}

在这种方法中,我能够访问Application上下文,但由于某种原因没有设置属性。

从您更新的部分删除最终,然后它将工作。 因为您只能在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;
        };
    };

您可以在此处找到完整的源代码。

资源链接:

  1. Restlet框架 - Hello World示例
  2. Restlet授权

UPDATE1:

Restlet文档和示例代码中 ,我得到了一些有用的区域。 希望它会对你有所帮助。

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类来创建我的对象,并使用单例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()       
    ...     
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM