发出将上下文属性传递给ServerResource

时间:2016-06-07 13:15:25

标签: java restlet restlet-2.0

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

    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应用程序运行,因此没有可用的服务器上下文。

更新

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

    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上下文,但由于某种原因没有设置属性。

2 个答案:

答案 0 :(得分:0)

更新部分删除final,然后它就可以了。因为您只能在constructoran initializer中设置最终变量。在常规方法中,不能更改声明为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找到完整的源代码。

资源链接:

  1. Restlet Framework – Hello World Example
  2. Restlet Authorization
  3. UPDATE1:

    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!";
        }
    }
    

答案 1 :(得分:0)

我目前最好的解决方案是使用带有工厂方法的单例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()       
    ...     
}