我的应用程序尝试设置上下文属性:
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上下文,但由于某种原因没有设置属性。
答案 0 :(得分:0)
从更新部分删除final,然后它就可以了。因为您只能在constructor
或an 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找到完整的源代码。
资源链接:
从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
等...并从此处复制粘贴其内容:
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()
...
}