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

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

    Jackson


    TODO

    展开全文
  • jackson

    2018-08-25 19:26:39
    使用JSON是需要的jar包,加压后即可导入项目使用。
  • jackson-databind jackson-annatation jackson-core jackson-mapper
  • jackson json

    2017-09-14 23:44:56
    jackson json jackson json jackson jsonjackson jsonjackson jsonjackson jsonjackson jsonjackson jsonjackson json
  • jackson 1.9.13

    2019-01-04 16:17:02
    Jackson 1.9.13
  • jackson2.9.7

    2018-11-04 10:12:00
    Jackson2.9。7版本 包含 jackson-core-2.9.7.jar, jackson-annotations-2.9.7.jar, jackson-databind-2.9.7.jar
  • jackson2.9.6(jackson-annotations-2.9.6.jar、jackson-core-2.9.6.jar、jackson-databind-2.9.6.jar)3个jar包齐全。
  • Jackson 入门Jackson 入门

    2011-06-11 19:41:52
    Jackson 入门 Jackson 入门 Jackson 入门
  • jackson databind

    2018-02-28 18:04:58
    jackson-databind-2.7.0.jar jackson-databind-2.7.0.jar jackson-databind-2.7.0.jar jackson-databind-2.7.0.jar
  • jackson2.8

    2017-11-16 10:38:50
    包含jackson-core-2.8.2.jar, jackson-annotations-2.8.5.jar,jackson-databind-2.8.5.jar
  • jackson 2.9.3 jar文件与jackson 2.9.3源码文件,打包成了一个zip
  • Jackson API

    2016-04-12 18:06:09
    Jackson API
  • 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.9 搭配spring4使用,如果版本不符合,会出现“http请求415错误Unsupported Media Type”错误
  • jacksonJackson项目的主门户页面
  • 最新jackson

    2016-03-25 09:06:05
    jackson的三个jar包:jackson-annotations-2.7.3.jar和jackson-core-2.7.3.jar以及jackson-databind-2.6.5.jar
  • jackson2.96

    2018-07-13 15:44:38
    版本:jackson2.96 三个jar包: jackson-core-2.96.jar jackson-annotations-2.96.jar jackson-databind-2.96.jar 与spring5.0兼容。
  • jackson2.2.3

    2015-10-24 15:02:00
    jackson所需jar jackson-databind-2.2.3.jar jackson-core-2.2.3.jar jackson-annotations-2.2.3.jar
  • 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.这里都有。
  • jackson.zip

    2020-03-31 12:51:00
    jackson-2.8.3三个jar包 jackson-core-2.8.3.jar、jackson-annotations-2.8.3.jar、jackson-databind
  • Jackson1.9.7

    2015-08-27 14:02:00
    Jackson1.9.7相关包,包括 jackson-core-asl-1.9.7.jar jackson-core-lgpl-1.9.7.jar jackson-mapper-asl-1.9.7.jar jackson-mapper-lgpl-1.9.7.jar 该包文件支持SpringMVC的Jackson功能,并附有相关配置文件
  • 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组件。

    展开全文
  • Java-Jackson使用详解

    万次阅读 多人点赞 2021-03-18 17:59:24
    Java下利用Jackson进行JSON解析和序列化。Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换。 讲解了Json是什么:基本规则、获取数据、用途 如何使用Jackson进行Json与Java对象之间的相互...
     
     

    Java-Jackson使用详解

    序列化

    Json是什么?

    1.基本规则

    2.获取数据

    3.用途

    Jackson

    1.导入Jar包

    2.Json注解

    3.Json转为Java对象

    4.Java对象转换Json


    序列化

    序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

    Json是什么?

    Jason是 JavaScript Object Notation—  JavaScript对象表示法,是一种轻量级数据交换格式。主要用于数据传输,比如说在后端写了一个Java对象,想在其他地方(前端)使用这个对象,就需要转换为Json这种形式进行传输。

    1.基本规则

      数据在名称/值对中:json数据是由键值对构成的

         值用引号引起来,也可以不使用引号

         值的取值类型: 数字、字符串、布尔值、数组(如{"persons":[{},{},{}]})、对象、null

         数据用逗号分隔:多个键值对由逗号分隔

         方括号保存数组:[]

         花括号保存对象:使用{}定义json格式

    2.获取数据

        json对象.键名

        json对象["键名"]

        数组对象[索引]

        遍历

    3.用途

       以某种存储形式使自定义对象持久化;

       将对象从一个地方传递到另一个地方。

       使程序更具维护性。


    Jackson

    Java生态圈中有很多处理JSON和XML格式化的类库, 常见的解析器:Jsonlib,Gson,fastjson,Jackson。Jackson是其中比较著名的一个,也比较方便。,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的JSON操作方法。

    1.导入Jar包

    2.Json注解

    @JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。

    @JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。

    @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty("name")。

    public class Person {
    
        private String name;
        private int age;
         @JsonProperty("gender")
        private String gender;
    
       // @JsonIgnore//忽略该属性,不进行转换
        @JsonFormat(pattern = "yyyy-MM-dd")
        private Date birthday;
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        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 String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", gender='" + gender + '\'' +
                    '}';
        }
    }

    3.Json转为Java对象

    导入Jackson的相关jar包

    创建Jackson的核心对象,ObjectMapper

    调用ObjectMapper的相关方法进行数据转换——将Json字符串转换为Java对象

              readValue(json字符串数据,类.Class)

    //将Json字符串转为Java对象
        @Test
        public  void  test5() throws Exception{
            //json字符串
            String str="{\"gender\":\"男\",\"name\":\"zhangsan\",\"age\":23}";
            //Jackson核心对象
            ObjectMapper mapper = new ObjectMapper();
            //使用readValue方法进行转换
            Person person = mapper.readValue(str, Person.class);
            System.out.println(person);
        }

    4.Java对象转换Json

    导入Jackson的相关jar包

    创建Jackson的核心对象,ObjectMapper

    调用ObjectMapper的相关方法进行数据转换——将Java对象转换为Json

            writeValue(参数,obj对象)

                   参数:File:将obj对象转换为JSON字符串,并保存到指定的文件中

                   参数:Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中

                   参数:OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中

            writeValueAsString(obj):将对象转为json字符串(常用)

     //Java对象转Json
        @Test
        public void test1() throws IOException {
    
            //1.创建Java对象
            Person p=new Person();
            p.setName("张三");
            p.setAge(23);
            p.setGender("男");
    
            //2.创建Jackson对象 ObjectMapper
            ObjectMapper mapper=new ObjectMapper();
            //3.转换为JSOn
            String json = mapper.writeValueAsString(p);
            System.out.println(json);
            mapper.writeValue(new File("d:\\jaon.txt"),json);
            mapper.writeValue(new FileWriter("d:\\json.txt"),json);
        }
    
    
        @Test
        public void test2() throws JsonProcessingException {
    
            //1.创建Java对象
            Person p = new Person();
            p.setName("张三");
            p.setAge(23);
            p.setGender("男");
            p.setBirthday(new Date());
            //2.创建Jackson对象 ObjectMapper
            ObjectMapper mapper = new ObjectMapper();
            //3.转换为JSOn
            String json = mapper.writeValueAsString(p);
            System.out.println(json);
        }
    
    
        @Test
        public void test3() throws Exception {
            //复杂格式的转换:list
            //1.创建Java对象
            Person p1 = new Person();
            p1.setName("张三");
            p1.setAge(23);
            p1.setGender("男");
            p1.setBirthday(new Date());
    
            Person p2 = new Person();
            p2.setName("张三");
            p2.setAge(23);
            p2.setGender("男");
            p2.setBirthday(new Date());
    
            List<Person> list=new ArrayList<>();
            list.add(p1);
            list.add(p1);
       
            //2.创建Jackson对象 ObjectMapper
            ObjectMapper mapper = new ObjectMapper();
            //3.转换为JSOn
            String json = mapper.writeValueAsString(list);
            System.out.println(json);//[{"name":"张三","age":23,"gender":"男","birthday":"2021-03-19"},{"name":"张三","age":23,"gender":"男","birthday":"2021-03-19"}]
    
        }
    
        @Test
        public  void   test4() throws Exception{
            //复杂格式的转换Map
            //1.创建map对象
            Map<String,Object> map=new HashMap<>();
            map.put("name","zhangsan");
            map.put("age",23);
            map.put("gender","男");
            //2.创建Jackson对象 ObjectMapper
            ObjectMapper mapper = new ObjectMapper();
            //3.转换为JSOn
            String json = mapper.writeValueAsString(map);
            System.out.println(json);//{"gender":"男","name":"zhangsan","age":23}
        }

    创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。    

     

     

    展开全文
  • jackson-annotations-2.0.0.jar jackson-core-2.0.0.jar jackson-databind-2.0.0.jar

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 130,902
精华内容 52,360
关键字:

jackson