Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JAXB解组器&x27;s handleEvent没有被调用_Java_Json_Jaxb_Jersey - Fatal编程技术网

Java JAXB解组器&x27;s handleEvent没有被调用

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

我正在尝试使用MOXy for JAXB JSON支持来设置一个简单的Jersey JAX-RS应用程序,我想定制解组器。我做了以下工作:

@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
    ,除非您禁用Moxy

  • 如果第一个假设是正确的,那么肯定会调用
    public 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使用的,在向事件处理程序发出警告之前,会检查媒体类型是否为xml

  • 那么如何解决这个问题呢。我可能不知道最好的答案,但以下是我的解决方案:

    preReadFrom
    方法中,添加自定义
    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);
        }
    }