Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 设计为支持按对象类型处理请求_Java_Oop_Asynchronous_Gson - Fatal编程技术网

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等)
  • 客户机使用适当的输入类型调用这些API,我们将响应发送回客户机,并以JSON形式(使用Gson)推送队列中的输入对象(例如SQS)
  • 另一个轮询器继续轮询队列并从队列接收消息。收到消息后,轮询器必须按照inputObject类型执行任务
  • 有两个地方我的代码可能看起来很脏:

    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从队列接收到对象类型(修改了详细的问题)。很好,那么你可以考虑我的建议!很好,那么你可以考虑我的建议!