Java三方库-JSON库

5 篇文章 0 订阅
4 篇文章 0 订阅


记录下Jackson常用的功能

Jackson组成

jackson是java处理json的标准库

Jackson核心有三个包

core,annotation,databind, databind依赖前两者,所以使用时直接引入databind即可

		<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>

JSON和对象系列

JSON和POJO互转示例

使用ObjectMapper进行JSON字符串和类,List,Map的互转,字段若私有,则需提供getter和setter方法

        ObjectMapper objectMapper = new ObjectMapper();
        Information information = new Information();
        information.setHost("12414142");
        information.setN ame("111");
        information.setPassword("123");
        Email email = new Email();
        email.setTitle("email-1");
        email.setInformation(information);

        String string = objectMapper.writeValueAsString(email);
        System.out.println(string);

        Email email1 = objectMapper.readValue(string, Email.class);
        System.out.println(email1);

List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

Map<String, Object> map 
  = objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){});

public class Email {
    private Information information;
    private String title;

    public Information getInformation() {
        return information;
    }

    public void setInformation(Information information) {
        this.information = information;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}


public class Information {
    private String name;
    private String password;
    private String host;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }
}
// Note: can use getters/setters as well; here we just use public fields directly:
public class MyValue {
  public String name;
  public int age;
  // NOTE: if using getters/setters, can keep fields `protected` or `private`
}

TreeNode和ObjectNode

针对非对象类,动态场景,动态字段场景

// can be read as generic JsonNode, if it can be Object or Array; or,
// if known to be Object, as ObjectNode, if array, ArrayNode etc:
JsonNode root = mapper.readTree("{ \"name\": \"Joe\", \"age\": 13 }");
String name = root.get("name").asText();
int age = root.get("age").asInt();

// can modify as well: this adds child Object as property 'other', set property 'type'
root.withObject("/other").put("type", "student");
String json = mapper.writeValueAsString(root); // prints below

/*
with above, we end up with something like as 'json' String:
{
  "name" : "Bob",
  "age" : 13,
  "other" : {
    "type" : "student"
  }
} 
*/
// Some parts of this json are modeled in our code, some are not
JsonNode root = mapper.readTree(complexJson);
Person p = mapper.treeToValue(root.get("person"), Person.class); // known single pojo
Map<String, Object> dynamicmetadata = mapper.treeToValue(root.get("dynamicmetadata"), Map.class); // unknown smallish subfield, convert all to collections
int singledeep = root.get("deep").get("large").get("hiearchy").get("important").intValue(); // single value in very deep optional subfield, ignoring the rest
int singledeeppath = root.at("/deep/large/hiearchy/important").intValue(); // json path
int singledeeppathunique = root.findValue("important").intValue(); // by unique field name

// Send an aggregate json from heterogenous sources
ObjectNode root = mapper.createObjectNode();
root.putPOJO("person", new Person("Joe")); // simple pojo
root.putPOJO("friends", List.of(new Person("Jane"), new Person("Jack"))); // generics
Map<String, Object> dynamicmetadata = Map.of("Some", "Metadata");
root.putPOJO("dynamicmetadata", dynamicmetadata);  // collections
root.putPOJO("dynamicmetadata", mapper.valueToTree(dynamicmetadata)); // same thing
root.set("dynamicmetadata", mapper.valueToTree(dynamicmetadata)); // same thing
root.withObject("deep").withObject("large").withObject("hiearchy").put("important", 42); // create as you go
root.withObject("/deep/large/hiearchy").put("important", 42); // json path
mapper.writeValueAsString(root);

配置

未知字段

//反序列化时候忽略未知字段(多的字段)    
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    Car car = objectMapper.readValue(jsonString, Car.class);
    
    JsonNode jsonNodeRoot = objectMapper.readTree(jsonString);
    JsonNode jsonNodeYear = jsonNodeRoot.get("year");
    String year = jsonNodeYear.asText();
//单个类反序列化时忽略未知字段
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDtoIgnoreUnknown { ... }
//反序列化时支持反序列化不完整的JSON

//设置是否允许基础字段为null
    objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
//是否允许将枚举值序列化/反序列化为数字
    objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);



忽略字段

基本都要用对应注解

四个维度:类,字段,过滤器,类型字段忽略

忽略null值

1.配置单个类或者单个字段用相应注解

2.mapper上配置

mapper.setSerializationInclusion(Include.NON_NULL);

字段别名

@JsonProperty注解

使用自定义序列化和反序列化

    public class CustomCarSerializer extends StdSerializer<Car> {

        public CustomCarSerializer() {
            this(null);
        }
    
        public CustomCarSerializer(Class<Car> t) {
            super(t);
        }
    
        @Override
        public void serialize(
          Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("car_brand", car.getType());
            jsonGenerator.writeEndObject();
        }
    }


    public class CustomCarDeserializer extends StdDeserializer<Car> {

        public CustomCarDeserializer() {
            this(null);
        }
    
        public CustomCarDeserializer(Class<?> vc) {
            super(vc);
        }
    
        @Override
        public Car deserialize(JsonParser parser, DeserializationContext deserializer) {
            Car car = new Car();
            ObjectCodec codec = parser.getCodec();
            JsonNode node = codec.readTree(parser);
            
            // try catch block
            JsonNode colorNode = node.get("color");
            String color = colorNode.asText();
            car.setColor(color);
            return car;
        }
    }



    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = 
      new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null));
    module.addSerializer(Car.class, new CustomCarSerializer());
    mapper.registerModule(module);
    Car car = new Car("yellow", "renault");
    String carJson = mapper.writeValueAsString(car);


String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
ObjectMapper mapper = new ObjectMapper();
SimpleModule module =
  new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Car.class, new CustomCarDeserializer());
mapper.registerModule(module);
Car car = mapper.readValue(json, Car.class);

处理日期格式

    ObjectMapper objectMapper = new ObjectMapper();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
    objectMapper.setDateFormat(df);
    String carAsString = objectMapper.writeValueAsString(request);
    // 输出: {"car":{"color":"yellow","type":"renault"},"datePurchased":"2016-07-03 11:43 AM CEST"}

类型转换

// Convert from List<Integer> to int[]
List<Integer> sourceList = ...;
int[] ints = mapper.convertValue(sourceList, int[].class);
// Convert a POJO into Map!
Map<String,Object> propertyMap = mapper.convertValue(pojoValue, Map.class);
// ... and back
PojoType pojo = mapper.convertValue(propertyMap, PojoType.class);
// decode Base64! (default byte[] representation is base64-encoded String)
String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz";
byte[] binary = mapper.convertValue(base64, byte[].class);

XML和对象系列

xml依赖

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.17.0</version>
        </dependency>

序列化字符串

XmlMapper xmlMapper = new XmlMapper();
    String xml = xmlMapper.writeValueAsString(new Person());

反序列化字符串

XmlMapper xmlMapper = new XmlMapper();
    SimpleBean value
      = xmlMapper.readValue("<SimpleBean><x>1</x><y>2</y></SimpleBean>", SimpleBean.class);

序列化xml文件

   xmlMapper.writeValue(new File("person_bean.xml"), new Person());

反序列化xml文件

XmlMapper xmlMapper = new XmlMapper();
    String xml = inputStreamToString(new FileInputStream(file));
    SimpleBean value = xmlMapper.readValue(xml, SimpleBean.class);

public String inputStreamToString(InputStream is) throws IOException {
    StringBuilder sb = new StringBuilder();
    String line;
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    while ((line = br.readLine()) != null) {
        sb.append(line);
    }
    br.close();
    return sb.toString();
}

List和xml的序列化和反序列化

<Person>
    <firstName>Rohan</firstName>
    <lastName>Daye</lastName>
    <phoneNumbers>
        <phoneNumbers>9911034731</phoneNumbers>
        <phoneNumbers>9911033478</phoneNumbers>
    </phoneNumbers>
    <address>
        <streetName>Name1</streetName>
        <city>City1</city>
    </address>
    <address>
        <streetName>Name2</streetName>
        <city>City2</city>
    </address>
</Person>

    public final class Person {
        private String firstName;
        private String lastName;
        private List<String> phoneNumbers = new ArrayList<>();
        @JacksonXmlElementWrapper(useWrapping = false)
        private List<Address> address = new ArrayList<>();
    
        //standard setters and getters
    }

XmlMapper xmlMapper = new XmlMapper();
        Person person = testPerson(); // test data
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        xmlMapper.writeValue(byteArrayOutputStream, person); 

高级特性

自定义序列化器根据属性值有条件的序列化对象

自定义序列化器根据属性值有条件的序列化对象

枚举类序列化和反序列化

//默认输出序列化枚举类 枚举名称

https://baeldung-cn.com/jackson-serialize-enums#45-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%99%A8

字段可见性

有两个维度,全局维度配置和类维度

objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);


@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class MyDtoNoAccessors { ... }

比较JSON对象

JsonNode.equals()
//    Jackson还提供了JsonNode.equals(comparator, JsonNode),以配置自定义Java比较器对象。
    
    
  //可以自定义比较器实现自己的比较逻辑
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值