sko*_*isa 4 java json json-deserialization jsonb-api
我创建了一个带有两个类的普通 Java 9 Maven 应用程序,以使用 JSON-B 测试 JSON 的序列化和反序列化。这是代码:
package com.jsonbdemos;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
public class App {
public static void main(String[] args) {
Jsonb jsonb = JsonbBuilder.create(new JsonbConfig());
String jsonData = "{\"creationDate\":\"2018-01-05\"}";
// Create Widget object from JSON string.
Widget widget = jsonb.fromJson(jsonData, Widget.class);
System.out.println("JSON => object: " + widget.toString());
// Serialize Widget object to JSON string.
String jsonFromObject = jsonb.toJson(widget);
System.out.println("object => JSON: " + jsonFromObject);
}
}
package com.jsonbdemos;
import java.time.LocalDate;
public class Widget { // IllegalAccessException if "public" is removed.
private LocalDate creationDate;
public Widget() {}
@Override
public String toString() { return "creationDate=" + creationDate; }
public LocalDate getCreationDate() { return creationDate; }
public void setCreationDate(LocalDate creationDate) { this.creationDate = creationDate; }
}
Run Code Online (Sandbox Code Playgroud)
pom.xml 中依赖于最新版本的 JSON-B ( Eclipse Yasson )参考实现:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>[1.1.2,)</version>
</dependency>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>[1.0,)</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>[1.0.0,)</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
该应用程序运行良好,但如果我将类Widget的访问级别从public更改为无(即“包私有”),则在调用Jsonb.fromJson()时会抛出 IllegalAccessException :
线程“main”中的异常 javax.json.bind.JsonbException:无法在 java.base/java.security 的 org.eclipse.yasson.internal.ReflectionUtils.lambda$createNoArgConstructorInstance$1(ReflectionUtils.java:191) 创建实例。 AccessController.doPrivileged(Native Method) at org.eclipse.yasson.internal.ReflectionUtils.createNoArgConstructorInstance(ReflectionUtils.java:186) at org.eclipse.yasson.internal.serializer.ObjectDeserializer.getInstance(ObjectDeserializer.java:92) at org. eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserialize(AbstractContainerDeserializer.java:62) 位于 org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:57) 位于 org.eclipse.yasson.internal.Unmarshaller.deserialize(AbstractContainerDeserializer.java:62) Unmarshaller.java:50) 在 org.eclipse.yasson.internal.JsonBinding。在 org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:52) 在 com.jsonbdemos.App.main(App.java:15) 处反序列化(JsonBinding.java:45)引起:java.lang.IllegalAccessException:class org.eclipse.yasson.internal.ReflectionUtils 无法访问类 com.jsonbdemos.Widget 的成员, 在 java.base/jdk.internal.reflect.Reflection.newIllegalAccessException( Reflection.java:361) at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:589) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:479) at org .eclipse.yasson.internal.ReflectionUtils.lambda$createNoArgConstructorInstance$1(ReflectionUtils.java:189) ... 9 更多
我在规范(JSR 367:"JSON-B: Java™ API for JSON Binding")(在3.7 Java Class部分)中没有看到任何需要公共类进行反序列化的内容。
关于如何使用 JSON-B 反序列化为非公开的类实例的任何建议?
更新 (5/2/18):
JSR 367 指出“传递给反序列化操作的任何实例都必须具有公共或受保护的无参数构造函数”,但如果构造函数是protected而不是public ,也会发生相同的错误。
我已经报告了这个问题:反序列化仍然无法使用受保护的无参数构造函数 #118
我测试了一些变体,结果如下:
独立类(自己的源文件):
静态内部类:
非静态内部类:
关键点是:
| 归档时间: |
|
| 查看次数: |
2997 次 |
| 最近记录: |