FasterXML/jackson-databind

GitHub: FasterXML/jackson-databind

Jackson 数据处理器的核心数据绑定包,实现 JSON 与 Java 对象之间高效的双向序列化与反序列化。

Stars: 3737 | Forks: 1494

# 概述 本项目包含通用的数据绑定功能 以及 [Jackson Data Processor](../../../jackson) 的树模型。 它基于 [Streaming API](../../../jackson-core)(流式解析器/生成器)包构建, 并使用 [Jackson Annotations](../../../jackson-annotations) 进行配置。 项目采用 [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) 授权。 虽然 Jackson 最初的使用场景是 JSON 数据绑定,但现在只要存在解析器和生成器实现,它也可以用于读取以其他数据格式编码的内容。 尽管对 JSON 格式并没有实际上的硬性依赖,但许多地方的类名中仍使用了“JSON”一词。 ## 状态 | 类型 | 状态 | | ---- | ------ | | 构建 (CI) | [![Build (github)](https://static.pigsec.cn/wp-content/uploads/repos/cas/f0/f0f4fa59a5b736a753672547c87eaee45e015f4ee033b65b09af8d2e40456056.svg)](https://github.com/FasterXML/jackson-databind/actions/workflows/main.yml) | | 构件 | [![Maven Central](https://img.shields.io/maven-central/v/tools.jackson.core/jackson-databind.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/tools.jackson.core/jackson-databind) | | OSS 赞助 | [![Tidelift](https://tidelift.com/badges/package/maven/tools.jackson.core:jackson-databind)](https://tidelift.com/subscription/pkg/maven-com-fasterxml-jackson-core-jackson-databind?utm_source=maven-tools-jackson-core-jackson-databind&utm_medium=referral&utm_campaign=readme) | | Javadocs | [![Javadoc](https://javadoc.io/badge/tools.jackson.core/jackson-databind.svg)](https://javadoc.io/doc/tools.jackson.core/jackson-databind) | | 代码覆盖率 (3.x) | [![codecov.io](https://codecov.io/github/FasterXML/jackson-databind/coverage.svg?branch=3.x)](https://codecov.io/github/FasterXML/jackson-databind?branch=3.x) | | OpenSSF 评分 | [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/FasterXML/jackson-databind/badge)](https://securityscorecards.dev/viewer/?uri=github.com/FasterXML/jackson-databind) | # 获取它! ## Maven 此包的功能包含在 Java 包 `tools.jackson.databind`(针对 Jackson 3.x)中,可以通过以下 Maven 依赖使用: ``` ... 3.0.0 ... ... tools.jackson.core jackson-databind ${jackson.version} ... ``` 该包还依赖于 `jackson-core` 和 `jackson-annotations` 包,但在使用 Maven 或 Gradle 等构建工具时,依赖会自动包含在内。 不过,您可能需要使用 [jackson-bom](../../../jackson-bom) 来确保依赖版本的兼容性。 如果您使用的构建工具无法通过项目的 `pom.xml` 处理依赖,则需要手动下载并显式包含这两个 jar 包。 ## 非 Maven 依赖解析 对于不会自动从 Maven 仓库解析依赖的用例,您仍然可以从 [Central Maven repository](https://repo1.maven.org/maven2/tools/jackson/core/jackson-databind/) 下载 jar 包。 Databind jar 也是一个功能完整的 OSGi bundle,具有正确的导入/导出声明,因此可以直接在 OSGi 容器中使用。 Jackson 2.10 及更高版本包含 `module-info.class` 定义,因此该 jar 也是一个标准的 Java Module (JPMS)。 Jackson 2.12 及更高版本包含额外的 Gradle 6 Module Metadata,以便与 Gradle 进行版本对齐。 ## 兼容性 ### JDK Jackson-databind 包的基本 JDK 要求如下: * 2.x 版本需要 JDK 8 * 3.x 版本需要 JDK 17 ### Android 由于 Jackson 2.13 才添加了兼容性检查器,以下列表并不完整。 * 2.14 - 2.19:Android SDK 26+ * 3.0:Android SDK 34+ 有关 Android SDK 版本与 Android 发布名称的对应信息,请参见 [https://en.wikipedia.org/wiki/Android_version_history](https://en.wikipedia.org/wiki/Android_version_history) # 使用它! 更全面的文档可以在 [Jackson-docs](../../../jackson-docs) 仓库以及本项目的 [Wiki](../../wiki) 中找到。 但这里有一些简短的入门教程,按推荐的阅读顺序排列。 ## 1 分钟教程:POJO 与 JSON 互转 最常见的用法是获取一段 JSON,并从中构造出一个 Plain Old Java Object ("POJO")。让我们从这里开始。像这样一个简单的包含 2 个属性的 POJO: ``` // Note: can use getters/setters as well; here we just use public fields directly: public class MyValue { public String name; public int age; // NOTE: if using getters/setters, can keep fields `protected` or `private` } ``` 我们需要一个 `tools.jackson.databind.ObjectMapper` 实例用于所有数据绑定,所以让我们构造一个: ``` // With default settings can use ObjectMapper mapper = new ObjectMapper(); // create once, reuse // But if configuration needed, use builder pattern: ObjectMapper mapper = JsonMapper.builder() // configuration .build(); ``` 默认实例对我们的使用来说已经足够了——稍后我们将学习如何在必要时配置 mapper 实例。用法很简单: ``` MyValue value = mapper.readValue(new File("data.json"), MyValue.class); // or: value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class); // or: value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class); ``` 如果我们想写入 JSON,我们执行相反的操作: ``` mapper.writeValue(new File("result.json"), myResultObject); // or: byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject); // or: String jsonString = mapper.writeValueAsString(myResultObject); ``` 到目前为止一切都还好吧? ## 3 分钟教程:泛型集合,树模型 除了处理简单的 Bean 风格 POJO 之外,您还可以处理 JDK 的 `List`、`Map`: ``` Map scoreByName = mapper.readValue(jsonSource, Map.class); List names = mapper.readValue(jsonSource, List.class); // and can obviously write out as well mapper.writeValue(new File("names.json"), names); ``` 只要 JSON 结构匹配,且类型简单即可。 如果您的值是 POJO,您需要指明实际类型(注意:对于具有 `List` 等类型的 POJO 属性,这并不是必需的): ``` Map results = mapper.readValue(jsonSource, new TypeReference>() { } ); // why extra work? Java Type Erasure will prevent type detection otherwise ``` (注意:无论泛型类型如何,序列化都不需要额外的操作) 等等!还有更多! (进入树模型……) ### 树模型 虽然处理 `Map`、`List` 和其他“简单”对象类型(字符串、数字、布尔值)可能很简单,但对象遍历可能会很麻烦。 这就是 Jackson 的 [树模型](https://github.com/FasterXML/jackson-databind/wiki/JacksonTreeModel) 派上用场的地方: ``` // can be read as generic JsonNode, if it can be Object or Array; or, // if known to be Object, as ObjectNode, if array, ArrayNode etc: JsonNode root = mapper.readTree("{ \"name\": \"Joe\", \"age\": 13 }"); String name = root.get("name").asText(); int age = root.get("age").asInt(); // can modify as well: this adds child Object as property 'other', set property 'type' root.withObject("/other").put("type", "student"); String json = mapper.writeValueAsString(root); // prints below /* with above, we end up with something like as 'json' String: { "name" : "Bob", "age" : 13, "other" : { "type" : "student" } } */ ``` 在结构高度动态或不能很好地映射到 Java 类的情况下,树模型可能比数据绑定更方便。 最后,可以随意混合使用,甚至在同一个 JSON 文档中也可以(当文档中只有一部分内容已知并在代码中建模时非常有用) ``` // Some parts of this json are modeled in our code, some are not JsonNode root = mapper.readTree(complexJson); Person p = mapper.treeToValue(root.get("person"), Person.class); // known single pojo Map dynamicmetadata = mapper.treeToValue(root.get("dynamicmetadata"), Map.class); // unknown smallish subfield, convert all to collections int singledeep = root.get("deep").get("large").get("hiearchy").get("important").intValue(); // single value in very deep optional subfield, ignoring the rest int singledeeppath = root.at("/deep/large/hiearchy/important").intValue(); // json path int singledeeppathunique = root.findValue("important").intValue(); // by unique field name // Send an aggregate json from heterogenous sources ObjectNode root = mapper.createObjectNode(); root.putPOJO("person", new Person("Joe")); // simple pojo root.putPOJO("friends", List.of(new Person("Jane"), new Person("Jack"))); // generics Map dynamicmetadata = Map.of("Some", "Metadata"); root.putPOJO("dynamicmetadata", dynamicmetadata); // collections root.putPOJO("dynamicmetadata", mapper.valueToTree(dynamicmetadata)); // same thing root.set("dynamicmetadata", mapper.valueToTree(dynamicmetadata)); // same thing root.withObject("deep").withObject("large").withObject("hiearchy").put("important", 42); // create as you go root.withObject("/deep/large/hiearchy").put("important", 42); // json path mapper.writeValueAsString(root); ``` **支持 Jackson 2.16+ 版本** ``` // generics List friends = mapper.treeToValue(root.get("friends"), new TypeReference>() { }); // create as you go but without trying json path root.withObjectProperty("deep").withObjectProperty("large").withObjectProperty("hiearchy").put("important", 42); ``` ## 5 分钟教程:流式解析器,生成器 虽然数据绑定(与 POJO 互转)非常方便,树模型也非常灵活,但还有一种标准的处理模型:增量式(也称为“流式”)模型。 它是数据绑定和树模型构建所基于的底层处理模型,但也提供给那些希望获得极致性能和/或控制解析或生成细节的用户。 如需深入了解,请查看 [Jackson Core component](https://github.com/FasterXML/jackson-core)。 但让我们看一个简单的预告来吊起您的胃口。 ``` ObjectMapper mapper = ...; // First: write simple JSON output File jsonFile = new File("test.json"); // note: method added in Jackson 2.11 (earlier would need to use // mapper.getFactory().createGenerator(...) JsonGenerator g = mapper.createGenerator(jsonFile, JsonEncoding.UTF8); // write JSON: { "message" : "Hello world!" } g.writeStartObject(); g.writeStringField("message", "Hello world!"); g.writeEndObject(); g.close(); // Second: read file back try (JsonParser p = mapper.createParser(jsonFile)) { 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); } ``` ## 10 分钟教程:配置 您可能会使用两种入门级的配置机制: [Features](https://github.com/FasterXML/jackson-databind/wiki/JacksonFeatures) 和 [Annotations](https://github.com/FasterXML/jackson-annotations)。 ### 常用的 Features 以下是您最可能需要了解的配置特性示例。 让我们从更高层次的数据绑定配置开始。 在 Jackson 3.x 中,您需要使用“Builder”风格的构造(2.x 也支持直接配置,但这已被移除,以使 `ObjectMapper` 实例不可变且完全线程安全) ``` // SerializationFeature for changing how JSON is written // to enable standard indentation ("pretty-printing"): ObjcetMapper mapper = JsonMapper.builder() .enable(SerializationFeature.INDENT_OUTPUT) // to allow serialization of "empty" POJOs (no properties to serialize) // (without this setting, an exception is thrown in those cases) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) // to write java.util.Date, Calendar as number (timestamp): .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) // DeserializationFeature for changing how JSON is read as POJOs: // to prevent exception when encountering unknown property: .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) // to allow coercion of JSON empty String ("") to null Object value: .enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT) .build(); ``` 此外,您可能需要更改一些底层的 JSON 解析和生成细节。 这可以通过启用/禁用来实现: * `StreamReadFeature` / `StreamWriteFeature` 用于通用(格式无关)的设置 * `JsonReadFeature` / `JsonWriteFeature` 用于特定于 JSON 的设置 ``` ObjcetMapper mapper = JsonMapper.builder() // StreamReadFeatures for configuring parsing settings: // to allow C/C++ style comments in JSON (non-standard, disabled by default) .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) // to allow (non-standard) unquoted field names in JSON: .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) // to allow use of apostrophes (single quotes), non standard .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) // JsonWriteFeature for configuring low-level JSON generation: // to force escaping of non-ASCII characters: .configure(JsonWriteFeature.ESCAPE_NON_ASCII, true) .build(); ``` 完整的特性集在 [Jackson Features](https://github.com/FasterXML/jackson-databind/wiki/JacksonFeatures) 页面进行了解释。 ### Annotations:更改属性名称 最简单的基于注解的方法是像这样使用 `@JsonProperty` 注解: ``` public class MyBean { private String _name; // without annotation, we'd get "theName", but we want "name": @JsonProperty("name") public String getTheName() { return _name; } // note: it is enough to add annotation on just getter OR setter; // so we can omit it here public void setTheName(String n) { _name = n; } } ``` 还有其他机制可用于系统性的命名更改,包括使用“命名策略”(通过 `@JsonNaming` 注解)。 您可以使用 [Mix-in Annotations](https://github.com/FasterXML/jackson-docs/wiki/JacksonMixinAnnotations) 来关联任何和所有 Jackson 提供的注解。 ### Annotations:忽略属性 有两个主要的注解可用于忽略属性:用于单个属性的 `@JsonIgnore`;以及用于类级别定义的 `@JsonIgnoreProperties` ``` // means that if we see "foo" or "bar" in JSON, they will be quietly skipped // regardless of whether POJO has such properties @JsonIgnoreProperties({ "foo", "bar" }) public class MyBean { // will not be written as JSON; nor assigned from JSON: @JsonIgnore public String internal; // no annotation, public field is read/written normally public String external; @JsonIgnore public void setCode(int c) { _code = c; } // note: will also be ignored because setter has annotation! public int getCode() { return _code; } } ``` 与重命名一样,请注意注解在匹配的字段、getter 和 setter 之间是“共享”的:如果只有一个带有 `@JsonIgnore`,它也会影响其他的。 但也可以使用“拆分”注解,例如: ``` public class ReadButDontWriteProps { private String _name; @JsonProperty public void setName(String n) { _name = n; } @JsonIgnore public String getName() { return _name; } } ``` 在这种情况下,不会写出任何 "name" 属性(因为 'getter' 被忽略了);但如果从 JSON 中找到了 "name" 属性,它将被分配给 POJO 属性! 有关在写出 JSON 时忽略属性的所有可能方法的更完整解释,请查看 ["Filtering properties"](https://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html) 文章。 ### Annotations:使用自定义构造函数 与许多其他数据绑定包不同,Jackson 不需要您定义“默认构造函数”(不带参数的构造函数)。 如果没有其他可用的构造函数,它会使用一个,但您可以轻松地定义使用一个带参数的构造函数: ``` public class CtorBean { public final String name; public final int age; @JsonCreator // constructor can be public, private, whatever private CtorBean(@JsonProperty("name") String name, @JsonProperty("age") int age) { this.name = name; this.age = age; } } ``` 构造函数在支持使用 [Immutable objects](https://www.cowtowncoder.com/blog/archives/2010/08/entry_409.html) 时特别有用。 或者,您也可以定义“工厂方法”: ``` public class FactoryBean { // fields etc omitted for brevity @JsonCreator public static FactoryBean create(@JsonProperty("name") String name) { // construct and return an instance } } ``` 请注意,使用“creator method”(带有 `@JsonProperty` 注解参数的 `@JsonCreator`)并不排除使用 setter:您可以将构造函数/工厂方法中的属性与通过 setter 设置或直接使用字段设置的属性混合搭配。 ## 教程:更高级的功能,转换 Jackson 的一个有用(但不太为人所知)的特性是它能够执行任意的 POJO 到 POJO 的转换。从概念上讲,您可以将转换视为两个步骤的序列:首先,将 POJO 写为 JSON,其次,将该 JSON 绑定到另一种 POJO。实现只是跳过了 JSON 的实际生成,并使用了更高效的中间表示。 转换可以在任何兼容的类型之间进行,调用非常简单: ``` ResultType result = mapper.convertValue(sourceObject, ResultType.class); ``` 只要源类型和结果类型兼容——也就是说,如果 to-JSON、from-JSON 序列能够成功——事情就会“正常运行”。 但这里有几个潜在有用的用例: ``` // Convert from List to int[] List sourceList = ...; int[] ints = mapper.convertValue(sourceList, int[].class); // Convert a POJO into Map! Map propertyMap = mapper.convertValue(pojoValue, Map.class); // ... and back PojoType pojo = mapper.convertValue(propertyMap, PojoType.class); // decode Base64! (default byte[] representation is base64-encoded String) String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"; byte[] binary = mapper.convertValue(base64, byte[].class); ``` 基本上,Jackson 可以替代许多 Apache Commons 组件,用于诸如 base64 编码/解码以及处理“dyna beans”(Map 与 POJO 互转)等任务。 ## 教程:Builder 设计模式 + Jackson Builder 设计模式是一种创建型设计模式,可用于逐步创建复杂对象。 如果我们有一个对象需要对其他依赖项进行多重检查,在这种情况下,首选使用 builder 设计模式。 让我们考虑一下具有一些可选字段的 person 结构 ``` public class Person { private final String name; private final Integer age; // getters } ``` 让我们看看如何在反序列化中利用它的强大功能。首先,让我们声明一个私有的全参数构造函数和一个 Builder 类。 ``` private Person(String name, Integer age) { this.name = name; this.age = age; } static class Builder { String name; Integer age; Builder withName(String name) { this.name = name; return this; } Builder withAge(Integer age) { this.age = age; return this; } public Person build() { return new Person(name, age); } } ``` 首先,我们需要用 `@JsonDeserialize` 注解标记我们的类,并传递一个带有 builder 类完全限定域名的 builder 参数。 之后,我们需要将 builder 类本身注解为 `@JsonPOJOBuilder`。 ``` @JsonDeserialize(builder = Person.Builder.class) public class Person { //... @JsonPOJOBuilder static class Builder { //... } } ``` 一个简单的单元测试将是: ``` String json = "{\"name\":\"Hassan\",\"age\":23}"; Person person = new ObjectMapper().readValue(json, Person.class); assertEquals("Hassan", person.getName()); assertEquals(23, person.getAge().intValue()); ``` 如果您的 builder 模式实现为其方法使用了其他前缀,或者为 builder 方法使用了 build() 以外的名称,Jackson 也为您提供了一种便捷的方式。 例如,如果您有一个 builder 类,它为其方法使用 "set" 前缀,并使用 create() 方法而不是 build() 来构建整个类,您必须像这样注解您的类: ``` @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set") static class Builder { String name; Integer age; Builder setName(String name) { this.name = name; return this; } Builder setAge(Integer age) { this.age = age; return this; } public Person create() { return new Person(name, age); } } ``` 要将对象对应的属性反序列化为不同名称的 JSON 字段, 可以在 builder 中的相应字段上使用 @JsonProperty 注解。 ``` @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set") static class Builder { @JsonProperty("known_as") String name; Integer age; //... } ``` 这会将 JSON 属性 `known_as` 反序列化到 builder 字段 `name` 中。如果没有提供这样的映射(并且没有提供其他注解来处理此问题),那么在反序列化过程中,如果提供了该字段,将抛出 `Unrecognized field "known_as"` 异常。 如果您希望在反序列化时使用多个别名来引用属性,可以使用 `@JsonAlias` 注解。 ``` @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set") static class Builder { @JsonProperty("known_as") @JsonAlias({"identifier", "first_name"}) String name; Integer age; //... } ``` 这会将带有 `known_as`、`identifer` 和 `first_name` 的 JSON 字段反序列化到 `name` 中。您可以通过像 `JsonAlias("identifier")` 这样指定一个字符串来使用单个别名,而不是使用条目数组。 注意:要使用 `@JsonAlias` 注解,还必须使用 `@JsonProperty` 注解。 总的来说,Jackson 库在使用 builder 模式反序列化对象方面非常强大。 ## 教程:收集多个错误 (3.1+) 最近引入的一项功能是能够收集多个反序列化错误,而不是在遇到第一个错误时就快速失败。这对于验证用例来说非常方便。 默认情况下,如果 Jackson 在反序列化过程中遇到问题——比如 `int` 属性的字符串 `"xyz"`——它会立即抛出异常并停止。但有时您希望一次性看到所有问题。 考虑这样一种情况,您有几个包含错误数据的字段: ``` class Order { public int orderId; public Date orderDate; public double amount; } String json = "{\"orderId\":\"not-a-number\",\"orderDate\":\"bad-date\",\"amount\":\"xyz\"}"; ``` 通常您会得到关于 `orderId` 的错误,修复它,重新提交,然后得到关于 `orderDate` 的错误,以此类推。这并不有趣。所以让我们把它们全部收集起来: ``` ObjectMapper mapper = new JsonMapper(); ObjectReader reader = mapper.readerFor(Order.class).problemCollectingReader(); try { Order result = reader.readValueCollectingProblems(json); // worked fine } catch (DeferredBindingException ex) { System.out.println("Found " + ex.getProblems().size() + " problems:"); for (CollectedProblem problem : ex.getProblems()) { System.out.println(problem.getPath() + ": " + problem.getMessage()); // Can also access problem.getRawValue() to see what the bad input was } } ``` 这将一次性报告所有 3 个问题。好多了。 默认情况下,Jackson 在放弃之前最多会收集 100 个问题(以防止带有巨大错误 payload 的 DoS 风格攻击)。您可以对此进行配置: ``` ObjectReader reader = mapper.readerFor(Order.class).problemCollectingReader(10); // limit to 10 ``` 需要记住的几点: 1. 这是尽力而为:并非所有问题都能被收集。格式错误的 JSON(如缺少右大括号)或其他结构性问题仍然会立即失败。但是,类型转换错误、未知属性(如果您启用了该检查)等都将被收集。 2. 错误路径使用 JSON Pointer 表示法 (RFC 6901):因此 `"/items/0/price"` 表示 `items` 数组中的第一项,`price 字段。特殊字符会被转义(`~` 变为 `~0`,`/` 变为 `~1`)。 3. 每次调用 `readValueCollectingProblems()` 都会获得自己的问题桶,因此重用同一个 `ObjectReader` 是线程安全的。 4. 在尝试期间,反序列化失败的字段会获得默认值(基本类型为 0,对象为 null),但如果收集到了任何问题,则只会在 `DeferredBindingException` 中报告问题——不会返回部分结果。 这对于诸如 REST API 验证(向客户端返回所有验证错误)、批处理(记录错误但继续执行)或开发工具等情况特别有用。 # 贡献! 我们非常乐意接受您的贡献,无论是 bug 报告、功能增强请求 (RFE)、文档还是代码补丁的形式。 有关以下内容的详细信息,请参见 [CONTRIBUTING](https://github.com/FasterXML/jackson/blob/main/CONTRIBUTING.md): * 社区,互动方式(邮件列表,gitter) * 问题跟踪([GitHub Issues](https://github.com/FasterXML/jackson-databind/issues)) * 文书工作:CLA(只需在第一次合并贡献前提交一次) ## 核心组件的依赖限制 对于所谓的核心组件(streaming api、jackson-annotations 和 jackson-databind)存在一个额外的限制:不允许有以下之外的额外依赖: * 核心组件可以依赖支持的 JDK 中包含的任何方法 * 对于 `jackson-databind` 和大多数非核心组件的 Jackson 2.7 - 2.12 版本,最低 Java 版本为 Java 7 * 对于 Jackson 2.13 及更高版本,最低 Java 版本为 Java 8 * Jackson-databind(此包)依赖于其他两个组件(annotations、streaming)。 这意味着任何必须依赖额外 API 或库的内容都需要作为扩展来构建, 通常是 Jackson 模块。 ## 分支 `3.x` 分支用于开发下一个主要的 Jackson 版本——3.0——但 还有许多活跃的维护分支,大部分开发工作都在其中进行: * `2.x` 是用于发布“下一个”次要版本的分支(截至 2025 年 5 月为 2.20) * `2.19` 是当前稳定的 2.x 次要版本 * `2.18` 用于选定的反向移植修复 较旧的分支在 [Jackson Releases](https://github.com/FasterXML/jackson/wiki/Jackson-Releases) 页面上被声明为关闭后通常不再维护, 但保留它们以防万一需要罕见的紧急补丁。 所有已发布的版本都有匹配的 git 标签(例如 `jackson-dataformats-binary-2.12.3`)。 ## 与 Jackson 1.x 的区别 该仓库包含 2.0 及以上版本:上一个 (1.x) 版本 1.9 的源代码可在 [Jackson-1](../../../jackson-1) 仓库中找到。 与 1.x “mapper” jar 的主要区别在于: * 使用 Maven 而不是 Ant 进行构建 * Java 包: * 1.x: `org.codehaus.jackson.mapper` * 2.x: `com.fasterxml.jackson.databind` * 3.x: `tools.jackson.databind` ## 支持 ### 社区支持 Jackson 组件由 Jackson 社区通过邮件列表、Gitter 论坛、Github issues 提供支持。有关完整详细信息,请参见 [Participation, Contributing](../../../jackson#participation-contributing)。 ### 企业支持 作为 [Tidelift](https://tidelift.com/subscription/pkg/maven-com-fasterxml-jackson-core-jackson-databind) 订阅的一部分提供。 `jackson-databind` 和其他数千个包的维护者正在与 Tidelift 合作,为您用于构建应用程序的开源依赖提供商业支持和维护。在为您使用的确切依赖的维护者付费的同时,节省时间、降低风险并提高代码健康度。[了解更多。](https://tidelift.com/subscription/pkg/maven-com-fasterxml-jackson-core-jackson-databind?utm_source=maven-com-fasterxml-jackson-core-jackson-databind&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## 延伸阅读 * [Overall Jackson Docs](../../../jackson-docs) * [项目 wiki 页面](https://github.com/FasterXML/jackson-databind/wiki) 相关: * [Core annotations](https://github.com/FasterXML/jackson-annotations) 包定义了通常用于配置数据绑定细节的注解 * [Core parser/generator](https://github.com/FasterXML/jackson-core) 包定义了底层的增量/流式解析器和生成器 * [Jackson Project Home](../../../jackson) 包含了所有模块的链接 * [Jackson Docs](../../../jackson-docs) 是项目的文档中心
标签:Jackson, JSON, JS文件枚举, 后台面板检测, 域名枚举, 序列化, 数据绑定