[英]Insert custom setter in maven-jaxb2-plugin
I'm using the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin to create POJOs from XSD schema files. 我正在使用org.jvnet.jaxb2.maven2:maven-jaxb2-plugin从XSD架构文件创建POJO。
Now I want to insert something like a custom setter. 现在我想插入类似自定义setter的东西。 It should trim all Strings and should remove certain characters. 它应修剪所有字符串,并应删除某些字符。
Do you know how to do this? 你知道怎么做吗?
The XJB file: XJB文件:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<jaxb:bindings schemaLocation="my-schema-xml4.xsd" node="/xs:schema">
<xjc:javaType name="java.lang.String" adapter="my.StringAdapter" />
</jaxb:bindings>
</jaxb:bindings>
Solution for binding Java types: 绑定Java类型的解决方案:
<?xml version="1.0" encoding="UTF-8" ?>
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<bindings schemaLocation="mySchema-xml4.xsd" node="/xs:schema">
<globalBindings>
<xjc:javaType name="java.lang.String" xmlType="xs:string"
adapter="com.name.MyAdapter" />
<xjc:javaType name="java.lang.String" xmlType="xs:anySimpleType"
adapter="com.name.MyAdapter" />
</globalBindings>
</bindings>
</bindings>
But the @XmlJavaTypeAdapter
still isn't added to the content
property in nodes with mixed content, although the property has the type java.lang.String
. 但是@XmlJavaTypeAdapter
仍然没有添加到具有混合内容的节点中的content
属性,尽管该属性的类型为java.lang.String
。
I think the best way to achieve this is to implement an own XmlAdapter and configure it via the property customization. 我认为实现这一目标的最佳方法是实现自己的XmlAdapter并通过属性自定义进行配置。 You can do this with a standard jaxb:property
customization or with the annotate plugin . 您可以使用标准的jaxb:property
自定义或使用annotate插件执行此操作 。
jaxb:property
: jaxb:property
:
<jaxb:property>
<jaxb:baseType>
<xjc:javaType name="java.lang.String"
adapter="com.acme.foo.MyAdapter"/>
</jaxb:baseType>
</jaxb:property>
Annotate plugin: 注释插件:
<annox:annotate target="field">
<annox:annotate
annox:class="javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter"
value="com.acme.foo.MyAdapter"/>
</annox:annotate>
See the sample project here: 请在此处查看示例项目:
https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/tests/one/ https://svn.java.net/svn/jaxb2-commons~svn/basics/trunk/tests/one/
If your XSD will not change in the future just generate the POJOs, comment out the JAXB plugin and modify the source by hand. 如果您的XSD将来不会更改,只需生成POJO,注释掉JAXB插件并手动修改源代码。
If your XSD changes rarely you still can use this solution with a version control system. 如果您的XSD 很少更改,您仍然可以将此解决方案与版本控制系统一起使用。 Commit the generated source, modify the POJOs and commit the modifications. 提交生成的源,修改POJO并提交修改。 Next time when the XSD is modified generate a patch between the two commits, generate the POJOs from the new XSD and apply the patch. 下次修改XSD时,在两次提交之间生成补丁,从新的XSD生成POJO并应用补丁。 I found this solution a lot simpler in cases where the XSD almost never changes. 在XSD几乎从不改变的情况下,我发现这个解决方案更简单。
An alternate approach would be to use a StAX StreamReaderDelegate
to manipulate the XML text before it was received by the JAXB implementation. 另一种方法是使用StAX StreamReaderDelegate
在JAXB实现接收XML文本之前对其进行操作。
Demo 演示
Your code would look something like the following. 您的代码看起来如下所示。 You would implement a StreamReaderDelegate
to manipulate the text returned from the text events: 您将实现StreamReaderDelegate
来操作从文本事件返回的文本:
package forum7329881;
import java.io.FileInputStream;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum7329881/input.xml"));
xsr = new MyStreamReaderDelegate(xsr);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Customer customer = (Customer) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
private static class MyStreamReaderDelegate extends StreamReaderDelegate {
public MyStreamReaderDelegate(XMLStreamReader xsr) {
super(xsr);
}
@Override
public String getText() {
return super.getText().trim();
}
@Override
public char[] getTextCharacters() {
return getText().toCharArray();
}
@Override
public int getTextLength() {
return getText().length();
}
@Override
public int getTextStart() {
return 0;
}
}
}
input.xml input.xml中
Below is sample input that contains whitespace in the text nodes: 下面是包含文本节点中的空格的示例输入:
<customer Id="1">
<name> Jane Doe </name>
<address>
<street> 123 A Street </street>
</address>
</customer>
Output 产量
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<address>
<street>123 A Street A</street>
</address>
<name>Jane Doe</name>
</customer>
Customer 顾客
package forum7329881;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {
private String name;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address 地址
package forum7329881;
public class Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
For More Information 欲获得更多信息
Below is a link to a more detailed example where I used a StAX StreamReaderDelegate
to support case insensitive unmarshalling: 下面是一个更详细的示例的链接,其中我使用StAX StreamReaderDelegate
来支持不区分大小写的解组:
In my opinion, you should use AOP, Pick Spring AOP, for instance, Intercept the Adapter methods to have trim / strip logic. 在我看来,你应该使用AOP,Pick Spring AOP,例如Intercept the Adapter方法来修剪/剥离逻辑。 In fact this can now be a generic logic that would apply to all string types. 实际上,现在这可以是适用于所有字符串类型的通用逻辑。 If this sounds convincing, I can further help with the code 如果这听起来令人信服,我可以进一步帮助代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.