Null 防止使用JAXB从XSD生成空@XmlType注释
让我从我的问题归结为什么开始。我正在使用maven-jaxb2-plugin从XSD模式生成一个名为MyServiceResponse的类。生成的MyServiceResponse类包含带有空名称属性的Null 防止使用JAXB从XSD生成空@XmlType注释,null,jaxb,unmarshalling,xmlstreamreader,Null,Jaxb,Unmarshalling,Xmlstreamreader,让我从我的问题归结为什么开始。我正在使用maven-jaxb2-plugin从XSD模式生成一个名为MyServiceResponse的类。生成的MyServiceResponse类包含带有空名称属性的@XmlType注释 @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { }) 我想使用填充的name属性生成MyServiceResponse,或者不使用@XmlType注释。这是否
@XmlType
注释
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
})
我想使用填充的name
属性生成MyServiceResponse,或者不使用@XmlType
注释。这是否可以在XJB文件中使用自定义绑定或以其他方式实现?无论如何,如果可能的话,我想在生成过程中解决这个问题,因为每次运行Maven插件时,对MyserviceResponse的手动编辑都会被覆盖
下面是一个Java类,它演示了我的实际问题。该类使用XmlStreamReader和JAXB从消息中的任何元素开始解组XML消息。“xml”变量未完全解组。“car”属性保持为空。发生这种情况的原因是xmlns=”http://www.example.com/type
命名空间由XmlStreamReader复制到Body元素,但不复制到Car子元素。不知何故,JAXB无法看到我希望它继续对Car元素进行解组。(这里有个大问号)
我已经知道一些修复,但它们涉及到对XSD或MyServiceResponse类的手动更改
首先,我可以在XSD上设置elementFormDefault=“qualified”
,从中生成MyServiceResponse类、ObjectFactory和一个package-info.java。这是可行的,但它也会导致我的请求XML消息使用限定的名称空间进行封送,而我将消息发送到的服务不接受这一点。此外,它还需要对XSD进行更改,如果可能的话,我宁愿避免这样做
其次,在Body和Car@XmlType注释上设置名称起作用:@XmlType(name=“Body”,propOrder={})
和@XmlType(name=“Car”,propOrder={})
。但它需要手动编辑MyServiceResponse
第三个,删除@XmlType(name=”,propOrder={})
注释是可行的,但它还涉及到手动编辑MyServiceResponse
这是一个可复制的演示类:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.Reader;
import java.io.StringReader;
public class XmlStreamReaderUnmarshallingTest {
private static JAXBContext jaxbContext;
static {
try {
jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
} catch (JAXBException e) {
e.printStackTrace();
}
}
private static String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<soapenv:Envelope xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n" +
"\txmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" \n" +
"\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"\t<soapenv:Body>\n" +
"\t\t<response xmlns=\"http://www.example.com/type\">\n" +
"\t\t\t<type:serviceResponse xmlns:type=\"http://www.example.com/type\">\n" +
"\t\t\t\t<Body>\n" +
"\t\t\t\t\t<Car>\n" +
"\t\t\t\t\t\t<Brand>Mitsubishi</Brand>\n" +
"\t\t\t\t\t\t<Color>Red</Color>\n" +
"\t\t\t\t\t</Car>\n" +
"\t\t\t\t</Body>\n" +
"\t\t\t</type:serviceResponse>\n" +
"\t\t</response>\n" +
"\t</soapenv:Body>\n" +
"</soapenv:Envelope>";
private static String xmlStripped = "<type:serviceResponse xmlns:type=\"http://www.example.com/type\">\n" +
"\t\t\t\t<Body>\n" +
"\t\t\t\t\t<Car>\n" +
"\t\t\t\t\t\t<Brand>Mitsubishi</Brand>\n" +
"\t\t\t\t\t\t<Color>Red</Color>\n" +
"\t\t\t\t\t</Car>\n" +
"\t\t\t\t</Body>\n" +
"\t\t\t</type:serviceResponse>";
public static void main(String[] args) throws JAXBException, XMLStreamException {
readXml(xml, "serviceResponse");
readXml(xmlStripped, "serviceResponse");
}
private static void readXml(String inputXml, String startFromElement) throws JAXBException, XMLStreamException {
final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
final Reader reader = new StringReader(inputXml);
final XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(reader);
final XMLStreamReader streamReader = skipToElement(xmlStreamReader, startFromElement);
final MyServiceResponse serviceResponse = (MyServiceResponse) unmarshal(streamReader);
if(serviceResponse.getBody().getCar() == null) {
System.out.println("It didn't work :-(");
} else {
System.out.println("It worked");
}
}
private static XMLStreamReader skipToElement(final XMLStreamReader xsr, final String startAtElement) throws XMLStreamException {
while (startAtElement != null && xsr.hasNext()) {
xsr.next();
if (xsr.hasName()) {
final String name = xsr.getName().getLocalPart();
if (name.equals(startAtElement)) {
return xsr;
}
}
}
throw new IllegalArgumentException(String.format("Could not find element %s in response", startAtElement));
}
private static Object unmarshal(final XMLStreamReader xsr) throws JAXBException {
final Object entity = unmarshaller(jaxbContext).unmarshal(xsr);
return (entity instanceof JAXBElement ? ((JAXBElement) entity).getValue() : entity);
}
// Create unmarshaller every time
private static Unmarshaller unmarshaller(JAXBContext context) throws JAXBException {
return context.createUnmarshaller();
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MyServiceResponse", propOrder = {
})
class MyServiceResponse {
@XmlElement(name = "Body")
protected MyServiceResponse.Body body;
/**
* Gets the value of the body property.
*
* @return
* possible object is
* {@link MyServiceResponse.Body }
*
*/
public MyServiceResponse.Body getBody() {
return body;
}
/**
* Sets the value of the body property.
*
* @param value
* allowed object is
* {@link MyServiceResponse.Body }
*
*/
public void setBody(MyServiceResponse.Body value) {
this.body = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <all>
* <element name="Car" minOccurs="0">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <all>
* <element name="Brand" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="Color" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </all>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </all>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
})
public static class Body {
@XmlElement(name = "Car")
protected MyServiceResponse.Body.Car car;
/**
* Gets the value of the car property.
*
* @return
* possible object is
* {@link MyServiceResponse.Body.Car }
*
*/
public MyServiceResponse.Body.Car getCar() {
return car;
}
/**
* Sets the value of the car property.
*
* @param value
* allowed object is
* {@link MyServiceResponse.Body.Car }
*
*/
public void setCar(MyServiceResponse.Body.Car value) {
this.car = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <all>
* <element name="Brand" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="Color" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </all>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
})
public static class Car {
@XmlElement(name = "Brand")
protected String brand;
@XmlElement(name = "Color")
protected String color;
/**
* Gets the value of the brand property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getBrand() {
return brand;
}
/**
* Sets the value of the brand property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setBrand(String value) {
this.brand = value;
}
/**
* Gets the value of the color property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getColor() {
return color;
}
/**
* Sets the value of the color property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setColor(String value) {
this.color = value;
}
}
}
}
@XmlRegistry
class ObjectFactory {
private final static QName _ServiceResponse_QNAME = new QName("http://www.example.com/type", "serviceResponse");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.example.type
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {@link MyServiceResponse }
*
*/
public MyServiceResponse createMyServiceResponse() {
return new MyServiceResponse();
}
/**
* Create an instance of {@link MyServiceResponse.Body }
*
*/
public MyServiceResponse.Body createMyServiceResponseBody() {
return new MyServiceResponse.Body();
}
/**
* Create an instance of {@link MyServiceResponse.Body.Car }
*
*/
public MyServiceResponse.Body.Car createMyServiceResponseBodyCar() {
return new MyServiceResponse.Body.Car();
}
/**
* Create an instance of {@link JAXBElement }{@code <}{@link MyServiceResponse }{@code >}}
*
*/
@XmlElementDecl(namespace = "http://www.example.com/type", name = "serviceResponse")
public JAXBElement<MyServiceResponse> createServiceResponse(MyServiceResponse value) {
return new JAXBElement<MyServiceResponse>(_ServiceResponse_QNAME, MyServiceResponse.class, null, value);
}
}
import javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBElement;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Unmarshaller;
导入javax.xml.bind.annotation.*;
导入javax.xml.namespace.QName;
导入javax.xml.stream.XMLInputFactory;
导入javax.xml.stream.XMLStreamException;
导入javax.xml.stream.XMLStreamReader;
导入java.io.Reader;
导入java.io.StringReader;
公共类XmlStreamReaderUnmarshallingTest{
私有静态JAXBContext JAXBContext;
静止的{
试一试{
jaxbContext=jaxbContext.newInstance(ObjectFactory.class);
}捕获(JAXBEException e){
e、 printStackTrace();
}
}
私有静态字符串xml=“\n”+
“\n”+
“\t\n”+
“\t\t\n”+
“\t\t\t\n”+
“\t\t\t\t\n”+
“\t\t\t\t\t\n”+
“\t\t\t\t\t\tMitsubishi\n”+
“\t\t\t\t\t\t\tRed\n”+
“\t\t\t\t\t\n”+
“\t\t\t\t\n”+
“\t\t\t\n”+
“\t\t\n”+
“\t\n”+
"";
私有静态字符串xmlStripped=“\n”+
“\t\t\t\t\n”+
“\t\t\t\t\t\n”+
“\t\t\t\t\t\tMitsubishi\n”+
“\t\t\t\t\t\t\tRed\n”+
“\t\t\t\t\t\n”+
“\t\t\t\t\n”+
“\t\t\t”;
公共静态void main(字符串[]args)抛出JAXBEException、XMLStreamException{
readXml(xml,“服务响应”);
readXml(xmlStripped,“serviceResponse”);
}
私有静态void readXml(String inputXml,String startFromElement)抛出JAXBEException,XMLStreamException{
最终XMLInputFactory XMLInputFactory=XMLInputFactory.newFactory();
最终读取器=新的StringReader(inputXml);
最终XMLStreamReader=xmlInputFactory.createXMLStreamReader(读取器);
最终XMLStreamReader streamReader=skipToElement(XMLStreamReader,startFromElement);
最终MyServiceResponse serviceResponse=(MyServiceResponse)解组(streamReader);
如果(serviceResponse.getBody().getCar()==null){
System.out.println(“它不工作:-(”);
}否则{
System.out.println(“它成功了”);
}
}
私有静态XMLStreamReader skipToElement(最终XMLStreamReader xsr,最终字符串StartElement)抛出XMLStreamException{
while(startAtElement!=null&&xsr.hasNext()){
xsr.next();
if(xsr.hasName()){
最终字符串名称=xsr.getName().getLocalPart();
if(name.equals(startElement)){
返回xsr;
}
}
}
抛出新的IllegalArgumentException(String.format(“在响应中找不到元素%s”,StartElement));
}
私有静态对象解组(最终XMLStreamReader xsr)抛出JAXBEException{
最终对象实体=unmarshaller(jaxbContext).unmarshal(xsr);
返回(实体instanceof JAXBElement?((JAXBElement)entity).getValue():entity);
}
//每次创建解组器
私有静态解组器解组器(JAXBContext上下文)抛出JAXBEException{
返回context.createUnmarshaller();
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“MyServiceResponse”,proporter={
})
类MyServiceResponse{
@xmlement(name=“Body”)
保护我的服务响应。身体;
/**
*获取body属性的值。
*
*@返回
*可能的对象是
*{@link MyServiceResponse.Body}
*
*/
public-myservicesponse.Body-getBody(){
返回体;
}
/**
*
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.com/type"
targetNamespace="http://www.example.com/type" elementFormDefault="qualified" >
<xs:element name="serviceResponse" type="MyServiceResponse"/>
<xs:complexType name="MyServiceResponse">
<xs:all>
<xs:element name="Body" minOccurs="0">
<xs:complexType>
<xs:all>
<xs:element name="Car" minOccurs="0">
<xs:complexType>
<xs:all>
<xs:element name="Brand" type="xs:string" minOccurs="0"/>
<xs:element name="Color" type="xs:string" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:schema>
<type:serviceResponse xmlns:type="http://www.example.com/type">
<Body xmlns="http://www.example.com/type">
<Car>
<Brand>Mitsubishi</Brand>
<Color>Red</Color>
</Car>
</Body>
</type:serviceResponse>
<xs:element name="Body" type="Body" minOccurs="0" />
<xs:complexType name="Body">
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.com/type"
targetNamespace="http://www.example.com/type" elementFormDefault="unqualified" >
<xs:element name="serviceResponse" type="MyServiceResponse"/>
<xs:complexType name="MyServiceResponse">
<xs:all>
<xs:element name="Body" type="Body" minOccurs="0" />
</xs:all>
</xs:complexType>
<xs:complexType name="Body">
<xs:all>
<xs:element name="Car" type="Car" minOccurs="0"/>
</xs:all>
</xs:complexType>
<xs:complexType name="Car">
<xs:all>
<xs:element name="Brand" type="xs:string" minOccurs="0"/>
<xs:element name="Color" type="xs:string" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:schema>