精华内容
参与话题
问答
  • Jackson

    千次阅读 2018-07-26 06:58:26
    Jackson Jackson is a Java JSON API which provides several different ways to work with JSON. Jackson is one of the most popular Java JSON APIs out there. You can find Jackson here: ...

    Jackson

    Jackson is a Java JSON API which provides several different ways to work with JSON. Jackson is one of the most popular Java JSON APIs out there. You can find Jackson here:

    https://github.com/FasterXML/jackson

    Jackson contains 2 different JSON parsers:

    • The Jackson ObjectMapper which parses JSON into custom Java objects, or into a Jackson specific tree structure (tree model).
    • The Jackson JsonParser which is Jackson’s JSON pull parser, parsing JSON one token at a time.

    Jackson also contains two JSON generators:

    • The Jackson ObjectMapper which can generate JSON from custom Java objects, or from a Jackson specific tree structure (tree model).
    • The Jackson JsonGenerator which can generate JSON one token at a time.

    1.0 Jackson Installation

    The Java JSON API called Jackson consists of one core JAR file (project) and two other JAR files that use the core JAR file. The three JAR files (projects) in the Jackson JSON API are:

    • Jackson Core
    • Jackson Annotations
    • Jackson Databind

    Jackson Gradle Dependencies

    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.3'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.3'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.3'

    Git Hub: https://github.com/FasterXML/jackson-core/releases

    2.0 Jackson ObjectMapper

    How Jackson ObjectMapper Matches JSON Fields to Java Fields

    By default Jackson maps the fields of a JSON object to fields in a Java object by matching the names of the JSON field to the getter and setter methods in the Java object. Jackson removes the “get” and “set” part of the names of the getter and setter methods, and converts the first character of the remaining name to lowercase.

    package com.zheting.jackson.demo;
    
    public class Car {
    
        private String brand = null;
        private int doors = 0;
    
        public Car() {
        }
    
        public Car(String brand, int doors) {
            this.brand = brand;
            this.doors = doors;
        }
    
        public String getBrand() {
            return this.brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public int getDoors() {
            return this.doors;
        }
    
        public void setDoors(int doors) {
            this.doors = doors;
        }
    }
    
    package com.zheting.jackson.demo;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.junit.Test;
    
    import java.io.*;
    import java.net.URL;
    import java.nio.charset.StandardCharsets;
    import java.util.List;
    
    /**
     * @author sheting
     */
    public class TestObjectMapper{
    
        /**
         * Read Object From JSON String
         */
        @Test
        public void testJsonToObject() throws IOException {
    
            ObjectMapper objectMapper = new ObjectMapper();
    
            //Ignore Unknown JSON Fields
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
            String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5, \"color\" : \" black \" }";
    
            Car car = objectMapper.readValue(carJson, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object From JSON Reader
         */
        @Test
        public void testJsonToObject2() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
    
            String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 4 }";
            Reader reader = new StringReader(carJson);
    
            Car car = objectMapper.readValue(reader, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object From JSON File
         */
        @Test
        public void testJsonToObject3() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
    
            File file = new File("src\\main\\resources\\data\\car.json");
    
            Car car = objectMapper.readValue(file, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object From JSON via URL
         */
        @Test
        public void testJsonToObject4() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
    
            //This example uses a file URL, but you can use an HTTP URL too
            URL url = new URL("file:D:\\dev\\learning\\json\\src\\main\\resources\\data\\car.json");
    
            Car car = objectMapper.readValue(url, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object From JSON InputStream
         */
        @Test
        public void testJsonToObject5() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
    
            InputStream input = new FileInputStream("src\\main\\resources\\data\\car.json");
    
            Car car = objectMapper.readValue(input, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object From JSON Byte Array
         */
        @Test
        public void testJsonToObject6() throws IOException {
            ObjectMapper objectMapper = new ObjectMapper();
    
            String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
    
            byte[] bytes = carJson.getBytes(StandardCharsets.UTF_8);
    
            Car car = objectMapper.readValue(bytes, Car.class);
    
            System.out.println("car brand = " + car.getBrand());
            System.out.println("car doors = " + car.getDoors());
        }
    
        /**
         * Read Object Array From JSON Array String
         */
        @Test
        public void testJsonToObject7() throws IOException {
            String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
    
            ObjectMapper objectMapper = new ObjectMapper();
    
            Car[] cars = objectMapper.readValue(jsonArray, Car[].class);
    
            System.out.println("car brand = " + cars[0].getBrand());
            System.out.println("car doors = " + cars[0].getDoors());
        }
    
        /**
         * Read Object List From JSON Array String
         */
        @Test
        public void testJsonToObject8() throws IOException {
            String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
    
            ObjectMapper objectMapper = new ObjectMapper();
    
            List<Car> cars = objectMapper.readValue(jsonArray, new TypeReference<List<Car>>(){});
    
            System.out.println("car brand = " + cars.get(0).getBrand());
            System.out.println("car doors = " + cars.get(0).getDoors());
        }
    
    
        @Test
        public void testObjectToJson() {
            ObjectMapper objectMapper = new ObjectMapper();
    
            Car car = new Car("BMW", 4);
    
            try {
                String json = objectMapper.writeValueAsString(car);
                System.out.println(json);  //{"brand":"BMW","doors":4}
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         *  Jackson has a built-in tree model which can be used to represent a JSON object.
         *  The Jackson tree model is represented by the JsonNode class.
         */
        @Test
        public void testJsonNode(){
            String carJson =
                    "{ \"brand\" : \"Mercedes\", \"doors\" : 5," +
                            "  \"owners\" : [\"John\", \"Jack\", \"Jill\"]," +
                            "  \"nestedObject\" : { \"field\" : \"value\" } }";
    
            ObjectMapper objectMapper = new ObjectMapper();
    
    
            try {
    
                JsonNode node = objectMapper.readValue(carJson, JsonNode.class);
    
                JsonNode brandNode = node.get("brand");
                String brand = brandNode.asText();
                System.out.println("brand = " + brand);
    
                JsonNode doorsNode = node.get("doors");
                int doors = doorsNode.asInt();
                System.out.println("doors = " + doors);
    
                JsonNode array = node.get("owners");
                JsonNode jsonNode = array.get(0);
                String john = jsonNode.asText();
                System.out.println("john  = " + john);
    
                JsonNode child = node.get("nestedObject");
                JsonNode childField = child.get("field");
                String field = childField.asText();
                System.out.println("field = " + field);
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    car.json

    {"brand" : "Mercedes", "doors" : 4}

    3.0 Jackson JsonParser

    The Jackson JsonParser works at a lower level than the Jackson ObjectMapper. This makes the JsonParser faster than the ObjectMapper, but also more cumbersome to work with.

    package com.zheting.jackson.demo;
    
    import com.fasterxml.jackson.core.JsonFactory;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonToken;
    import org.junit.Test;
    
    import java.io.IOException;
    
    /**
     * @author sheting
     */
    public class TestJsonParser {
    
        @Test
        public void testParseJson() throws IOException {
    
            //Creating a JsonParser
            String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
            JsonFactory factory = new JsonFactory();
            JsonParser parser  = factory.createParser(carJson);
    
            //Parsing JSON With the JsonParser
            Car car = new Car();
            while(!parser.isClosed()){
                JsonToken jsonToken = parser.nextToken();
    
                if(JsonToken.FIELD_NAME.equals(jsonToken)){
                    String fieldName = parser.getCurrentName();
                    System.out.println(fieldName);
    
                    jsonToken = parser.nextToken();
    
                    if("brand".equals(fieldName)){
                        car.setBrand(parser.getValueAsString());
                    } else if ("doors".equals(fieldName)){
                       car.setDoors(parser.getValueAsInt());
                    }
                }
            }
    
            System.out.println("car.brand = " + car.getBrand());
            System.out.println("car.doors = " + car.getDoors());
        }
    
    }
    

    4.0 Jackson JsonGenerator

    package com.zheting.jackson.demo;
    
    import com.fasterxml.jackson.core.JsonEncoding;
    import com.fasterxml.jackson.core.JsonFactory;
    import com.fasterxml.jackson.core.JsonGenerator;
    import org.junit.Test;
    
    import java.io.File;
    import java.io.IOException;
    
    /**
     * @author sheting
     */
    public class TestJsonGenerator {
    
        @Test
        public void testGenerateJson() throws IOException {
    
            //Creating a JsonGenerator
            JsonFactory factory = new JsonFactory();
    
            JsonGenerator generator = factory.createGenerator(new File("src\\main\\resources\\data\\out_car.json"), JsonEncoding.UTF8);
    
            //Generating JSON With The JsonGenerator
            generator.writeStartObject();
            generator.writeStringField("brand", "Mercedes");
            generator.writeNumberField("doors", 5);
            generator.writeEndObject();
    
            //Closing the JsonGenerator
            generator.close();
        }
    
    }
    

    5.0 Jackson Annotations

    Read + Write Annotations

    • @JsonIgnore
      The Jackson annotation @JsonIgnore is used to tell Jackson to ignore a certain property (field) of a Java object. The property is ignored both when reading JSON into Java objects, and when writing Java objects into JSON.

    • @JsonIgnoreProperties
      The @JsonIgnoreProperties Jackson annotation is used to specify a list of properties of a class to ignore. The @JsonIgnoreProperties annotation is placed above the class declaration instead of above the individual properties (fields) to ignore.

    • @JsonIgnoreType
      The @JsonIgnoreType Jackson annotation is used to mark a whole type (class) to be ignored everywhere that type is used.

    • @JsonAutoDetect
      The Jackson annotation @JsonAutoDetect is used to tell Jackson to include properties which are not public, both when reading and writing objects.
      The JsonAutoDetect.Visibility class contains constants matching the visibility levels in Java, meaning ANY, DEFAULT, NON_PRIVATE, NONE, PROTECTED_AND_PRIVATE and PUBLIC_ONLY.

    Read Annotations

    Jackson contains a set of annotations that only affect how Jackson parses JSON into objects - meaning they affect Jackson’s reading of JSON. I refer to these as “read annotations”. The following sections explains Jackson’s read annotations.

    • @JsonSetter
      The Jackson annotation @JsonSetter is used to tell Jackson that is should match the name of this setter method to a property name in the JSON data, when reading JSON into objects. This is useful if the property names used internally in your Java class is not the same as the property name used in the JSON file.

    Write Annotations

    Jackson also contains a set of annotations that can influence how Jackson serializes (writes) Java objects to JSON. Each of these write (serialization) annotations will be covered in the following sections.

    • @JsonInclude
      The Jackson annotation @JsonInclude tells Jackson only to include properties under certain circumstances. For instance, that properties should only be included if they are non-null, non-empty, or have non-default values.

    • @JsonGetter
      The @JsonGetter Jackson annotation is used to tell Jackson that a certain field value should be obtained from calling a getter method instead of via direct field access. The @JsonGetter annotation is useful if your Java class uses jQuery style for getter and setter names.

    • @JsonPropertyOrder
      The @JsonPropertyOrder Jackson annotation can be used to specify in what order the fields of your Java object should be serialized into JSON.

    • @JsonRawValue
      The @JsonRawValue Jackson annotation tells Jackson that this property value should written directly as it is to the JSON output.

      
      
    reference :http://tutorials.jenkov.com/java-json/index.html

    展开全文
  • jackson

    2013-11-19 14:57:34
    import java.io.File; import java.io.IOException; import java.util.Map; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonParseException;...import org.codehaus.jackson
    import java.io.File;
    import java.io.IOException;
    import java.util.Map;
    
    import org.codehaus.jackson.JsonGenerationException;
    import org.codehaus.jackson.JsonParseException;
    import org.codehaus.jackson.map.JsonMappingException;
    import org.codehaus.jackson.map.ObjectMapper;
    
    public class User {
    	int age;
    	int name;
    
    	public int getName() {
    		return name;
    	}
    
    	public void setName(int name) {
    		this.name = name;
    	}
    public static void main(String[] args) throws IOException {
    		String s = "{\"name\":123}";
    		ObjectMapper mapper = new ObjectMapper();
    		User a = mapper.readValue(s, User.class);
    		System.out.println(mapper.writeValueAsString(a));
    
    		// writeJsonObject();
    		// readJsonObject();
    		// readJsonMap();
    	}
    // 直接写入一个对象
    	public static void writeJsonObject() {
    		ObjectMapper mapper = new ObjectMapper();
    		Person person = new Person("nomouse", 25);
    		try {
    			mapper.writeValue(new File("c:/person.json"), person);
    		} catch (JsonGenerationException e) {
    			e.printStackTrace();
    		} catch (JsonMappingException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    // 直接将一个json转化为对象
    	public static void readJsonObject() {
    		ObjectMapper mapper = new ObjectMapper();
    		try {
    			Person person = mapper.readValue(new File("c:/person.json"),
    					Person.class);
    			System.out.println(person.getName() + ":" + person.getAge());
    		} catch (JsonParseException e) {
    			e.printStackTrace();
    		} catch (JsonMappingException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    // 直接转化为map
    	public static void readJsonMap() {
    		ObjectMapper mapper = new ObjectMapper();
    		try {
    			// 需要注意的是这里的Map实际为一个LikedHashMap,即链式哈希表,可以按照读入顺序遍历
    			Map map = mapper.readValue(new File("c:/person.json"), Map.class);
    			System.out.println(map.get("name") + ":" + map.get("age"));
    		} catch (JsonParseException e) {e.printStackTrace();
    		} catch (JsonMappingException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    class Person {
    	private String name;
    	private int age;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public Person(String name, int age) {
    		this.name = name;
    		this.age = age;
    	}
    
    	public Person() {
    	}
    
    }
    

    展开全文
  • jackson-databind jackson-annatation jackson-core jackson-mapper
  • Jackson快速入门

    万次阅读 多人点赞 2018-05-30 00:36:26
    Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个。虽然JDK自带了XML处理类库,但是相对来说比较低级,使用本文介绍的Jackson等高级类库处理起来会方便很多。 引入类库 由于Jackson...

    Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个。虽然JDK自带了XML处理类库,但是相对来说比较低级,使用本文介绍的Jackson等高级类库处理起来会方便很多。

    引入类库

    由于Jackson相关类库按照功能分为几个相对独立的,所以需要同时引入多个类库,为了方便我将版本号单独提取出来设置,相关Gradle配置如下。

    ext {
        jacksonVersion = '2.9.5'
    }
    
    dependencies {
        compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
        compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
        compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
        // 引入XML功能
        compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: jacksonVersion
        // 比JDK自带XML实现更高效的类库
        compile group: 'com.fasterxml.woodstox', name: 'woodstox-core', version: '5.1.0'
        // Java 8 新功能
        compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: jacksonVersion
        compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: jacksonVersion
        compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: jacksonVersion
    
        compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.22'
    }

    Maven配置请去mvnrepository搜索。

    Jackson注解

    Jackson类库包含了很多注解,可以让我们快速建立Java类与JSON之间的关系。详细文档可以参考Jackson-Annotations。下面介绍一下常用的。

    属性命名

    @JsonProperty注解指定一个属性用于JSON映射,默认情况下映射的JSON属性与注解的属性名称相同,不过可以使用该注解的value值修改JSON属性名,该注解还有一个index属性指定生成JSON属性的顺序,如果有必要的话。

    属性包含

    还有一些注解可以管理在映射JSON的时候包含或排除某些属性,下面介绍一下常用的几个。

    @JsonIgnore注解用于排除某个属性,这样该属性就不会被Jackson序列化和反序列化。

    @JsonIgnoreProperties注解是类注解。在序列化为JSON的时候,@JsonIgnoreProperties({"prop1", "prop2"})会忽略pro1和pro2两个属性。在从JSON反序列化为Java类的时候,@JsonIgnoreProperties(ignoreUnknown=true)会忽略所有没有Getter和Setter的属性。该注解在Java类和JSON不完全匹配的时候很有用。

    @JsonIgnoreType也是类注解,会排除所有指定类型的属性。

    序列化相关

    @JsonPropertyOrder@JsonPropertyindex属性类似,指定属性序列化时的顺序。

    @JsonRootName注解用于指定JSON根属性的名称。

    处理JSON

    简单映射

    我们用Lombok设置一个简单的Java类。

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Friend {
        private String nickname;
        private int age;
    }

    然后就可以处理JSON数据了。首先需要一个ObjectMapper对象,序列化和反序列化都需要它。

            ObjectMapper mapper = new ObjectMapper();
            Friend friend = new Friend("yitian", 25);
    
            // 写为字符串
            String text = mapper.writeValueAsString(friend);
            // 写为文件
            mapper.writeValue(new File("friend.json"), friend);
            // 写为字节流
            byte[] bytes = mapper.writeValueAsBytes(friend);
            System.out.println(text);
            // 从字符串中读取
            Friend newFriend = mapper.readValue(text, Friend.class);
            // 从字节流中读取
            newFriend = mapper.readValue(bytes, Friend.class);
            // 从文件中读取
            newFriend = mapper.readValue(new File("friend.json"), Friend.class);
            System.out.println(newFriend);

    程序结果如下。可以看到生成的JSON属性和Java类中定义的一致。

    {"nickname":"yitian","age":25}
    Friend(nickname=yitian, age=25)

    集合的映射

    除了使用Java类进行映射之外,我们还可以直接使用Map和List等Java集合组织JSON数据,在需要的时候可以使用readTree方法直接读取JSON中的某个属性值。需要注意的是从JSON转换为Map对象的时候,由于Java的类型擦除,所以类型需要我们手动用new TypeReference<T>给出。

            ObjectMapper mapper = new ObjectMapper();
    
            Map<String, Object> map = new HashMap<>();
            map.put("age", 25);
            map.put("name", "yitian");
            map.put("interests", new String[]{"pc games", "music"});
    
            String text = mapper.writeValueAsString(map);
            System.out.println(text);
    
            Map<String, Object> map2 = mapper.readValue(text, new TypeReference<Map<String, Object>>() {
            });
            System.out.println(map2);
    
            JsonNode root = mapper.readTree(text);
            String name = root.get("name").asText();
            int age = root.get("age").asInt();
    
            System.out.println("name:" + name + " age:" + age);

    程序结果如下。

    {"name":"yitian","interests":["pc games","music"],"age":25}
    {name=yitian, interests=[pc games, music], age=25}
    name:yitian age:25

    Jackson配置

    Jackson预定义了一些配置,我们通过启用和禁用某些属性可以修改Jackson运行的某些行为。详细文档参考JacksonFeatures。下面我简单翻译一下Jackson README上列出的一些属性。

    // 美化输出
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    // 允许序列化空的POJO类
    // (否则会抛出异常)
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    // 把java.util.Date, Calendar输出为数字(时间戳)
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    
    // 在遇到未知属性的时候不抛出异常
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    // 强制JSON 空字符串("")转换为null对象值:
    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
    
    // 在JSON中允许C/C++ 样式的注释(非标准,默认禁用)
    mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
    // 允许没有引号的字段名(非标准)
    mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    // 允许单引号(非标准)
    mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    // 强制转义非ASCII字符
    mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
    // 将内容包裹为一个JSON属性,属性名由@JsonRootName注解指定
    mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

    这里有三个方法,configure方法接受配置名和要设置的值,Jackson 2.5版本新加的enable和disable方法则直接启用和禁用相应属性,我推荐使用后面两个方法。

    用注解管理映射

    前面介绍了一些Jackson注解,下面来应用一下这些注解。首先来看看使用了注解的Java类。

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonRootName("FriendDetail")
    @JsonIgnoreProperties({"uselessProp1", "uselessProp3"})
    public class FriendDetail {
        @JsonProperty("NickName")
        private String name;
        @JsonProperty("Age")
        private int age;
        private String uselessProp1;
        @JsonIgnore
        private int uselessProp2;
        private String uselessProp3;
    }

    然后看看代码。需要注意的是,由于设置了排除的属性,所以生成的JSON和Java类并不是完全对应关系,所以禁用DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES是必要的。

            ObjectMapper mapper = new ObjectMapper();
            //mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
            mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            FriendDetail fd = new FriendDetail("yitian", 25, "", 0, "");
            String text = mapper.writeValueAsString(fd);
            System.out.println(text);
    
            FriendDetail fd2 = mapper.readValue(text, FriendDetail.class);
            System.out.println(fd2);

    运行结果如下。可以看到生成JSON的时候忽略了我们制定的值,而且在转换为Java类的时候对应的属性为空。

    {"NickName":"yitian","Age":25}
    FriendDetail(name=yitian, age=25, uselessProp1=null, uselessProp2=0, uselessProp3=null)

    然后取消注释代码中的那行,也就是启用WRAP_ROOT_VALUE功能,再运行一下程序,运行结果如下。可以看到生成的JSON结果发生了变化,而且由于JSON结果变化,所以Java类转换失败(所有字段值全为空)。WRAP_ROOT_VALUE这个功能在有些时候比较有用,因为有些JSON文件需要这种结构。

    {"FriendDetail":{"NickName":"yitian","Age":25}}
    FriendDetail(name=null, age=0, uselessProp1=null, uselessProp2=0, uselessProp3=null)

    Java8日期时间类支持

    Java8增加了一套全新的日期时间类,Jackson对此也有支持。这些支持是以Jackson模块形式提供的,所以首先就是注册这些模块。

            ObjectMapper mapper = new ObjectMapper()
                    .registerModule(new JavaTimeModule())
                    .registerModule(new ParameterNamesModule())
                    .registerModule(new Jdk8Module());

    导入类库之后,Jackson也可以自动搜索所有模块,不需要我们手动注册。

            mapper.findAndRegisterModules();

    我们新建一个带有LocalDate字段的Java类。

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonRootName("Person")
    public class Person {
        @JsonProperty("Name")
        private String name;
        @JsonProperty("NickName")
        private String nickname;
        @JsonProperty("Age")
        private int age;
        @JsonProperty("IdentityCode")
        private String identityCode;
        @JsonProperty
        @JsonFormat(pattern = "yyyy-MM-DD")
        private LocalDate birthday;
    
    }

    然后来看看代码。

        static void java8DateTime() throws IOException {
            Person p1 = new Person("yitian", "易天", 25, "10000", LocalDate.of(1994, 1, 1));
            ObjectMapper mapper = new ObjectMapper()
                    .registerModule(new JavaTimeModule());
            //mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            String text = mapper.writeValueAsString(p1);
            System.out.println(text);
    
            Person p2 = mapper.readValue(text, Person.class);
            System.out.println(p2);
        }

    运行结果如下。可以看到,生成的JSON日期变成了[1994,1,1]这样的时间戳形式,一般情况下不符合我们的要求。

    {"birthday":[1994,1,1],"Name":"yitian","NickName":"易天","Age":25,"IdentityCode":"10000"}
    Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

    取消注释那行代码,程序运行结果如下。这样一来就变成了我们一般使用的形式了。如果有格式需要的话,可以使用@JsonFormat(pattern = "yyyy-MM-DD")注解格式化日期显示。

    {"birthday":"1994-01-01","Name":"yitian","NickName":"易天","Age":25,"IdentityCode":"10000"}
    Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

    处理XML

    Jackson是一个处理JSON的类库,不过它也通过jackson-dataformat-xml包提供了处理XML的功能。Jackson建议我们在处理XML的时候使用woodstox-core包,它是一个XML的实现,比JDK自带XML实现更加高效,也更加安全。

    这里有个注意事项,如果你正在使用Java 9以上的JDK,可能会出现java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException异常,这是因为Java 9实现了JDK的模块化,将原本和JDK打包在一起的JAXB实现分隔出来。所以这时候需要我们手动添加JAXB的实现。在Gradle中添加下面的代码即可。

    compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'

    注解

    Jackson XML除了使用Jackson JSON和JDK JAXB的一些注解之外,自己也定义了一些注解。下面简单介绍一下几个常用注解。

    @JacksonXmlProperty注解有三个属性,namespace和localname属性用于指定XML命名空间的名称,isAttribute指定该属性作为XML的属性()还是作为子标签().

    @JacksonXmlRootElement注解有两个属性,namespace和localname属性用于指定XML根元素命名空间的名称。

    @JacksonXmlText注解将属性直接作为未被标签包裹的普通文本表现。

    @JacksonXmlCData将属性包裹在CDATA标签中。

    XML映射

    新建如下一个Java类。

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonRootName("Person")
    public class Person {
        @JsonProperty("Name")
        private String name;
        @JsonProperty("NickName")
        //@JacksonXmlText
        private String nickname;
        @JsonProperty("Age")
        private int age;
        @JsonProperty("IdentityCode")
        @JacksonXmlCData
        private String identityCode;
        @JsonProperty("Birthday")
        //@JacksonXmlProperty(isAttribute = true)
        @JsonFormat(pattern = "yyyy/MM/DD")
        private LocalDate birthday;
    
    }

    下面是代码示例,基本上和JSON的API非常相似,XmlMapper实际上就是ObjectMapper的子类。

            Person p1 = new Person("yitian", "易天", 25, "10000", LocalDate.of(1994, 1, 1));
            XmlMapper mapper = new XmlMapper();
            mapper.findAndRegisterModules();
            mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            String text = mapper.writeValueAsString(p1);
            System.out.println(text);
    
            Person p2 = mapper.readValue(text, Person.class);
            System.out.println(p2);

    运行结果如下。

    <Person>
      <Name>yitian</Name>
      <NickName>易天</NickName>
      <Age>25</Age>
      <IdentityCode><![CDATA[10000]]></IdentityCode>
      <Birthday>1994/01/01</Birthday>
    </Person>
    
    Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

    如果取消那两行注释,那么运行结果如下。可以看到Jackson XML注解对生成的XML的控制效果。

    <Person birthday="1994/01/01">
      <Name>yitian</Name>易天
      <Age>25</Age>
      <IdentityCode><![CDATA[10000]]></IdentityCode>
    </Person>
    
    Person(name=yitian, nickname=null, age=25, identityCode=10000, birthday=1994-01-01)

    Spring Boot集成

    自动配置

    Spring Boot对Jackson的支持非常完善,只要我们引入相应类库,Spring Boot就可以自动配置开箱即用的Bean。Spring自动配置的ObjectMapper(或者XmlMapper)作了如下配置,基本上可以适应大部分情况。

    • 禁用了MapperFeature.DEFAULT_VIEW_INCLUSION
    • 禁用了DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
    • 禁用了SerializationFeature.WRITE_DATES_AS_TIMESTAMPS

    如果需要修改自动配置的ObjectMapper属性也非常简单,Spring Boot提供了一组环境变量,直接在application.properties文件中修改即可。

    |Jackson枚举|Spring环境变量|
    |—–|—–|
    com.fasterxml.jackson.databind.DeserializationFeature|spring.jackson.deserialization.=true|false
    com.fasterxml.jackson.core.JsonGenerator.Feature|spring.jackson.generator.=true|false
    com.fasterxml.jackson.databind.MapperFeature|spring.jackson.mapper.=true|false
    com.fasterxml.jackson.core.JsonParser.Feature|spring.jackson.parser.=true|false
    com.fasterxml.jackson.databind.SerializationFeature|spring.jackson.serialization.=true|false
    com.fasterxml.jackson.annotation.JsonInclude.Include|spring.jackson.default-property-inclusion=always|non_null|non_absent|non_default|non_empty

    由于Spring会同时配置相应的HttpMessageConverters,所以我们其实要做的很简单,用Jackson注解标注好要映射的Java类,然后直接让控制器返回对象即可!下面是一个Java类。

    @JsonRootName("person")
    public class Person {
        @JsonProperty
        private String name;
        @JsonProperty
        private int id;
        @JsonFormat(pattern = "yyyy-MM-DD")
        private LocalDate birthday;
    
        public Person(String name, int id, LocalDate birthday) {
            this.name = name;
            this.id = id;
            this.birthday = birthday;
        }
    }

    然后是控制器代码。在整个过程中我们只需要引入Jackson类库,然后编写业务代码就好了。关于如何配置Jackson类库,我们完全不需要管,这就是Spring Boot的方便之处。

    @Controller
    public class MainController {
        private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));
    
        @RequestMapping("/")
        public String index() {
            return "index";
        }
    
    
        @RequestMapping(value = "/json", produces = "application/json")
        @ResponseBody
        public Person json() {
            return person;
        }
    }

    进入localhost:8080/xml就可以看到对应结果了。
    结果

    手动配置

    Spring Boot自动配置非常方便,但不是万能的。在必要的时候,我们需要手动配置Bean来替代自动配置的Bean。

    @Configuration
    public class JacksonConfig {
        @Bean
        @Primary
        @Qualifier("xml")
        public XmlMapper xmlMapper(Jackson2ObjectMapperBuilder builder) {
            XmlMapper mapper = builder.createXmlMapper(true)
                    .build();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            return mapper;
        }
    
        @Bean
        @Qualifier("json")
        public ObjectMapper jsonMapper(Jackson2ObjectMapperBuilder builder) {
            ObjectMapper mapper = builder.createXmlMapper(false)
                    .build();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            return mapper;
        }
    }

    然后在需要的地方进行依赖注入。需要注意为了区分ObjectMapper和XmlMapper,需要使用@Qualifier注解进行标记。

    @Controller
    public class MainController {
        private ObjectMapper jsonMapper;
        private XmlMapper xmlMapper;
        private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));
    
        public MainController(@Autowired @Qualifier("json") ObjectMapper jsonMapper, @Autowired @Qualifier("xml") XmlMapper xmlMapper) {
            this.jsonMapper = jsonMapper;
            this.xmlMapper = xmlMapper;
        }

    以上就是Jackson类库的一些介绍,希望对大家有所帮助。项目代码在我的Github,感兴趣的同学可以看看。

    展开全文
  • Jacksonjackson-databind

    2020-03-22 22:00:28
    原文链接:http://www.dubby.cn/detail.html?id=9070 前几篇介绍Jackson的文章(Jac...

    前几篇介绍Jackson的文章(Jackson介绍Jackson之jackson-core),虽然很好,但是我相信你并愿意在项目中使用,因为使用起来很复杂,也许这也是很多人愿意使用Fastjson的原因吧。为什么会感觉这么复杂呢,因为jackson-core提供的是很低级的API,我们可以充分的了解细节,但是代价就是操作起来更复杂。

    这篇文章介绍使用高级的API,让你看到Jackson也可以这么的简单,容易。

    Maven依赖

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.2</version>
    </dependency>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    因为jackson-databind依赖core和annotations,所以在这里需要依赖这三个jar。

    POJO和JSON之间的转化

    给出一个足够简单的POJO:

    public class MyValue {
      public String name;
      public int age;
    }
    • 1
    • 2
    • 3
    • 4

    注意:如果使用getters/setters的话,可以用private/protected修饰属性,这里直接用public修饰了,就不需要getters/setters了。

    使用databind,我们需要一个最基础的对象com.fasterxml.jackson.databind.ObjectMapper,这里我们构造一个:

    ObjectMapper mapper = new ObjectMapper(); 
    • 1

    注意:这个mapper是可以复用的,就好比HttpClient一样。

    简单的把JSON反序列化成Object的用法如下:

    MyValue value = mapper.readValue(new File("data.json"), MyValue.class);
    // or:
    value = mapper.readValue(new URL("http://www.dubby.cn/api/entry.json"), MyValue.class);
    // or:
    value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);
    • 1
    • 2
    • 3
    • 4
    • 5

    简单的把Object序列化成JSON的用法如下:

    mapper.writeValue(new File("result.json"), myResultObject);
    // or:
    byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
    // or:
    String jsonString = mapper.writeValueAsString(myResultObject);
    • 1
    • 2
    • 3
    • 4
    • 5

    其实到这一步,对于很多读者来说已经足够了。因为大部分时候我们要的就是这些。但是不妨继续看下去,还有一些你可能会用到的。

    集合、树

    如果你使用的不是简单的POJO,而是List,Map:

    Map<String, Integer> scoreByName = mapper.readValue(jsonSource, Map.class);
    List<String> names = mapper.readValue(jsonSource, List.class);
    
    mapper.writeValue(new File("names.json"), names);
    • 1
    • 2
    • 3
    • 4

    如果你反序列化的更复杂,你可以指定类型:

    Map<String, ResultValue> results = mapper.readValue(jsonSource, new TypeReference<Map<String, ResultValue>>() { } );
    • 1

    思考:为什么需要指定类型?(类型擦除)

    注意:序列化的时候不需要指定,只有反序列化的时候需要。

    虽然看起来处理的很方便,但是某些时候会有一些很麻烦的情况,这时候可以考虑使用树模型:

    //如果结果可能是Object或者是Array,那可以使用JsonNode;
    //如果你知道是Object,你可以直接强转成ObjectNode;如果你知道是Array,你可以直接强转成ArrayNode;
    ObjectNode root = (ObjectNode) mapper.readTree("stuff.json");
    String name = root.get("name").asText();
    int age = root.get("age").asInt();
    
    // 还可以修改这个树,然后再输出成json字符串
    root.with("other").put("type", "student");
    String json = mapper.writeValueAsString(root);
    
    // with above, we end up with something like as 'json' String:
    // {
    //   "name" : "Bob", "age" : 13,
    //   "other" : {
    //      "type" : "student"
    //   }
    // }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    上面的例子中的JSON如下:

    {
      "name" : "Bob", "age" : 13,
      "other" : {
         "type" : "student"
      }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果 json 类型太过动态,不适合反序列化成对象的时候,树模型比数据绑定更合适。

    流式解析器、生成器

    看完上面的介绍,我想你应该相当满意ObjectMapper的能力了,但是如果你希望控制底层的一些细节,或者对性能有更高的要求,你可以通过ObjectMapper来设置。建议你先看看Jackson之jackson-core:

    JsonFactory f = mapper.getFactory();
    // 1、输入JSON字符串
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    JsonGenerator g = f.createGenerator(outputStream);
    // 输出JSON: { "message" : "Hello world!" }
    g.writeStartObject();
    g.writeStringField("message", "Hello world!");
    g.writeEndObject();
    g.close();
    // 2、把JSON字符串反序列化
    JsonParser p = f.createParser(outputStream.toString());
    JsonToken t = p.nextToken(); // Should be JsonToken.START_OBJECT
    t = p.nextToken(); // JsonToken.FIELD_NAME
    if ((t != JsonToken.FIELD_NAME) || !"message".equals(p.getCurrentName())) {
        // handle error
    }
    t = p.nextToken();
    if (t != JsonToken.VALUE_STRING) {
        // similarly
    }
    String msg = p.getText();
    System.out.printf("My message to you is: %s!\n", msg);
    p.close();
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    你也可以直接构造JsonFactory,然后作为构造参数传给ObjectMapper

    配置

    有两个方面的配置,特性注解

    特性配置

    给出一个简单的使用特性配置的例子,先给出序列化配置:

    // 设置序列化成漂亮的JSON,而不是压缩的字符串
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    // 如果你要序列化的对象没有字段(很搞笑吧),会抛异常,可以设置这个来避免异常,直接序列化成`{}`
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    // 默认Date会序列化成时间戳,可以设置这个来序列化成`date":"2017-12-09T12:50:13.000+0000`这个样子
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    反序列化配置的例子:

    // 默认,如果反序列化时,JSON字符串里有字段,而POJO中没有定义,会抛异常,可以设置这个来忽略未定义的字段
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    // 默认如果是字符串(""),反序列化会失败,可以开启这个设置,字符串("")会被反序列化成(null)
    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
    • 1
    • 2
    • 3
    • 4

    除此之外,还可以针对序列化和反序列化的底层细节指定一些配置,先给出parsing的配置:

    // 默认如果JSON中有C/C++风格的注释,在反序列化的时候会报错,可以指定这个配置来忽略C/C++风格的注释
    mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
    //默认JSON字符串如果字段名没有用双引号包裹,回报错,可以设置这个来支持这种非正规的JSON(JS支持这种非正规的JSON)
    mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    // 默认如果JSON中是用的单引号包裹字段和值,反序列化时会报错,可以设置这个来兼容单引号这种非正规的JSON
    mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    再给出generation的配置:

    // 把非ASCII转义成ASCII值,如(杨正)会被转义成(\u6768\u6B63)
    mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
    • 1
    • 2

    注解配置

    改变字段名

    注解@JsonProperty:

    public class MyBean {
       private String _name;
    
       // 默认是`theName`,现在改为`name`
       @JsonProperty("name")
       public String getTheName() { return _name; }
    
       // 只需要修饰getter或者setter其中的一个就可以了,这里可以省略不写
       public void setTheName(String n) { _name = n; }
    }

    忽略字段

    @JsonIgnore可以忽略单个字段,@JsonIgnoreProperties可以加在类定义上:

    // 序列化和反序列化时,直接忽略JSON中的foo和bar字段
    @JsonIgnoreProperties({ "foo", "bar" })
    public class MyBean
    {
       // 序列化和反序列化时,直接忽略JSON中的internal字段
       @JsonIgnore
       public String internal;
    
       // 正常字段
       public String external;
    
       @JsonIgnore
       public void setCode(int c) { _code = c; }
    
       // 虽然这里没有修饰,但是setter被修饰了,所以也会被忽略
       public int getCode() { return _code; }
    }

    从上面我们可以看出,注解在字段名、setter和getter上都是一样的,修饰任何一个都会直接忽略这个字段,但是我们可以值忽略反序列化,而不忽略序列化,或者反之:

    public class ReadButDontWriteProps {
       private String _name;
       @JsonProperty public void setName(String n) { _name = n; }
       @JsonIgnore public String getName() { return _name; }
    }

    这里使用@JsonProperty保证,虽然序列化是name会被忽略,但是从JSON中反序列化时,可以正常接收这个字段。

    自定义构造方法

    和其他数据绑定工具不一样,Jackson不会强制要求你的POJO必须有个默认构造方法(无参构造方法)。你可以指定一个构造方法来接收反序列化的字段值:

    public class CtorBean
    {
      public final String name;
      public final int age;
    
      @JsonCreator
      private CtorBean(@JsonProperty("name") String name,
        @JsonProperty("age") int age)
      {
          this.name = name;
          this.age = age;
      }
    }

    构造方法可以是public,private或者任何其他修饰符修饰

    对于一些不可改变的对象,这个会很有用,除了构造方法,@JsonCreator这个注解还可以定义一个工厂方法:

    public class FactoryBean
    {
        // fields etc omitted for brewity
    
        @JsonCreator
        public static FactoryBean create(@JsonProperty("name") String name) {
          // construct and return an instance
        }
    }

    注意:构造方法(@JsonCreator@JsonProperty)和setter不互斥,你可以混合使用。

    填充、转换

    Jackson还有一个很有意思的功能,虽然没有广泛的被人所知道。那就是POJO和POJO之间的转换。概念性的可以理解成POJO1->JSON->POJO2,但是实际上会省略中间这一步,不会真正的生成JSON,而会用其他更高效的实现:

    ResultType result = mapper.convertValue(sourceObject, ResultType.class);
    • 1

    还有其他用法:

    // List<Integer> -> int[]
    List<Integer> sourceList = ...;
    int[] ints = mapper.convertValue(sourceList, int[].class);
    // POJO -> Map
    Map<String,Object> propertyMap = mapper.convertValue(pojoValue, Map.class);
    // Map -> POJO
    PojoType pojo = mapper.convertValue(propertyMap, PojoType.class);
    // decode Base64! (default byte[] representation is base64-encoded String)

    甚至还可以解码base64码:

    //解码
    String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz";
    byte[] binary = mapper.convertValue(base64, byte[].class);
    System.out.println(new String(binary));
    //编码
    String str = "Man is distinguished, not only by his reason, but by this";
    String base = mapper.convertValue(str.getBytes(), String.class);
    System.out.println(base);

    所以,Jackson甚至强大到可以代替Apache Commons组件。

    展开全文
  • Jackson基础教程

    千次阅读 2019-04-22 00:02:22
    Jackson目前有2个版本 1.x版本包名为org.codehaus.jackson 2.x版本包名为com.fasterxml.jackson 使用 Spring Boot Web项目默认引入了Jackson,其他项目只要在pom文件中加入依赖即可 参考博客 ...
  • Jackson

    千次阅读 2020-05-02 15:11:49
    Jackson图 虽然程序中实际使用的数据结构种类繁多,但是他们的数据元素彼此之间的逻辑关系却只有顺序、选择和重复3类,因此,逻辑数据结构也只有这3类。 1.顺序结构 顺序结构的数据由一个或多个数据元素组成,每...
  • 在本文中,我们将展示如何根据Spring Security中定义的用户角色过滤JSON序列化输出。 为什么我们需要过滤? 让我们考虑一个简单但常见的用例,我们有一个Web应用程序,为不同角色的用户提供服务。...
  • jackson-jar

    千次下载 热门讨论 2013-07-20 20:34:32
    jackson所需要的所有jar jackson-all-1.6.2.jar jackson-core-asl-1.6.2.jar jackson-mapper-asl-1.6.2.jar jakarta-oro.jar 1. 背景 目前维护的产品使用jackson处理json,现整理一下jackson相关资料,希望对...
  • com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 5)): only regular white space (\r, \n, \t) is allowed between tokens at [Source: �z��& �r#�$�3S "; line: 1, ...
  • jackson-2.9.6

    2018-09-24 11:16:33
    这个压缩包包含了Jackson的最新版本(截止2018.09.24),包含jackson-annotations-2.9.6,jackson-core-2.9.6,jackson-databind-2.9.6

空空如也

1 2 3 4 5 ... 20
收藏数 22,906
精华内容 9,162
关键字:

jackson