当前位置: 首页 > 知识库问答 >
问题:

使用注释时如何在JAXB解组器上设置自定义ValidationEventHandler

微生嘉
2023-03-14

我们结合使用JAX-WS和JAXB来接收和解析XML web服务调用。所有这些都是基于注释的,也就是说,我们在代码中从未掌握过JAXBContext。我需要在解组器上设置一个自定义ValidationEventHandler,这样,如果某个特定字段的日期格式不被接受,我们就可以捕获错误并在响应中报告一些好消息。我们在讨论的字段上有一个XMLJavaTypeAdapter,它进行解析并引发异常。我看不出如何使用我们现有的基于注释的配置将ValidationEventHandler设置到解组器上。有什么想法吗?

注:与此评论相同的问题,目前尚未回答。

共有1个答案

林弘壮
2023-03-14

上周我一直在努力解决这个问题,终于找到了一个可行的解决办法。诀窍在于,JAXB在注释为@XmlRootElement的对象中查找Unmarshal之前和Unmarshal之后的方法。

..
@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:

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;
      }
}

}

这是在实用程序类中创建的getSchemaFromContext方法:

  @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);
  }
 类似资料:
  • 问题内容: 我有一个要求,根据字段上标记的自定义注释来编组/解组java pojo的某些元素。假设我的Java pojp中有3个字段 如果我在jaxb中进行转换时传递version =“ v1”参数,我只想编组具有v1的字段。如果我通过v2,则所有带v2注释的字段都应编组。 甚至可以使用jaxb吗?我确信选择性的编组将通过某种图书馆或某种方式得到支持,经过大量的搜索后仍无法弄清楚。任何帮助或建议或

  • 问题内容: 用例: 想要将自定义注释插入由JAXB生成的Java类中的字段 问题: 使用Annotate插件+ JAXB [1],能够成功插入自定义注释,但是它们是通过getter方法而非字段插入的。Morphia(mongo DB)批注(我实际上要插入)批注只能批注java字段[2]。 我的测试XSD: 我的测试绑定xjb: 我生成的Java代码段: 如您所见,我要注释“栏”字段。请指教。如有需

  • 我想使用自定义Java注释,使用Spring AOP(和/或AspectJ)在私有类属性中插入一个值。快速示例: 我的注释。java: MyController.java: 我的方面。java: 我将调用并进入,在它返回后,我希望在控制台或日志中看到“helloworld”。我想使用AOP将var1设置为自定义值。用MyAnnotation注释的任何属性变量都将设置为“helloworld”。我希

  • 我发现了几个与此相关的(不是重复的)问题,但它们不能让我满意。 我无法理解在哪里以及为什么要使用? 我在一本书中读到了一个自定义注释的示例,但没有详细解释。 myMeth()内的输出与预期一致。 关于这个例子,我有几个问题。 1-如何在此程序中使用和?或

  • 问题是我写了简单的注释处理器,它根本不处理类型注释。simple annotations processor的源代码如下所示: 有什么想法如何使用或如何通过SimpleAnnotationsProcessor访问类型注释吗?使用可插入的注释处理API对我来说是不必要的,我认为它会比Java反射有更好的性能。无论如何,我也不知道如何通过Java反射访问类型注释。

  • 我正在尝试使用Spring安全注释,如@PreAuthorize和@安全,但我希望评估用户不是在一个角色上,而是他们是否拥有对特定实体的权限,在这种情况下是一家公司。在我的控制器中,我收到一个超文本传输协议请求,其中包含一个firmId作为参数,我想确保这个用户被允许进入这家公司。是否可以使用当前的Spring安全注释?。我正在寻找一个优雅的解决方案,我一直在寻找自定义约束验证器作为jsr303规