簡體   English   中英

如何使 java class 在運行時和根據需要表現得像正常的 object 和對象列表?

[英]how to make java class behave like a normal object and list-of-object at runtime and as per need?

我在 java 中有一個簡單的 class,如下所示:

class Simple {
   private String name;
   private String email;
}

根據我的程序接收到的輸入數據,我想要java.util.List<Simple>Simple的行為。

IE

情況 1:: 如果我的程序收到以下類型的 json 數組輸入

{"simple" : [ {"name":"a", "email" : "a@z.com"}, {"name":"b", "email" : "b@z.com"} ]}

我需要使用List<Simple>解析它

情況 2:: 如果我的程序收到以下類型的 json 對象輸入

{"simple" : {"name":"c", "email" : "c@z.com"} }

我需要使用Simple解析它

注意:我試過使用JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY ,但問題是它基本上是在編寫 json 時將單個值也轉換為 json 數組。我需要按原樣堅持 json,有沒有其他方法可以實現這個?

您可以使用JsonNode.isArray() (或JsonNode.isObject() )來執行此檢查。

然后您可以使用ObjectReader.readValue()將節點解析為列表或使用ObjectMapper.treeToValue()解析為 POJO。

String myJson = """
    {"simple" : {"name":"c", "email" : "c@z.com"} }
""";
    
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(myJson);

if (node.isArray()) {
    ObjectReader reader = mapper.readerFor(new TypeReference<List<Simple>>() {});
    List<Simple> list = reader.readValue(node);

    // do something with a list
} else {
    Simple pojo = mapper.treeToValue(node, Simple.class);

    // do something else with a single object
}

為了避免任何Jackson自定義,我將創建包裝器 class 和一個Object simple屬性。 我們可以添加兩個額外的檢查方法和兩個額外的轉換方法。 它將允許Jackson執行它的邏輯,在運行時我們可以檢查我們實際擁有的內容:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Collections;
import java.util.List;

public class DateApp {
    private final static JsonMapper JSON_MAPPER = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build();

    public static void main(String[] args) throws Exception {
        Simple object = new Simple("John", "john@doe.com");
        SimpleWrapper wrapper = new SimpleWrapper();
        wrapper.setSimple(object);

        serializeAndDeserialize(wrapper);

        wrapper.setSimple(Collections.singletonList(object));
        serializeAndDeserialize(wrapper);
    }

    private static void serializeAndDeserialize(SimpleWrapper wrapper) throws JsonProcessingException {
        String json = JSON_MAPPER.writeValueAsString(wrapper);
        System.out.println("JSON:");
        System.out.println(json);

        wrapper = JSON_MAPPER.readValue(json, SimpleWrapper.class);
        System.out.println("Wrapper:");
        System.out.println(wrapper);
    }
}

@Data
class SimpleWrapper {
    private Object simple;

    @JsonIgnore
    public boolean isSimpleObject() {
        return simple instanceof Simple;
    }

    @JsonIgnore
    public boolean isSimpleList() {
        return simple instanceof List;
    }

    @JsonIgnore
    public Simple getSimpleAsObject() {
        return (Simple) simple;
    }

    @JsonIgnore
    public List<Simple> getSimpleAsList() {
        return (List<Simple>) simple;
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Simple {
    private String name;
    private String email;
}

上面的代碼打印:

JSON:
{
  "simple" : {
    "name" : "John",
    "email" : "john@doe.com"
  }
}
Wrapper:
SimpleWrapper(simple={name=John, email=john@doe.com})

JSON:
{
  "simple" : [ {
    "name" : "John",
    "email" : "john@doe.com"
  } ]
}
Wrapper:
SimpleWrapper(simple=[{name=John, email=john@doe.com}])

Jackson 能夠將任何 json 解析為 map,其中值是任何 object。然后您可以查詢 map 值的類型

Map<String, Object> map = new ObjectMapper().readValue(jsonInput, Map.class);
Object value = map.get("simple");
if (value instanceof Collection) { // will return false for null
    Collection<Simple> simples = (Collection<Simple>)value;
}
else if (value instanceof Simple) {
    Simple simple = (Simple)value;
}
else {
    System.err.println("unrecognized");
}

您只需要讀取第一個節點, simple並檢查它是否是一個數組 - 使用isArray()方法。

public class Main{
    public static void main(String args[]) {
        
        //String inputString = [your input];
        
        ObjectMapper mapper = new ObjectMapper();
    
        JsonNode root = mapper.readTree(inputString);
    
        JsonNode simpleNode = root.findPath("simple");
    
        if(simpleNode.isArray()) {
    
           //you have an array

        } else {
    
        // you have an element
    
        }

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM