What's the purpose of minOccurs, nillable and restriction?

后端 未结 5 1784
故里飘歌
故里飘歌 2021-02-02 13:44

Documentation for required says:

If required() is true, then Javabean property is mapped to an XML schema ele

相关标签:
5条回答
  • 2021-02-02 14:16

    Indeed it seems that SOAP envelopes aren't validated upon WSDL, neither on server or client.

    And I think it's best this way. Validation consumes resources and time. For most WebServices, all we need with WSDL is to provide to client the definitions to be able to talk to WebService, and not set restrictions like if a property can or not be null.

    When server and client are on same PC, Axis2 add 3-5 milisecs of overhead compared to internal calls. Unecessary validation would only increase overhead. I's better to make operations throw an exception and manually validate what's really needed.

    0 讨论(0)
  • 2021-02-02 14:27

    The purposes of required and minOccurs aren't mislead, the problem is that the schema validation is not enabled. Just enable SchemaValidation to the WebService and define the order of the XmlType's mapping as follows:

    Web Service:

    @javax.jws.WebService
    @org.jboss.ws.annotation.SchemaValidation(enabled = true)
    public class WebServiceClass {
    
        @javax.jws.WebMethod
        public WSResponseData webServiceMethod() {
            //...
        }
    }
    

    XmlType:

    @javax.xml.bind.annotation.XmlType(propOrder = {"field1", "field2", "field3"})
    public class WSData {
        //...
    
        private String field1;
    
        private Long field2;
    
        private XmlMonthType field3;
    
        //...
    }
    
    0 讨论(0)
  • 2021-02-02 14:29

    Nillable allows empty values. For example, if you have an Integer or a Date, if it's nillable, the XML tag could be empty. If it's not nillable but not required, the XML element would either have to exist with a valid content, or not exist at all; an empty tag wouldn't be valid.

    0 讨论(0)
  • 2021-02-02 14:32

    Make minOccurs 1, to make month required;

    The default value for minOccurs is one, so the month element is required. Note how minOccurs="0" had to be added to userLogin to make it optional.

    <xs:complexType name="wsData">
      <xs:sequence>
        <xs:element name="month" type="xs:string"/>
        <xs:element minOccurs="0" name="userLogin" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
    

    Validate month with its generated restriction (without a XmlAdapter).

    You can set an instance of Schema on the Unmarshaller to have the input validated:

    • http://blog.bdoughan.com/2010/12/jaxb-and-marshalunmarshal-schema.html

    Demo

    The following code can be used to generate the XML schema:

    package forum9111936;
    
    import java.io.IOException;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.SchemaOutputResolver;
    import javax.xml.transform.Result;
    import javax.xml.transform.stream.StreamResult;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(WSData.class);
            SchemaOutputResolver sor = new SchemaOutputResolver() {
    
                @Override
                public Result createOutput(String namespaceUri,
                        String suggestedFileName) throws IOException {
                    StreamResult result = new StreamResult(System.out);
                    result.setSystemId(suggestedFileName);
                    return result;
                }
    
            };
            jc.generateSchema(sor);
            System.out.println();
        }
    
    }
    

    UPDATE

    The JAXB RI normally throws a ValidationEvent of severity 1 for conversion issues. The default ValidationEventHandler ignores all issues of severity less than 2. This normally results in the value being set to null. You can override the ValidationEventHandler as follows:

        unmarshaller.setEventHandler(new ValidationEventHandler() {
            @Override
            public boolean handleEvent(ValidationEvent event) {
                System.out.println(event);
                return event.getSeverity() < ValidationEvent.ERROR;
            }
        });
    

    However the JAXB RI does not appear to throw events related to converting enum values (possible bug). If you happen to be using EclipseLink JAXB (MOXy) as your JAXB provider then you will get an exception like:

    Exception in thread "main" Local Exception Stack: 
    Exception [EclipseLink-116] (Eclipse Persistence Services - 2.4.0.qualifier): org.eclipse.persistence.exceptions.DescriptorException
    Exception Description: No conversion value provided for the value [13] in field [month/text()].
    Mapping: org.eclipse.persistence.oxm.mappings.XMLDirectMapping[month-->month/text()]
    Descriptor: XMLDescriptor(forum9111936.WSData --> [])
        at org.eclipse.persistence.exceptions.DescriptorException.noFieldValueConversionToAttributeValueProvided(DescriptorException.java:1052)
        at org.eclipse.persistence.mappings.converters.ObjectTypeConverter.convertDataValueToObjectValue(ObjectTypeConverter.java:140)
        at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getAttributeValue(XMLDirectMapping.java:287)
        at org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.endElement(XMLDirectMappingNodeValue.java:190)
        at org.eclipse.persistence.oxm.record.UnmarshalRecord.endElement(UnmarshalRecord.java:910)
        at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:133)
        at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:83)
        at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:72)
        at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:838)
        at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:626)
        at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:472)
        at forum9111936.Demo2.main(Demo2.java:30)
    

    For More Information

    • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
    0 讨论(0)
  • 2021-02-02 14:35

    I looked into the XSD structure that you have posted - and find that you have not used complex type that you have defined for the month , Insteqad of handling it on java code you can mention that all in XSD , and also the minOccur on month - element in your complex type is missing . Please use any standered XSD to java generator , it will do all the java file generation task for you

    The convention are as follow - 
    
    MinOccur = 0 --> the element can be abscent in input , and can be present
    
    MinOccur = 1 --> the element must be there in input
    (but if you use it, then your java generated member will be of list type - list of ENUM for Int )
    
    If you don't write MinOccur in attributes - then it makes the element mandatory , ( then you java generated member will be of simply ENUM for int )
    
    
    MaxOccur = 1 --> minimum one element can be there in input 
    (but if you use it, then your java generated member will be of list type - list of ENUM for Int )
    
    
    MaxOccur = unbound --> only one element can be there in input 
    (if you use it, then your java generated member will be of list type - list of ENUM for Int )
    
       <xs:complexType name="wsData">
      <xs:sequence>
        <xs:element name="month" type="xmlMonthType" minOccurs="1" nillable="false" />
        <xs:element name="userLogin" type="xs:string" minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
    
    <xs:simpleType name="xmlMonthType">
      <xs:restriction base="xs:int">
        <xs:enumeration value="1"/>
        <xs:enumeration value="2"/>
        <xs:enumeration value="3"/>
        <!-- ... months 4 ~9 ... -->
        <xs:enumeration value="10"/>
        <xs:enumeration value="11"/>
        <xs:enumeration value="12"/>
      </xs:restriction>
    </xs:simpleType>
    
    0 讨论(0)
提交回复
热议问题