Json 如何配置Gson来序列化一组JSR-303 ConstraintViolation对象?
我似乎无法找到如何使用Gson序列化Hibernate的约束冲突实现 这是我到目前为止试过的 方法1 方法2 但是,它会因以下错误而失败:Json 如何配置Gson来序列化一组JSR-303 ConstraintViolation对象?,json,hibernate,gson,bean-validation,hibernate-validator,Json,Hibernate,Gson,Bean Validation,Hibernate Validator,我似乎无法找到如何使用Gson序列化Hibernate的约束冲突实现 这是我到目前为止试过的 方法1 方法2 但是,它会因以下错误而失败: java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: com.bar.baz.MyPojo. Forgot to register a type adapter? at com.google.gson.internal.bind.TypeA
java.lang.UnsupportedOperationException:
Attempted to serialize java.lang.Class: com.bar.baz.MyPojo.
Forgot to register a type adapter?
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:67)
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
at com.google.gson.internal.bind.ObjectTypeAdapter.write(ObjectTypeAdapter.java:107)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.toJson(Gson.java:593)
at com.google.gson.Gson.toJson(Gson.java:572)
at com.google.gson.Gson.toJson(Gson.java:527)
at com.google.gson.Gson.toJson(Gson.java:507)
java.lang.UnsupportedOperationException:
Attempted to serialize java.lang.Class:
com.bar.baz.MyPojo.
Forgot to register a type adapter?
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:67)
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195)
at com.google.gson.internal.bind.ObjectTypeAdapter.write(ObjectTypeAdapter.java:107)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.toJson(Gson.java:593)
at com.google.gson.Gson.toJson(Gson.java:572)
at com.google.gson.Gson.toJson(Gson.java:527)
at com.google.gson.Gson.toJson(Gson.java:507)
方法4
查看错误消息,我认为这可能有效:
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(
new TypeToken<ConstraintViolation<MyPojo>>() {}.getType(),
new JsonSerializer<ConstraintViolation<MyPojo>>() {
@Override
public JsonElement serialize(ConstraintViolation<MyPojo> src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("aTestProperty", "A Test Value");
return result;
}
});
builder.registerTypeAdapter(
new TypeToken<MyPojo>() {}.getType(),
new JsonSerializer<MyPojo>() {
@Override
public JsonElement serialize(MyPojo src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("anotherTestProperty", "Another Test Value");
return result;
}
});
Gson gson = builder.create();
Set<ConstraintViolation<MyPojo>> violations = validator.validate(MyPojo);
System.out.println(gson.toJson(violations));
GsonBuilder=newgsonbuilder();
builder.registerTypeAdapter(
新建TypeToken(){}.getType(),
新的JsonSerializer(){
@凌驾
公共JsonElement序列化(ConstraintViolation src,类型typeOfSrc,JsonSerializationContext){
JsonObject结果=新建JsonObject();
结果.addProperty(“aTestProperty”,“A测试值”);
返回结果;
}
});
builder.registerTypeAdapter(
新建TypeToken(){}.getType(),
新的JsonSerializer(){
@凌驾
公共JsonElement序列化(MyPojo src,类型typeOfSrc,JsonSerializationContext){
JsonObject结果=新建JsonObject();
result.addProperty(“另一个测试属性”、“另一个测试值”);
返回结果;
}
});
Gson Gson=builder.create();
设置冲突=validator.validate(MyPojo);
System.out.println(gson.toJson(违规));
但它失败了,出现了类似的错误
方法5:工作但丑陋
我唯一能做到的就是使用特定于供应商(Hibernate)的ConstraintViolation实现类型注册序列化程序:
Set<ConstraintViolation<MyPojo>> violations = validator.validate(MyPojo);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(
new TypeToken<ConstraintViolationImpl>() {}.getType(),
new JsonSerializer<ConstraintViolation<MyPojo>>() {
@Override
public JsonElement serialize(ConstraintViolation<MyPojo> src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("aTestProperty", "A Test Value");
return result;
}
});
Gson gson = builder.create();
System.out.println(gson.toJson(violations));
设置冲突=validator.validate(MyPojo);
GsonBuilder=新的GsonBuilder();
builder.registerTypeAdapter(
新建TypeToken(){}.getType(),
新的JsonSerializer(){
@凌驾
公共JsonElement序列化(ConstraintViolation src,类型typeOfSrc,JsonSerializationContext){
JsonObject结果=新建JsonObject();
结果.addProperty(“aTestProperty”,“A测试值”);
返回结果;
}
});
Gson Gson=builder.create();
System.out.println(gson.toJson(违规));
有没有一种方法可以在不依赖于
ConstraintViolation
(即org.hibernate.validator.internal.engine.ConstraintViolationImpl
)的具体实现的情况下实现这一点?似乎没有一种合理的方法来序列化javax.validation.ConstraintViolation
对象。事实上,即使Jackson在尝试序列化集合时也会出错:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: fromIndex(0) > toIndex(-1) (through reference chain: java.util.HashSet[0]->org.hibernate.validator.internal.engine.ConstraintViolationImpl["propertyPath"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
目前,我只是将错误集转换为我编写的一组自定义POJO,并将其序列化
自定义ValidationError POJO:
但是,生成的对象图过于冗长,不适合在生产中使用。您可以看到示例输出
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(
new TypeToken<ConstraintViolation<MyPojo>>() {}.getType(),
new JsonSerializer<ConstraintViolation<MyPojo>>() {
@Override
public JsonElement serialize(ConstraintViolation<MyPojo> src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("aTestProperty", "A Test Value");
return result;
}
});
builder.registerTypeAdapter(
new TypeToken<MyPojo>() {}.getType(),
new JsonSerializer<MyPojo>() {
@Override
public JsonElement serialize(MyPojo src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("anotherTestProperty", "Another Test Value");
return result;
}
});
Gson gson = builder.create();
Set<ConstraintViolation<MyPojo>> violations = validator.validate(MyPojo);
System.out.println(gson.toJson(violations));
Set<ConstraintViolation<MyPojo>> violations = validator.validate(MyPojo);
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(
new TypeToken<ConstraintViolationImpl>() {}.getType(),
new JsonSerializer<ConstraintViolation<MyPojo>>() {
@Override
public JsonElement serialize(ConstraintViolation<MyPojo> src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.addProperty("aTestProperty", "A Test Value");
return result;
}
});
Gson gson = builder.create();
System.out.println(gson.toJson(violations));
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: fromIndex(0) > toIndex(-1) (through reference chain: java.util.HashSet[0]->org.hibernate.validator.internal.engine.ConstraintViolationImpl["propertyPath"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"]->org.hibernate.validator.internal.engine.path.PathImpl["pathWithoutLeafNode"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
public class ValidationError {
private String className;
private String propertyPath;
private String errorMessage;
public static Set<ValidationError> fromViolations(Set violations) {
Set<ValidationError> errors = new HashSet<ValidationError>();
for (Object o : violations) {
ConstraintViolation v = (ConstraintViolation) o;
ValidationError error = new ValidationError();
error.setClassName(v.getRootBeanClass().getSimpleName());
error.setErrorMessage(v.getMessage());
error.setPropertyPath(v.getPropertyPath().toString());
errors.add(error);
}
return errors;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getPropertyPath() {
return propertyPath;
}
public void setPropertyPath(String propertyPath) {
this.propertyPath = propertyPath;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
@Override
public String toString() {
return "ValidationError{" +
"className='" + className + '\'' +
", propertyPath='" + propertyPath + '\'' +
", errorMessage='" + errorMessage + '\'' +
'}';
}
}
Set<ConstraintViolation<MyBean>> violations = validator.validate(myBean);
Set<ValidationError> errors = ValidationError.fromViolations(violations);
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
System.out.println(gson.toJson(errors));
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.setMode(XStream.NO_REFERENCES);
System.out.println(xstream.toXML(violations));