如何参数化Java中的响应解析? [英] How do I parametrize response parsing in Java?

查看:98
本文介绍了如何参数化Java中的响应解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个网络类,并希望能够解析对不同类的不同响应(仍然存在一对一的关系,但是我想拥有一个单独的parseResponse(),它可以处理来自不同端点的所有响应,并且endpoint.className具有我应该映射到的预期 classType ):

I'm writing a network class and want to be able to parse different responses to different classes (there's still one-to-one relationship but I want to have a single parseResponse() that will deal with all responses from different endpoints, and endpoint.className has the expected classType that I should map to):

private Class<?> parseResponse(StringBuilder responseContent, Endpoint endpoint) {
    ObjectMapper mapper = new ObjectMapper();
    try {
        Class<?> object = mapper.readValue(responseContent.toString(), endpoint.className);
        // endpoint.className has Class<?> type
        if (object instanceof endpoint.className) {
        }
    } catch (IOException e) {
        // handle errors
    }
}

但是如果我写if (object instanceof endpoint.className)

更新:可能更好的选择是将parse()方法添加到Endpoint类:

Update: probably the better option is to add parse() method to Endpoint class:

public Class<?> parseResponse(String responseContent) {
   // this.className has Class<?> type (e.g., Foo.class).
}

public enum Endpoint {
    FOO (Foo.class),
    BAR (Bar.class);

    private Class<?> classType;
}

但是仍然存在相同的类型错误.

But there're still the same type errors.

推荐答案

您应将JSON反序列化与应用程序的其他部分分开.您不能为所有响应实现一个方法,但是响应数量可能有限,并且可以为每个类声明一些简单方法.通常,您只能使用一种具有如下声明的方法:

You should separate JSON deserialisation from other parts of your app. You can not implement one method for all responses but you probably have a limited number of responses and you can declare some simple methods for each class. Generally, you could have only one method with declaration like below:

public <T> T deserialise(String payload, Class<T> expectedClass) {
    Objects.requireNonNull(payload);
    Objects.requireNonNull(expectedClass);

    try {
        return mapper.readValue(payload, expectedClass);
    } catch (IOException e) {
        throw new IllegalStateException("JSON is not valid!", e);
    }
} 

现在,您可以反序列化所需的所有有效负载.您需要提供要返回的JSON有效负载和POJO类.

And now, you can deserialise all payloads you want. You need to provide JSON payload and POJO class you want to receive back.

显示该概念的简单工作解决方案:

Simple working solution which shows that concept:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.io.IOException;
import java.util.Objects;

public class JsonMapper {

    private final ObjectMapper mapper = new ObjectMapper();

    public JsonMapper() {
        // configure mapper instance if required
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        // etc...
    }

    public String serialise(Object value) {
        try {
            return mapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new IllegalStateException("Could not generate JSON!", e);
        }
    }

    public <T> T deserialise(String payload, Class<T> expectedClass) {
        Objects.requireNonNull(payload);
        Objects.requireNonNull(expectedClass);

        try {
            return mapper.readValue(payload, expectedClass);
        } catch (IOException e) {
            throw new IllegalStateException("JSON is not valid!", e);
        }
    }

    public Foo parseResponseFoo(String payload) {
        return deserialise(payload, Foo.class);
    }

    public Bar parseResponseBar(String payload) {
        return deserialise(payload, Bar.class);
    }

    public static void main(String[] args) {
        JsonMapper jsonMapper = new JsonMapper();

        String bar = "{\"bar\" : 2}";
        System.out.println(jsonMapper.parseResponseBar(bar));

        String foo = "{\"foo\" : 1}";
        System.out.println(jsonMapper.parseResponseFoo(foo));

        System.out.println("General method:");
        System.out.println(jsonMapper.deserialise(foo, Foo.class));
        System.out.println(jsonMapper.deserialise(bar, Bar.class));
    }
}

class Foo {

    public int foo;

    @Override
    public String toString() {
        return "Foo{" +
                "foo=" + foo +
                '}';
    }
}

class Bar {

    public int bar;

    @Override
    public String toString() {
        return "Bar{" +
                "bar=" + bar +
                '}';
    }
}

另请参阅:

  • Deserializing or serializing any type of object using Jackson ObjectMapper and handling exceptions
  • What are Reified Generics? How do they solve Type Erasure problems and why can't they be added without major changes?
  • How to use jackson to deserialize to Kotlin collections

这篇关于如何参数化Java中的响应解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆