Java JAXB解组器&x27;s handleEvent没有被调用
我正在尝试使用MOXy for JAXB JSON支持来设置一个简单的Jersey JAX-RS应用程序,我想定制解组器。我做了以下工作:Java JAXB解组器&x27;s handleEvent没有被调用,java,json,jaxb,jersey,Java,Json,Jaxb,Jersey,我正在尝试使用MOXy for JAXB JSON支持来设置一个简单的Jersey JAX-RS应用程序,我想定制解组器。我做了以下工作: @Provider public class CustomProvider extends ConfigurableMoxyJsonProvider{ @Override protected void preReadFrom(..., Unmarshaller unmarshaller) throws JAXBException{ super
@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
中的print语句,但不会执行事件处理程序中的print语句。因此,提供程序已正确注册,但未调用事件处理程序
什么可能导致此问题
我想要实现的是,当用户在JSON正文中传递无关的属性时,我想要抛出一个错误(默认情况下,这些属性被忽略)。在各种网站上搜索时,添加事件处理程序是唯一的方法。如果我也能以不同的方式实现这一点,那就太好了
System.out.println(“preReadFrom entered”)
被调用,您的CustomProvider
实际上已注册并使用。因为在Weblogic中,例如,即使您注册了不同的提供程序,仍然会调用默认的ConfigurableMoxyJsonProvider
,除非您禁用Moxypublic boolean handleEvent(ValidationEvent事件)
进行验证,就像您的Pojo属性是数值的,并且您正在json中传递字符串一样unappedelements
,我看到Moxy“忽略”了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使用的,在向事件处理程序发出警告之前,会检查媒体类型是否为xmlpreReadFrom
方法中,添加自定义unappedHandlerClass
,如下所示
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;
}
});
}
那就行了。但在尝试3之前,只需通过添加断点或System.out确保您的a)CustomProvider实际上正在被调用。。陈述b)handleEvent会因一般错误而被调用,例如在json中传递字符串x,作为数字字段。为什么不在传递之前自定义传递给
preReadFrom
的Unmarshaller
?为什么你需要一个全新的供应商?你能提供一些可以运行的代码来进行测试吗?我正在这样做。我正在自定义传递给preReadFrom
的解组器。通过定制,如果你的意思是设置一些属性的话-我在问题中添加了我的意图。我找不到任何达到此目的的属性。在将解组器传递到preReadFrom
方法之前,您能否访问它?它是从哪里来的?有什么特别的原因会对你有好处吗?我们也可以这样做吗?那么您可以直接更改解组器
,而不必创建新的提供者。哪里调用了preReadFrom
?在说了这些之后,我还想与Moxy团队的@blaise doughan核实一下,看看是否有更简单的方法来处理未映射的Json字段。@nitishc我想实现的是当用户在Json正文中传递无关的属性时,我想抛出一个错误
这一行建议您确实需要自定义未映射内容处理器以及ValidationHandler。哇!感谢第2点中的详细说明。到目前为止,我通过传递一个无效的JSON进行检查。在这种情况下,不会调用handleEvent。但是当我传递一个字符串而不是一个数字时——正如你所说——它被称为!我想知道为什么。第3点@nitishch解释了这一点,原因是默认的“unmap”元素处理只适用于xml,因为上面第3点提到了签入类。这可以用我添加的代码片段来解决,这是因为ContextResolver中的一些错误配置。我在ContextResolver中有JAXBContext.property(ServerProperties.MOXY\u JSON\u FEATURE\u DISABLE,true)
。出于某种原因,我删除了它,现在一切正常:)
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);
}
}