精华内容
下载资源
问答
  • Jackson

    千次阅读 2013-09-24 17:41:37
    Jackson

    Jackson


    TODO

    展开全文
  • 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,感兴趣的同学可以看看。

    展开全文
  • jackson2.5.3

    热门讨论 2015-04-27 22:05:26
    jackson解析json一共需要三个jar包,分别是jackson-core-2.5.3.jar,jackson-databind-2.5.3.jar,jackson-annotations-2.5.3.jar.这里都有。
  • Jacksonjackson-databind

    万次阅读 2017-12-09 21:57:06
    前几篇介绍Jackson的文章(Jackson介绍,Jacksonjackson-core),虽然很好,但是我相信你并愿意在项目中使用,因为使用起来很复杂,也许这也是很多人愿意使用Fastjson的原因吧。为什么会感觉这么复杂呢,因为...

    原文链接:http://www.dubby.cn/detail.html?id=9070

    前几篇介绍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>

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

    POJO和JSON之间的转化

    给出一个足够简单的POJO:

    public class MyValue {
      public String name;
      public int age;
    }

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

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

    ObjectMapper mapper = new ObjectMapper(); 

    注意:这个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);

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

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

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

    集合、树

    如果你使用的不是简单的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);

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

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

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

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

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

    //如果结果可能是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"
    //   }
    // }

    上面的例子中的JSON如下:

    {
      "name" : "Bob", "age" : 13,
      "other" : {
         "type" : "student"
      }
    }

    如果 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();

    你也可以直接构造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);

    反序列化配置的例子:

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

    除此之外,还可以针对序列化和反序列化的底层细节指定一些配置,先给出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);

    再给出generation的配置:

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

    注解配置

    改变字段名

    注解@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);

    还有其他用法:

    // 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-annotations.jar jackson-core.jar jackson-databind.jar
  • 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相关资料,希望对...
  • jackson jar包 官方绿色完整版

    万次下载 热门讨论 2014-08-05 14:46:22
    jackson-annotations-2.2.1.jar jackson-core-2.2.1.jar jackson-core-asl-1.8.8.jar jackson-databind-2.2.1.jar jackson-mapper-asl-1.8.8.jar jackson-module-jaxb-annotations-2.2.1.jar
  • FasterXML Jackson

    2019-10-31 17:01:52
    本篇文章参考于简书:... 老版本的Jackson使用的包名为org.codehaus.jackson,而新版本使用的是com.fasterxml.jacksonJackson主要包含了3个模块: jackson-core jackson-annotations jackson-d...
  • Jackson 框架

    千次阅读 2015-12-23 12:09:50
    Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。Jackson 社 区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。 Spring MVC 的...
  • Jackson介绍

    千次阅读 2019-04-20 19:16:32
    1 Jackson概述 序列化和反序列化json的Java开源框架 Spring MVC的默认json解析器 1.1 优点 Jackson 所依赖的jar包较少,简单易用。 与其他 Java 的 json 的框架 Gson 等相比,Jackson 解析大的 json 文件速度比较...
  • jackson-core-asl-1.9.13+jackson-mapper-asl-1.9.13札包

    千次下载 热门讨论 2014-05-23 20:29:43
    jackson-core-asl-1.9.13.jar和jackson-mapper-asl-1.9.13.jar,在ssh整合中需要用到。
  • Jackson

    千次阅读 2020-05-02 15:11:49
    Jackson图 虽然程序中实际使用的数据结构种类繁多,但是他们的数据元素彼此之间的逻辑关系却只有顺序、选择和重复3类,因此,逻辑数据结构也只有这3类。 1.顺序结构 顺序结构的数据由一个或多个数据元素组成,每...
  • jackson详解

    万次阅读 2015-05-26 12:10:41
    java中常见的json解析有json-lib、jackson两种方案,前者是老牌技术,后者在解析大数据的时候性能比较好。现在又出现了很多json解析技术,如:fastjson、gson等。 一、springmvc默认使用的是jackson来解析json的,...
  • Jackson ObjectMapper

    2019-05-25 09:05:09
    Jackson 的 ObjectMapper 可以非常轻松的帮我们实现对象和 JSON 的互转,下面是一个简单的例子。 package shangbo.jackson.demo1; import java.util.ArrayList; import java.util.List; import ...
  • 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简介

    2018-11-17 23:19:41
    Jackson简介 Jackson作为一个知名,并且经典的Java平台的JSON库,有人说它是最好的JSON解析工具,或者只是一个简单的还行的JSON解析库,不管如何Jackson都是一个值得一学,值得一用的JSON处理库。 Jackson不仅支持...
  • SpringBoot Jackson

    千次阅读 2019-05-28 14:59:00
    1. SpringBoot JSON工具包默认是Jackson,只需要引入spring-boot-starter-web依赖包,自动引入相应依赖包:  <dependency> <groupId>com.fasterxml.jackson.core</groupId> <...
  • Jackson详解

    千次阅读 2017-09-05 18:57:37
    jackson对象和字符串及其数组对象和字符串相互转换1.maven引入Jackson包 <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core <version>2.7.4
  • jackson-annotations-2.2.3.jar jackson-core-2.2.3.jar jackson-databind-2.2.3.jar
  • jackson学习之二:jackson-core

    千次阅读 2020-09-14 08:23:42
    了解jackson最底层的功能逻辑
  • Jacksonjackson-core

    千次阅读 2017-12-09 17:19:27
    原文链接:http://www.dubby.cn/detail.html?id=9069我们在这里使用jackson-core提供的JsonParser和JsonGenerator来实现基本的序列化和反序列化。1.数据和实体类我们先定义出JSON字符串:{ "id":123456789, "text":...
  • Jackson库于2012.10.8号发布了最新的2.1版。Jackson源码目前托管于GitHub,地址:https://github.com/FasterXML/ 一、Jackson 2.x介绍 Jackson 2.x版提供了三个JAR包供下载: 1. Core库:strea...
  • jackson 讲解

    2018-05-05 15:56:45
    jackson-datebind: 依赖情况 &lt;properties&gt; ... &lt;!-- Use the latest version whenever possible. --&gt; &lt;jackson.version&gt;2.9.5&lt;/jackson.version&gt; ...
  • Jackson学习笔记(一)Jackson解析Json

    千次阅读 2019-08-20 22:26:00
    初识Jackson 导入jar文件: jackson-annotations-2.9.9.jar jackson-core-2.9.9.jar jackson-databind-2.9.9.jar 一、Jackson简介 1、Jackson Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java...
  • Jackson解析xml Jackson解析xml并不常用,推荐使用Dom4j 导入jar文件: //基本 jackson-annotations-2.9.9.jar jackson-core-2.9.9.jar jackson-databind-2.9.9.jar //支持XML jackson-dataformat-xml-2.9.8.jar...
  • jackson需要jar包

    热门讨论 2015-07-16 19:22:37
    jackson-all-1.7.6 jackson-annotations-2.4.0 jackson-core-2.4.4 jackson-core-asl-1.6.0 jackson-mapper-asl-1.6.0 jackson-databind-2.4.4

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,499
精华内容 11,399
关键字:

jackson