This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory-site.git
The following commit(s) were added to refs/heads/main by this push:
new c8bcdabba0 🔄 synced local 'docs/guide/' with remote 'docs/guide/'
c8bcdabba0 is described below
commit c8bcdabba0dcf29282d091ad302b1d6e66af9e21
Author: chaokunyang <[email protected]>
AuthorDate: Thu Jul 16 00:59:17 2026 +0000
🔄 synced local 'docs/guide/' with remote 'docs/guide/'
---
docs/guide/java/android-support.md | 8 ++++--
docs/guide/java/graalvm-support.md | 4 +++
docs/guide/java/json-support.md | 56 ++++++++++++++++++++++++++++++++++++--
3 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/docs/guide/java/android-support.md
b/docs/guide/java/android-support.md
index 8891329f1c..25421b25ea 100644
--- a/docs/guide/java/android-support.md
+++ b/docs/guide/java/android-support.md
@@ -132,14 +132,18 @@ name that method explicitly.
Android Fory JSON requires a retained no-argument constructor for an ordinary
mutable class; it may
be non-public when Android reflection can make it accessible. `JsonCreator`
constructor-backed
classes follow the normal creator rules instead. Retain every field and method
used for reflection,
-or use an application codec when a model cannot satisfy those requirements.
+or use an application codec when a model cannot satisfy those requirements.
`JsonUnwrapped`
+supports mutable classes, creator-backed classes, and Records through their
normal property and
+construction paths. When the containing model and its unwrapped children use
`JsonType`, their
+generated companions supply those operations.
Android-desugared Records require a direct `@JsonType` annotation and the
annotation processor.
Manual R8 rules alone cannot reconstruct Record component order because
Android does not provide
the Java Record reflection APIs. This also applies to a Record whose complete
representation is a
`JsonValue` String: the generated companion identifies the propagated
component accessor and calls
an annotated one-String canonical constructor directly. Generated child codecs
act on one level
-exactly as they do on the JVM; use a complete value codec for deeper nested
behavior.
+exactly as they do on the JVM. Every Record in a `JsonUnwrapped` path needs
its own direct
+`JsonType`. Use a complete value codec for deeper nested behavior.
## Static Generated Serializers
diff --git a/docs/guide/java/graalvm-support.md
b/docs/guide/java/graalvm-support.md
index 216c42942c..553f616f45 100644
--- a/docs/guide/java/graalvm-support.md
+++ b/docs/guide/java/graalvm-support.md
@@ -114,6 +114,10 @@ uses its generated component accessor and canonical
constructor operations.
`@JsonCodec(valueCodec = ...)` on that field or getter to customize each
dynamic value. A second
`JsonAnySetter` parameter may use the normal configuration for its own value
shape.
+`JsonUnwrapped` uses the same interpreted behavior as on the JVM. Annotate the
containing model and
+every unwrapped child or intermediate object with `JsonType` so each model
receives its generated
+property and creator operations.
+
Child codecs act on one direct level. `elementCodec` supports `Collection`,
Java arrays, and
`AtomicReferenceArray`; `contentCodec` supports `Optional` and
`AtomicReference`; `keyCodec` and
`valueCodec` support Map keys and values. A complete `value` codec cannot be
combined with a child
diff --git a/docs/guide/java/json-support.md b/docs/guide/java/json-support.md
index bacad8bd35..2ab106e3f8 100644
--- a/docs/guide/java/json-support.md
+++ b/docs/guide/java/json-support.md
@@ -306,8 +306,8 @@ disabled. Every other builder option keeps the behavior
described above.
Fory JSON provides `JsonProperty`, `JsonPropertyOrder`, `JsonIgnore`,
`JsonAnyProperty`,
`JsonAnyGetter`, `JsonAnySetter`, `JsonCreator`, `JsonCodec`, `JsonValue`,
`JsonRawValue`,
-`JsonBase64`, `JsonSubTypes`, and `JsonType` under
`org.apache.fory.json.annotation`. They are not
-Jackson, Gson, or Fory binary-protocol annotations.
+`JsonBase64`, `JsonUnwrapped`, `JsonSubTypes`, and `JsonType` under
+`org.apache.fory.json.annotation`. They are not Jackson, Gson, or Fory
binary-protocol annotations.
```java
import java.util.LinkedHashMap;
@@ -326,6 +326,7 @@ import org.apache.fory.json.annotation.JsonRawValue;
import org.apache.fory.json.annotation.JsonSubTypes;
import org.apache.fory.json.annotation.JsonType;
import org.apache.fory.json.annotation.JsonValue;
+import org.apache.fory.json.annotation.JsonUnwrapped;
```
`JsonType` asks the annotation processor to generate direct property and
creator operations plus
@@ -414,6 +415,9 @@ subclass properties. Interface declarations are not
considered.
Property order affects serialization only. Deserialization remains name-based
and accepts members
in any order. Subtype discriminators remain before user properties.
+An unwrapped group also occupies one position, selected by the group's Java
logical property name.
+Its child members remain adjacent and retain the child's own order.
+
A write-enabled `JsonAnyProperty` or `JsonAnyGetter` participates as one
position identified by its
Java logical property name:
@@ -550,6 +554,54 @@ container elements, or Map values. It cannot share a
logical property with `Json
occurrence `JsonCodec`, or an Any declaration. The equivalent explicit codec is
`@JsonCodec(Base64ByteArrayCodec.class)`.
+### `JsonUnwrapped`
+
+Use `JsonUnwrapped` when an object-valued property should keep its Java object
boundary but place
+its members in the containing JSON object:
+
+```java
+import org.apache.fory.json.annotation.JsonUnwrapped;
+
+public final class Person {
+ public int age;
+
+ @JsonUnwrapped(prefix = "name_")
+ public Name name;
+}
+
+public final class Name {
+ public String first;
+ public String last;
+}
+```
+
+This writes `{"age":18,"name_first":"Ada","name_last":"Lovelace"}` instead of a
+nested `name` object. `prefix` and `suffix` apply to every final child name
after `JsonProperty` and
+the configured naming strategy. Nested groups compose these transformations
from the inside out.
+
+A null child emits no members. During reading, the child is created only when
at least one
+flattened member is present. A missing group preserves a mutable parent's
initialized value and
+leaves a record or creator argument at its normal missing-property default.
Partial input creates
+the child and uses ordinary defaults for its other members.
+
+Mutable classes, records, and `JsonCreator` classes are supported as parents
and children. A
+parameter-local creator parameter can define a read-only group; its required
`JsonProperty` value
+identifies the Java argument and is not a wrapper name. The containing parent
may be parameterized,
+but each unwrapped child and intermediate must be an exact raw, non-generic
class using the standard
+Fory object mapping.
+
+The complete group occupies one position in parent serialization order.
Position it with
+`JsonProperty.index`, or list its Java logical property name in
`JsonPropertyOrder`. Child ordering
+is preserved inside the group. Input matches parent fixed properties first,
flattened properties
+second, and dynamic Any members last.
+
+Fory rejects final-name or name-hash collisions, recursive chains made only of
unwrapped
+properties, parameterized children, JSON Any children, polymorphic or
custom-codec child roots,
+and scalar, array, collection, or Map children. Flatten Maps with
`JsonAnyProperty`,
+`JsonAnyGetter`, or `JsonAnySetter`. An unwrapped property cannot use
`JsonProperty.value`, a
+non-default `JsonProperty.include`, or `JsonCodec`; ordinary leaf properties
inside the child keep
+their normal annotations.
+
### Dynamic object members
Use `JsonAnyProperty` to flatten a `Map<String, V>` field into the containing
JSON object and store
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]