将上下文属性传递给 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,然后它将起作用。因为您只能在 constructor
或 an 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 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()
...
}
我的应用程序尝试设置上下文属性:
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,然后它将起作用。因为您只能在 constructor
或 an 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 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()
...
}