使用注释时如何在 JAXB 解组器上设置自定义 ValidationEventHandler [英] How to set custom ValidationEventHandler on JAXB unmarshaller when using annotations

查看:37
本文介绍了使用注释时如何在 JAXB 解组器上设置自定义 ValidationEventHandler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们将 JAX-WS 与 JAXB 结合使用来接收和解析 XML Web 服务调用.它都是基于注解的,即我们永远不会在我们的代码中获得 JAXBContext.我需要在解组器上设置一个自定义的 ValidationEventHandler,以便如果不接受特定字段的日期格式,我们可以捕获错误并在响应中报告一些不错的内容.我们在相关字段上有一个 XMLJavaTypeAdapter,它进行解析并抛出异常.我看不到如何使用我们拥有的基于注释的配置将 ValidationEventHandler 设置到解组器上.有什么想法吗?

We’re using JAX-WS in combination with JAXB to receive and parse XML web service calls. It’s all annotation-based, i.e. we never get hold of the JAXBContext in our code. I need to set a custom ValidationEventHandler on the unmarshaller, so that if the date format for a particular field is not accepted, we can catch the error and report something nice back in the response. We have a XMLJavaTypeAdapter on the field in question, which does the parsing and throws an exception. I can’t see how to set a ValidationEventHandler onto the unmarshaller using the annotation-based configuration that we have. Any ideas?

注意:与此评论相同的问题目前尚未得到答复.

Note: same question as this comment which is currently unanswered.

推荐答案

上周我一直在努力解决这个问题,最后我找到了一个可行的解决方案.诀窍是 JAXB 在用 @XmlRootElement 注释的对象中查找 beforeUnmarshal 和 afterUnmarshal 方法.

I have been struggling with this issue during the last week and finally i have managed a working solution. The trick is that JAXB looks for the methods beforeUnmarshal and afterUnmarshal in the object annotated with @XmlRootElement.

..
@XmlRootElement(name="MSEPObtenerPolizaFechaDTO")
@XmlAccessorType(XmlAccessType.FIELD)

public class MSEPObtenerPolizaFechaDTO implements Serializable {
..

public void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException, IOException, SAXException {
        unmarshaller.setSchema(Utils.getSchemaFromContext(this.getClass()));
        unmarshaller.setEventHandler(new CustomEventHandler());
  }

  public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException {
        unmarshaller.setSchema(null);
        unmarshaller.setEventHandler(null);
  }

使用这个 ValidationEventHandler:

Using this ValidationEventHandler:

public class CustomEventHandler implements ValidationEventHandler{

      @Override
      public boolean handleEvent(ValidationEvent event) {
            if (event.getSeverity() == event.ERROR ||
                        event.getSeverity() == event.FATAL_ERROR)
            {
                  ValidationEventLocator locator = event.getLocator();
                  throw new RuntimeException(event.getMessage(), event.getLinkedException());
            }
            return true;
      }
}

}

这是在您的 Utility 类中创建的 getSchemaFromContext 方法:

And this is the method getSchemaFromContext created in your Utility class:

  @SuppressWarnings("unchecked")
  public static Schema getSchemaFromContext(Class clazz) throws JAXBException, IOException, SAXException{
        JAXBContext jc = JAXBContext.newInstance(clazz);
        final List<ByteArrayOutputStream> outs = new ArrayList<ByteArrayOutputStream>();
        jc.generateSchema(new SchemaOutputResolver(){
              @Override
              public Result createOutput(String namespaceUri,
                         String suggestedFileName) throws IOException {
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              outs.add(out);
              StreamResult streamResult = new StreamResult(out);
              streamResult.setSystemId("");
              return streamResult;
              }
        });
        StreamSource[] sources = new StreamSource[outs.size()];
        for (int i = 0; i < outs.size(); i++) {
              ByteArrayOutputStream out = outs.get(i);
              sources[i] = new StreamSource(new ByteArrayInputStream(out.toByteArray()), "");
        }
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        return sf.newSchema(sources);
  }

这篇关于使用注释时如何在 JAXB 解组器上设置自定义 ValidationEventHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆