我使用Java + Gson,我希望序列化一个特殊的json。我想要对象的对象instand的内容。
a*b/c
是否可以序列化为:
import ctypes
import time
# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]
# Actuals Functions
def MouseMoveTo(x, y):
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.mi = MouseInput(x, y, 0, 0x0001, 0, ctypes.pointer(extra))
command = Input(ctypes.c_ulong(0), ii_)
ctypes.windll.user32.SendInput(1, ctypes.pointer(command), ctypes.sizeof(command))
我尝试使用此代码但错误:
{
"age": 26,
"email": "norman@futurestud.io",
"isDeveloper": true,
"name": "Norman",
"userAddress": {
"city": "Magdeburg",
"country": "Germany",
"houseNumber": "42A",
"street": "Main Street"
}
}
答案 0 :(得分:0)
您正在寻找JSON树。 但至少有一点需要注意的是在不同的对象中共享同名的属性名称。
假设您有以下数据类:
final class User {
final String email;
final String name;
final int age;
final boolean isDeveloper;
User(final String email, final int age, final String name, final boolean isDeveloper) {
this.age = age;
this.email = email;
this.isDeveloper = isDeveloper;
this.name = name;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("email", email)
.add("name", name)
.add("age", age)
.add("isDeveloper", isDeveloper)
.toString();
}
}
final class UserAddress {
final String country;
final String city;
final String street;
final String houseNumber;
UserAddress(final String country, final String city, final String street, final String houseNumber) {
this.country = country;
this.city = city;
this.street = street;
this.houseNumber = houseNumber;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("country", country)
.add("city", city)
.add("street", street)
.add("houseNumber", houseNumber)
.toString();
}
}
现在,您可以使用实用程序方法将多个对象序列化为单个JsonObject
实例。
此外,您可以轻松地使用反序列化计数器部件,该部件可以从JsonObject
实例反序列化多个对象。
例如:
final class JsonObjects {
private JsonObjects() {
}
@SafeVarargs
static JsonObject combine(final Gson gson, final Map.Entry<Object, ? extends Type>... objectAndTypeEntries) {
return Stream.of(objectAndTypeEntries)
// Each element should be serialized to a JsonElement
.map(e -> gson.toJsonTree(e.getKey(), e.getValue()))
// That must be a JSON object
.map(JsonElement::getAsJsonObject)
// And now we can collect a stream of JsonObject instances into a super-object
.collect(Collector.of(
JsonObject::new, // We'll collect into a new JsonObject instance, this is the accumulator
JsonObjects::mergeInto, // Merge each consecutive JsonObject instance into the accumulator
JsonObjects::mergeInto, // Or even combine multiple accumulators
Function.identity() // And just return the accumulator
));
}
static List<?> split(final Gson gson, final JsonObject jsonObject, final Type... types) {
return Stream.of(types)
// Each element should be deserialized from the JsonObject by a type
.map(type -> gson.fromJson(jsonObject, type))
// And just collect all the deserialized objects to a list
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}
private static JsonObject mergeInto(final JsonObject to, final JsonObject from) {
for ( final Map.Entry<String, JsonElement> e : from.entrySet() ) {
to.add(e.getKey(), e.getValue());
}
return to;
}
}
使用示例:
final User beforeUser = new User("norman@localhost", 26, "Norman", true);
System.out.println("BEFORE User: " + beforeUser);
final UserAddress beforeUserAddress = new UserAddress("Germany", "Magdeburg", "Main Street", "42A");
System.out.println("BEFORE User address: " + beforeUserAddress);
final JsonObject jsonObject = JsonObjects.combine(
gson,
new AbstractMap.SimpleImmutableEntry<>(beforeUser, User.class),
new AbstractMap.SimpleImmutableEntry<>(beforeUserAddress, UserAddress.class)
);
System.out.println("JSON: " + jsonObject);
final List<?> objects = JsonObjects.split(gson, jsonObject, User.class, UserAddress.class);
final User afterUser = (User) objects.get(0);
System.out.println("AFTER User: " + afterUser);
final UserAddress afterUserAddress = (UserAddress) objects.get(1);
System.out.println("AFTER User address: " + afterUserAddress);
输出:
BEFORE User: User{email=norman@localhost, name=Norman, age=26, isDeveloper=true} BEFORE User address: UserAddress{country=Germany, city=Magdeburg, street=Main Street, houseNumber=42A} JSON: {"email":"norman@localhost","name":"Norman","age":26,"isDeveloper":true,"country":"Germany","city":"Magdeburg","street":"Main Street","houseNumber":"42A"} AFTER User: User{email=norman@localhost, name=Norman, age=26, isDeveloper=true} AFTER User address: UserAddress{country=Germany, city=Magdeburg, street=Main Street, houseNumber=42A}
正如您所看到的,您不需要创建额外的DTO类来涵盖所有情况,但由于在这里使用了树,这也需要更多的内存使用。
答案 1 :(得分:0)
我找到了一个使用Gson工具的解决方案(类UserAddressAdapter extends TypeAdapter<UserAddress>
)。
public class User {
...
// see the first ligne of UserAddressAdapter#write
// city => (out.value(value.getCity());)
@SerializedName("city")
@JsonAdapter(UserAddressAdapter.class)
private final UserAddress userAddress;
...
}
public class UserAddressAdapter extends TypeAdapter<UserAddress> {
@Override
public void write(JsonWriter out, UserAddress value) throws IOException {
out.value(value.getCity());
out.name("country");
out.value(value.getCountry());
out.name("houseNumber");
out.value(value.getHouseNumber());
out.name("street");
out.value(value.getStreet());
}
@Override
public UserAddress read(JsonReader in) throws IOException {
final int city = in.nextInt();
UserAddress[] scopes = UserAddress.values();
for (UserAddress scope : scopes) {
if (scope.getCity() == city) {
return scope;
}
}
return null;
}
}
和来电者是:
new Gson().toJson(new User("...", ...))