无法使用 Dozzer Mapper 将自定义对象复制到 Apache-CXF 生成的对象
Unable to copy custom Object to Apache-CXF generated Object using Dozzer Mapper
我正在使用 Apache CXF (org.apache.cxf) maven 插件来自动生成 Java 文件 (wsdl2java) 并希望将业务逻辑生成的响应对象复制到Apache CXF 使用 Dozer 映射器自动生成的文件。但是 Dozer 映射器无法将列表对象从源复制到目标,因为列表的 setter 方法不是使用 CXF 插件生成的。
XSD 文件:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com/test/ram/webservices/customer" targetNamespace="http://com/test/ram/webservices/customer" elementFormDefault="qualified">
<xs:element name="customerRequest" type="tns:customerRequestType" />
<xs:complexType name="customerRequestType">
<xs:sequence>
<xs:element name="CustomerID" type="xs:string" minOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="customerResponse" type="tns:customerResponseType" />
<xs:complexType name="customerResponseType">
<xs:sequence>
<xs:element name="TemplateList" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Template" type="xs:string" minOccurs="0" maxOccurs="unbounded" >
<xs:annotation>
<xs:documentation>
TemplateList.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
pom.xml
org.apache.cxf plugin to generate wsdl2java
自定义客户class:
public class customerResponse {
private customerResponse.TemplateList templateList;
public customerResponse .TemplateList getTemplateList() {
return templateList;
}
public void setTemplateList(customerResponse .TemplateList value) {
this.templateList = value;
}
public static class TemplateList {
private List<String> template;
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
public void setTemplate(List<String> tmp) {
template=tmp
}
}
}
CXF 插件自动生成的 CustomerResponse 对象
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customerResponse", propOrder = {
"templateList"
})
public class customerResponse {
@XmlElement(name = "TemplateList", required = true)
protected customerResponse.TemplateList templateList;
public customerResponse .TemplateList getTemplateList() {
return templateList;
}
public void setTemplateList(customerResponse .TemplateList value) {
this.templateList = value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"template"
})
public static class TemplateList {
@XmlElement(name = "Template")
protected List<String> template;
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
}
}
Dozer 映射程序无法复制模板列表。
customerResponse response = dozerMapper.map(customerResponse, customerResponse.class);
那么,在自动生成的 java class 中没有 setter 方法的情况下,有没有办法使用 Dozer 映射器复制列表对象?
您可以使用生成 setter 方法的 JAXB2 Setters 插件。
插件由 -Xsetters
命令行选项激活。
您还可以使用 -Xsetters-mode=accessor
或 -Xsetters-mode=direct
选项来配置生成模式。
参考下面的maven示例来配置这个插件
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version><!-- Current version --></version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-Xcopyable</arg>
<arg>-Xmergeable</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version><!-- Current version --></version>
</plugin>
</plugins>
</configuration>
</plugin>
还要在 pom.xml 中添加以下依赖项,因为生成的代码依赖于它。
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
<version><!-- Current version --></version>
</dependency>
参考这个 link for more help. Also, there is a user guide 可能会有帮助。
我从参考文献 Link 得到了解决方案,现在我可以看到生成的 java class 有 setter 列表方法。
https://gist.github.com/meiwin/2779731
https://github.com/highsource/hyperjaxb3-support/issues/4
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>moc.scodma.tsacmoc.mra</groupId>
<artifactId>mra</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>mra-messaging-schema</artifactId>
<properties>
<src.generated.dir>src/main/java</src.generated.dir>
<artifact.cxf.version>3.1.6</artifact.cxf.version>
<xerces.version>2.11.0</xerces.version>
<inbound.wsdl>src/main/resources/wsdl/inbound/tsacmocService.wsdl</inbound.wsdl>
<inbound.wsdl.location>classpath:resources/wsdl/inbound/tsacmocService.wsdl</inbound.wsdl.location>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.0.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${artifact.cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${src.generated.dir}</sourceRoot>
<defaultOptions>
<noAddressBinding>true</noAddressBinding>
<faultSerialVersionUID>3105839350746982386</faultSerialVersionUID>
</defaultOptions>
<wsdlOptions>
<wsdlOption>
<wsdl>${inbound.wsdl}</wsdl>
<wsdlLocation>${inbound.wsdl.location}</wsdlLocation>
<serviceName>mraService</serviceName>
<extraargs>
<extraarg>-xjc-Xts</extraarg>
<extraarg>-xjc-Xcollection-setter-injector</extraarg>
<extraarg>-client</extraarg>
<extraarg>-verbose</extraarg>
<extraarg>-p</extraarg>
<extraarg>http://tsacmoc.ent.moc/mra/=moc.ent.tsacmoc.mra</extraarg>
<extraarg>-p</extraarg>
<extraarg>http://tsacmoc.ent.moc/mocmonheader/=moc.ent.tsacmoc.mocmonheader</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xerces.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>net.java.dev.vcc.thirdparty</groupId>
<artifactId>collection-setter-injector</artifactId>
<version>0.5.0-1</version>
</dependency>
<dependency>
<groupId>moc.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>moc.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
java :
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"template"
})
public static class TemplateList {
@XmlElement(name = "Template")
protected List<String> template;
/**
* Gets the value of the template property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the template property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getTemplate().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
/**
* Sets the value of the template property.
*
* @param template
* allowed object is
* {@link String }
*
*/
public void setTemplate(List<String> template) {
this.template = template;
}
}
我正在使用 Apache CXF (org.apache.cxf) maven 插件来自动生成 Java 文件 (wsdl2java) 并希望将业务逻辑生成的响应对象复制到Apache CXF 使用 Dozer 映射器自动生成的文件。但是 Dozer 映射器无法将列表对象从源复制到目标,因为列表的 setter 方法不是使用 CXF 插件生成的。
XSD 文件:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com/test/ram/webservices/customer" targetNamespace="http://com/test/ram/webservices/customer" elementFormDefault="qualified">
<xs:element name="customerRequest" type="tns:customerRequestType" />
<xs:complexType name="customerRequestType">
<xs:sequence>
<xs:element name="CustomerID" type="xs:string" minOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="customerResponse" type="tns:customerResponseType" />
<xs:complexType name="customerResponseType">
<xs:sequence>
<xs:element name="TemplateList" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Template" type="xs:string" minOccurs="0" maxOccurs="unbounded" >
<xs:annotation>
<xs:documentation>
TemplateList.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
pom.xml
org.apache.cxf plugin to generate wsdl2java
自定义客户class:
public class customerResponse {
private customerResponse.TemplateList templateList;
public customerResponse .TemplateList getTemplateList() {
return templateList;
}
public void setTemplateList(customerResponse .TemplateList value) {
this.templateList = value;
}
public static class TemplateList {
private List<String> template;
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
public void setTemplate(List<String> tmp) {
template=tmp
}
}
}
CXF 插件自动生成的 CustomerResponse 对象
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customerResponse", propOrder = {
"templateList"
})
public class customerResponse {
@XmlElement(name = "TemplateList", required = true)
protected customerResponse.TemplateList templateList;
public customerResponse .TemplateList getTemplateList() {
return templateList;
}
public void setTemplateList(customerResponse .TemplateList value) {
this.templateList = value;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"template"
})
public static class TemplateList {
@XmlElement(name = "Template")
protected List<String> template;
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
}
}
Dozer 映射程序无法复制模板列表。
customerResponse response = dozerMapper.map(customerResponse, customerResponse.class);
那么,在自动生成的 java class 中没有 setter 方法的情况下,有没有办法使用 Dozer 映射器复制列表对象?
您可以使用生成 setter 方法的 JAXB2 Setters 插件。
插件由 -Xsetters
命令行选项激活。
您还可以使用 -Xsetters-mode=accessor
或 -Xsetters-mode=direct
选项来配置生成模式。
参考下面的maven示例来配置这个插件
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version><!-- Current version --></version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<arg>-XtoString</arg>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-Xcopyable</arg>
<arg>-Xmergeable</arg>
</args>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version><!-- Current version --></version>
</plugin>
</plugins>
</configuration>
</plugin>
还要在 pom.xml 中添加以下依赖项,因为生成的代码依赖于它。
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
<version><!-- Current version --></version>
</dependency>
参考这个 link for more help. Also, there is a user guide 可能会有帮助。
我从参考文献 Link 得到了解决方案,现在我可以看到生成的 java class 有 setter 列表方法。
https://gist.github.com/meiwin/2779731
https://github.com/highsource/hyperjaxb3-support/issues/4
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>moc.scodma.tsacmoc.mra</groupId>
<artifactId>mra</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>mra-messaging-schema</artifactId>
<properties>
<src.generated.dir>src/main/java</src.generated.dir>
<artifact.cxf.version>3.1.6</artifact.cxf.version>
<xerces.version>2.11.0</xerces.version>
<inbound.wsdl>src/main/resources/wsdl/inbound/tsacmocService.wsdl</inbound.wsdl>
<inbound.wsdl.location>classpath:resources/wsdl/inbound/tsacmocService.wsdl</inbound.wsdl.location>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.0.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${artifact.cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${src.generated.dir}</sourceRoot>
<defaultOptions>
<noAddressBinding>true</noAddressBinding>
<faultSerialVersionUID>3105839350746982386</faultSerialVersionUID>
</defaultOptions>
<wsdlOptions>
<wsdlOption>
<wsdl>${inbound.wsdl}</wsdl>
<wsdlLocation>${inbound.wsdl.location}</wsdlLocation>
<serviceName>mraService</serviceName>
<extraargs>
<extraarg>-xjc-Xts</extraarg>
<extraarg>-xjc-Xcollection-setter-injector</extraarg>
<extraarg>-client</extraarg>
<extraarg>-verbose</extraarg>
<extraarg>-p</extraarg>
<extraarg>http://tsacmoc.ent.moc/mra/=moc.ent.tsacmoc.mra</extraarg>
<extraarg>-p</extraarg>
<extraarg>http://tsacmoc.ent.moc/mocmonheader/=moc.ent.tsacmoc.mocmonheader</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xerces.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>net.java.dev.vcc.thirdparty</groupId>
<artifactId>collection-setter-injector</artifactId>
<version>0.5.0-1</version>
</dependency>
<dependency>
<groupId>moc.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.1.8</version>
</dependency>
<dependency>
<groupId>moc.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
java :
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"template"
})
public static class TemplateList {
@XmlElement(name = "Template")
protected List<String> template;
/**
* Gets the value of the template property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the template property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getTemplate().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
*
*
*/
public List<String> getTemplate() {
if (template == null) {
template = new ArrayList<String>();
}
return this.template;
}
/**
* Sets the value of the template property.
*
* @param template
* allowed object is
* {@link String }
*
*/
public void setTemplate(List<String> template) {
this.template = template;
}
}