我正在尝试迁移某些 JSON 数据绑定代码的实现细节,以使用 Java EE 8 JSON-B API 而不是 Jackson。
为了匹配 Jackson 的默认行为,当 JSON 负载包含无法识别的属性时,我想拒绝将 JSON 负载反序列化为 POJO 的任何尝试。
例如,如果我有以下 JSON 数据:
{
"name": "Bob",
"extraProp": "Something"
}
Run Code Online (Sandbox Code Playgroud)
我有以下 Java 对象可以将此数据建模为:
public class Thing {
public String name;
// no mention of "extraProp"
}
Run Code Online (Sandbox Code Playgroud)
我如何拒绝将上述 JSON 数据绑定到上述 POJO 的尝试?
如果我尝试以下操作,则Thing创建的对象不会出错(这里我希望发生错误):
Jsonb jsonb = JsonbProvider.provider()
.create()
.build();
Thing t = jsonb.fromJson("{\"name\":\"Bob\",\"extraProp\":\"Something\"}", Thing .class);
Run Code Online (Sandbox Code Playgroud) 为了使用Java API for JSON Binding (JSON-B),我发现有必要在我的Maven POM中包含以下三个依赖项:
\n\n <!-- https://mvnrepository.com/artifact/jakarta.json.bind/jakarta.json.bind-api -->\n <dependency>\n <groupId>jakarta.json.bind</groupId>\n <artifactId>jakarta.json.bind-api</artifactId>\n <version>1.0.1</version>\n\n </dependency>\n\n <!-- https://mvnrepository.com/artifact/org.eclipse/yasson -->\n <dependency>\n <groupId>org.eclipse</groupId>\n <artifactId>yasson</artifactId>\n <version>1.0.3</version>\n </dependency>\n\n <!-- https://mvnrepository.com/artifact/org.glassfish/javax.json -->\n <dependency>\n <groupId>org.glassfish</groupId>\n <artifactId>javax.json</artifactId>\n <version>1.1.4</version>\n </dependency>\nRun Code Online (Sandbox Code Playgroud)\n\n前两个对我来说很有意义。
\n\njakarta.json.bind-api是JSR 367定义的JSON-B API 。yasson是该 API 的参考实现Eclipse Yasson。javax.json\xe2\x9e\xa5 但是来自Glassfish 的第三个依赖项到底给聚会带来了什么?为什么我的应用程序需要它才能运行?
如果省略,运行时Jsonb jsonb = JsonbBuilder.create();会出现此错误:
\n\n\njavax.json.JsonException:找不到提供者 org.glassfish.json.JsonProviderImpl
\n
我很困惑,因为我认为 Yasson是我的 JSON …
我已经使用JSON-B开发了Java REST服务,以将传入的有效负载映射到POJO。
现在,我想做的是验证传入的有效负载,可能是针对JSON模式,但是到目前为止,我还无法找到任何东西……
是否可以覆盖默认的JSON-B映射过程,从而捕获任何映射异常并自行处理?
我正在调整这段杰克逊代码:
@JsonDeserialize(as = EntityImpl.class)
public interface Entity { ... }
Run Code Online (Sandbox Code Playgroud)
即使对于嵌套的Entity对象,原始代码也能很好地工作.
如何使用新的json-b规范?我尝试使用@JsonbTypeDeserializer但是
javax.json.bind.JsonbException:无法推断用于解组的类型:Entity
这是我的反序列化代码:
public class EntityDeserializer implements JsonbDeserializer<Entity> {
@Override
public Entity deserialize(JsonParser parser, DeserializationContextdeserializationContext, Type runtimeType) {
Class<? extends Entity> entityClass = EntityImpl.class.asSubclass(Entity.class);
return deserializationContext.deserialize(entityClass, parser);
}
}
Run Code Online (Sandbox Code Playgroud)
任何提示或帮助非常感谢:-)
我创建了一个带有两个类的普通 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 …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 JSONB 反序列化 JSON 数组。
JSON
[
{
"id": "1",
"animal": "dog",
"age": "3"
},
{
"id": "2",
"animal": "cat",
"age": "5"
}
]
Run Code Online (Sandbox Code Playgroud)
控制器
Jsonb jsonb = JsonbBuilder.create();
Animal animal;
AnimalsList animalsList;
public AnimalsList getAnimals() {
try {
animalsList = jsonb.fromJson("[{\"id\":\"1\",\"animal\":\"dog\",\"age\":\"3\"},{\"id\":\"2\",\"animal\":\"cat\",\"age\":\"5\"}]", AnimalsList.class);
} catch (JSONException ex) {
Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
}
return animalsList;
}
Run Code Online (Sandbox Code Playgroud)
动物清单
public class AnimalsList implements Serializable{
private List<Animal> list;
public AnimalsList() {
}
public AnimalsList(List<Animal> list) {
this.list = list;
}
// getter & setter …Run Code Online (Sandbox Code Playgroud) 我在资源类中有一个 PATCH 端点,其中一个抽象类作为请求主体。我收到以下错误:
22:59:30 SEVERE [or.ec.ya.in.Unmarshaller] (on Line: 64) (executor-thread-63) Can't create instance
Run Code Online (Sandbox Code Playgroud)
似乎因为我声明为参数的身体模型是抽象的,所以它无法反序列化。
我期待得到 Element_A 或 Element_B
如何声明主体是多态的?
这是元素层次结构
public abstract class BaseElement {
public String name;
public Timestamp start;
public Timestamp end;
}
public class Element_A extends BaseElement{
public String A_data;
}
public class Element_B extends BaseElement{
public long B_data;
}
Run Code Online (Sandbox Code Playgroud)
这是我的端点的资源类
@Path("/myEndpoint")
public class ResourceClass {
@PATCH
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public Response updateEvent(@Valid BaseElement element, @Context UriInfo uriInfo, @PathParam long id) {
if (element instanceof Element_A) { …Run Code Online (Sandbox Code Playgroud) 到目前为止,我已经使用 Jersey,并且正在使用 JSON-B 进行第一次实现。
我正在使用 Payara,所以我与 Jersey 和 Yasson 一起工作。我遇到了问题,因为序列化日期始终包含“[UTC]”后缀。
我已设法在 DTO 中的日期属性上使用注释。但我想全局配置(在 JAX-RS 应用程序配置中?),而不是在每个日期属性上重复自己。那可能吗?到目前为止我还没有发现任何东西...
附带问题:我认为可以去掉这个“[UTC]”后缀,因为它会破坏所有尝试解析日期的客户端。任何想法?