JAXB unmarshaller 的 handleEvent 未被调用
JAXB unmarshaller's handleEvent not being called
我正在尝试使用 MOXy 设置一个简单的 Jersey JAX-RS 应用程序以获得 JAXB JSON 支持,并且我想自定义解组器。我做了以下事情:
@Provider
public class CustomProvider extends ConfigurableMoxyJsonProvider{
@Override
protected void preReadFrom(..., Unmarshaller unmarshaller) throws JAXBException{
super.preReadFrom(...);
System.out.println("preReadFrom entered");
unmarshaller.setEventHandler(new ValidationEventHandler(){
@Override
public boolean handleEvent(ValidationEvent event){
System.out.println("Entered handleEvent");
return false;
}
});
}
}
我为 preReadFrom
写了一个覆盖并在解组器上设置了一个事件处理程序。当我传递无效的 JSON 正文时,preReadFrom
中的打印语句会执行,但不会执行事件处理程序中的语句。因此提供程序已正确注册,但未调用事件处理程序。
什么可能导致此问题?
我想要实现的是当用户在 JSON 正文中传递无关属性时,我想抛出一个错误(默认情况下,这些属性被忽略)。在各种网站上搜索,添加事件处理程序是唯一的方法。如果我也能以不同的方式实现这一点,那就太好了。
我假设 System.out.println("preReadFrom entered");
正在调用,而您的 CustomProvider
实际上 已注册和使用。因为在 Weblogic 中,例如,即使您注册了不同的提供程序,除非您禁用 Moxy,否则默认值 ConfigurableMoxyJsonProvider
仍会被调用。
如果第一个假设是正确的,那么您肯定会收到 public boolean handleEvent(ValidationEvent event)
要求进行验证,例如如果您的 Pojo 属性是数字的并且您在 [=52= 中传递字符串].
对于UnmappedElements
,我看到了Moxy,"ignores" Json的警告。这意味着如果您的 pojo 如下所示:
public class Emp {
public Emp() {
super();
}
private int id ;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
而您的 Json 就像:{"id" : 11, "name1" : 111}
那么您的 handleEvent
将不会被调用。原因是 Moxy 使用 org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startUnmappedElement() 在向事件处理程序发出警告之前检查媒体类型是否为 xml。
那么throw怎么解决呢。我可能不知道最佳答案,但这是我的解决方案:
在您的 preReadFrom
方法中添加您的自定义 UnmappedHandlerClass
如下所示
protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
Unmarshaller unmarshaller) throws JAXBException {
System.out.println("preReadFrom entered");
super.preReadFrom(type, genericType, annotations, MediaType.WILDCARD_TYPE, httpHeaders, unmarshaller);
System.out.println("preReadFrom returned from super");
//new code
if(unmarshaller instanceof org.eclipse.persistence.jaxb.JAXBUnmarshaller) {
org.eclipse.persistence.jaxb.JAXBUnmarshaller moxyUn = ( org.eclipse.persistence.jaxb.JAXBUnmarshaller)unmarshaller;
moxyUn.getXMLUnmarshaller().setUnmappedContentHandlerClass(CustomUnmapped.class);
}
//your existing code
unmarshaller.setEventHandler(new ValidationEventHandler() {
@Override
public boolean handleEvent(ValidationEvent event) {
System.out.println("Entered handleEvent");
return false;
}
});
}
您可以像这样使用 Customunmapped class:
class CustomUnmapped extends org.eclipse.persistence.internal.oxm.unmapped.DefaultUnmappedContentHandler {
@Override
public void startElement(String p1, String p2, String p3, Attributes p4) throws SAXException {
throw new SAXNotRecognizedException(p1);
}
}
那应该行得通。但在尝试 3 之前,只需确保您的 a) CustomProvider 实际上是通过添加断点或 System.out.. 语句来调用的。和 b) 您的 handleEvent 被调用用于一般错误,例如在 json 中为数字字段传递字符串 x。
我正在尝试使用 MOXy 设置一个简单的 Jersey JAX-RS 应用程序以获得 JAXB JSON 支持,并且我想自定义解组器。我做了以下事情:
@Provider
public class CustomProvider extends ConfigurableMoxyJsonProvider{
@Override
protected void preReadFrom(..., Unmarshaller unmarshaller) throws JAXBException{
super.preReadFrom(...);
System.out.println("preReadFrom entered");
unmarshaller.setEventHandler(new ValidationEventHandler(){
@Override
public boolean handleEvent(ValidationEvent event){
System.out.println("Entered handleEvent");
return false;
}
});
}
}
我为 preReadFrom
写了一个覆盖并在解组器上设置了一个事件处理程序。当我传递无效的 JSON 正文时,preReadFrom
中的打印语句会执行,但不会执行事件处理程序中的语句。因此提供程序已正确注册,但未调用事件处理程序。
什么可能导致此问题?
我想要实现的是当用户在 JSON 正文中传递无关属性时,我想抛出一个错误(默认情况下,这些属性被忽略)。在各种网站上搜索,添加事件处理程序是唯一的方法。如果我也能以不同的方式实现这一点,那就太好了。
我假设
System.out.println("preReadFrom entered");
正在调用,而您的CustomProvider
实际上 已注册和使用。因为在 Weblogic 中,例如,即使您注册了不同的提供程序,除非您禁用 Moxy,否则默认值ConfigurableMoxyJsonProvider
仍会被调用。如果第一个假设是正确的,那么您肯定会收到
public boolean handleEvent(ValidationEvent event)
要求进行验证,例如如果您的 Pojo 属性是数字的并且您在 [=52= 中传递字符串].对于
UnmappedElements
,我看到了Moxy,"ignores" Json的警告。这意味着如果您的 pojo 如下所示:public class Emp { public Emp() { super(); } private int id ; public void setId(int id) { this.id = id; } public int getId() { return id; } }
而您的 Json 就像:
{"id" : 11, "name1" : 111}
那么您的handleEvent
将不会被调用。原因是 Moxy 使用 org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startUnmappedElement() 在向事件处理程序发出警告之前检查媒体类型是否为 xml。
那么throw怎么解决呢。我可能不知道最佳答案,但这是我的解决方案:
在您的 preReadFrom
方法中添加您的自定义 UnmappedHandlerClass
如下所示
protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
Unmarshaller unmarshaller) throws JAXBException {
System.out.println("preReadFrom entered");
super.preReadFrom(type, genericType, annotations, MediaType.WILDCARD_TYPE, httpHeaders, unmarshaller);
System.out.println("preReadFrom returned from super");
//new code
if(unmarshaller instanceof org.eclipse.persistence.jaxb.JAXBUnmarshaller) {
org.eclipse.persistence.jaxb.JAXBUnmarshaller moxyUn = ( org.eclipse.persistence.jaxb.JAXBUnmarshaller)unmarshaller;
moxyUn.getXMLUnmarshaller().setUnmappedContentHandlerClass(CustomUnmapped.class);
}
//your existing code
unmarshaller.setEventHandler(new ValidationEventHandler() {
@Override
public boolean handleEvent(ValidationEvent event) {
System.out.println("Entered handleEvent");
return false;
}
});
}
您可以像这样使用 Customunmapped class:
class CustomUnmapped extends org.eclipse.persistence.internal.oxm.unmapped.DefaultUnmappedContentHandler {
@Override
public void startElement(String p1, String p2, String p3, Attributes p4) throws SAXException {
throw new SAXNotRecognizedException(p1);
}
}
那应该行得通。但在尝试 3 之前,只需确保您的 a) CustomProvider 实际上是通过添加断点或 System.out.. 语句来调用的。和 b) 您的 handleEvent 被调用用于一般错误,例如在 json 中为数字字段传递字符串 x。