Java 设计为支持按对象类型处理请求
根据一个用例,这是我们要做的:Java 设计为支持按对象类型处理请求,java,oop,asynchronous,gson,Java,Oop,Asynchronous,Gson,根据一个用例,这是我们要做的: 公开具有不同参数的多个Async服务API(例如InputObject1、InputObject2等) 客户机使用适当的输入类型调用这些API,我们将响应发送回客户机,并以JSON形式(使用Gson)推送队列中的输入对象(例如SQS) 另一个轮询器继续轮询队列并从队列接收消息。收到消息后,轮询器必须按照inputObject类型执行任务 有两个地方我的代码可能看起来很脏: a. How to check the type of object on receivin
Async
服务API(例如InputObject1、InputObject2等)a. How to check the type of object on receiving from the queue? This would be in JSON format and I will have to convert JSON back to object. It will belong to one of the multiple potential objects.
b. Once type is known, how to call class responsible to handle that object?
这个用例的最佳设计是什么
For a), one option is to create a `RequestWrapper` containing all the objects and populating the one this message belongs to.
对于b)我可以考虑以下几种方法:
1. Add another parameter to the object and pass it to queue. Use this parameter to identify API called.
2. Use `instanceof` to get exact requestObject using multiple if-else and do the needful.
不过,我觉得这些不太整洁。还有更好的建议吗
==Edit==
@A4L
谢谢,我建议至少引入一个新的接口
QueueTaskAble
,它将由您的输入对象实现,第二个可选接口可以是java.lang.Runnable
,然后使用某种run
或execute
方法执行任务
下面是它的样子:
interface QueueTaskAble {
Runnable getQueueTask();
}
class InputObjectFooQueueTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
}
}
class InputObjectFooImpl implements QueueTaskAble {
@Override
public Runnable getQueueTask() {
return new InputObjectFooQueueTask();
}
}
void processQueueInputObject(QueueTaskAble queueObject) {
queueObject.getQueueTask().run();
}
编辑 不幸的是,不可能使用本机反序列化为接口。要做到这一点,您需要实现一个可以传递给的类型适配器,以便正确地序列化和反序列化对象 以下是您可以采取的措施: 类型适配器
public class GenericGsonTypeAdapter<T> implements JsonSerializer<T>,
JsonDeserializer<T> {
@Override
public JsonElement serialize(T src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject jo = new JsonObject();
jo.addProperty("className", src.getClass().getName());
jo.add("jsonData", context.serialize(src));
return jo;
}
@Override
public T deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
T obj = null;
if(json instanceof JsonObject) {
JsonObject jo = (JsonObject) json;
JsonElement jeJson = jo.get("jsonData");
if(jeJson != null) {
JsonElement jeClassName = jo.get("className");
try {
obj = context.deserialize(json,
Class.forName(jeClassName.getAsString()));
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
}
return obj;
}
}
最后是一个示例应用程序
public class App {
public static void main(String... args) {
InputObjectGsonBuilder gb = new InputObjectGsonBuilder();
InputObjectGsonQueue gq = new InputObjectGsonQueue();
gq.pushInputObject(gb.create().toJson(new InputObjectFooImpl(),
QueueTaskAble.class));
gq.pushInputObject(gb.create().toJson(new InputObjectBarImpl(),
QueueTaskAble.class));
gq.processQueue();
}
}
输出
Foo!
Bar!
我建议至少引入一个新接口
QueueTaskAble
,它将由您的输入对象实现,第二个接口(可选)可以是java.lang.Runnable
,然后使用某种run
或execute
方法执行任务
下面是它的样子:
interface QueueTaskAble {
Runnable getQueueTask();
}
class InputObjectFooQueueTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
}
}
class InputObjectFooImpl implements QueueTaskAble {
@Override
public Runnable getQueueTask() {
return new InputObjectFooQueueTask();
}
}
void processQueueInputObject(QueueTaskAble queueObject) {
queueObject.getQueueTask().run();
}
编辑 不幸的是,不可能使用本机反序列化为接口。要做到这一点,您需要实现一个可以传递给的类型适配器,以便正确地序列化和反序列化对象 以下是您可以采取的措施: 类型适配器
public class GenericGsonTypeAdapter<T> implements JsonSerializer<T>,
JsonDeserializer<T> {
@Override
public JsonElement serialize(T src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject jo = new JsonObject();
jo.addProperty("className", src.getClass().getName());
jo.add("jsonData", context.serialize(src));
return jo;
}
@Override
public T deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
T obj = null;
if(json instanceof JsonObject) {
JsonObject jo = (JsonObject) json;
JsonElement jeJson = jo.get("jsonData");
if(jeJson != null) {
JsonElement jeClassName = jo.get("className");
try {
obj = context.deserialize(json,
Class.forName(jeClassName.getAsString()));
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
}
return obj;
}
}
最后是一个示例应用程序
public class App {
public static void main(String... args) {
InputObjectGsonBuilder gb = new InputObjectGsonBuilder();
InputObjectGsonQueue gq = new InputObjectGsonQueue();
gq.pushInputObject(gb.create().toJson(new InputObjectFooImpl(),
QueueTaskAble.class));
gq.pushInputObject(gb.create().toJson(new InputObjectBarImpl(),
QueueTaskAble.class));
gq.processQueue();
}
}
输出
Foo!
Bar!
在“编辑”部分回答了您的问题。如果我没有错的话,在您的例子中,getQueueTask()从队列中获取一个任务并调用相应的runnable类。我对那部分更感兴趣。我们如何获得要调用的特定类?另外,将从队列接收到的Json转换为对象类型(用详细信息修改了问题)。在“编辑”部分回答了您的问题。如果我没有错,在您的例子中,getQueueTask()从队列中获取一个任务并调用相应的runnable类。我对那部分更感兴趣。我们如何获得要调用的特定类?此外,将JSON从队列接收到对象类型(修改了详细的问题)。很好,那么你可以考虑我的建议!很好,那么你可以考虑我的建议!