8

I have a @WebMethod call

@WebMethod
public int cancelCampaign(String campaignId, String reason);

I'd like to make the campaignId field marked as mandatory. Not sure how to do that.

I'm using a JBOSS 7.1 server.

Gaurav Sharma
  • 4,032
  • 14
  • 46
  • 72

2 Answers2

8

I had a similar requirement, and from SoapUI I noticed I was getting

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
     xmlns:bus="http://business.test.com/">
  <soapenv:Header/>
  <soapenv:Body>
     <!-- optional -->
     <bus:addItem>
        <bus:item>
           <id>?</id>
           <!-- optional -->
           <name>?</name>
        </bus:item>
        <!-- optional -->
        <itemType>?</itemType>
     </bus:addItem>
  </soapenv:Body>
</soapenv:Envelope>

instead of

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
     xmlns:bus="http://business.test.com/">
  <soapenv:Header/>
  <soapenv:Body>
     <bus:addItem>
        <bus:item>
           <id>?</id>
           <name>?</name>
        </bus:item>
        <itemType>?</itemType>
     </bus:addItem>
  </soapenv:Body>
</soapenv:Envelope>

A way out in JAX-WS Metro 2.0 RI is to annotate each parameter with

@XmlElement( required = true )

In my case, I had to do this to required WebMethod parameters and getters of all my required custom types, like so:

In the WebService:

...
 @WebMethod( operationName = "getItems" )
   @WebResult( name = "item" )
   public List<Item> getItems(
     @WebParam( name = "itemType" ) @XmlElement( required = true ) String itemType );
...

And in my POJO class:

@XmlAccessorType(XmlAccessType.FIELD)
public class Item implements Serializable
{
   private static final long serialVersionUID = 1L;

   @XmlElement( required = true )
   private int               id;

   @XmlElement( required = true )
   private String            name;

   /**
    * Default constructor.
    */
   public Item() { }

   /**
    * @return the id
    *
    */       
   public int getId()
   {
      return id;
   }

   /* setter for id */

   /**
    * @return the name
    */
   public String getName()
   {
      return name;
   }

   /* setter for name */

}
Damilola
  • 1,014
  • 2
  • 20
  • 22
4

The only way to do this with JAX-WS is to write some wrapper classes that specify the required=true flags on the XmlElement annotations. Your request element should look something like this:

@XmlType(name="YourRequestType", propOrder={"campaignId", "reason"})
public class YourRequest {
    @XmlElement(name="campaignId", required=true)
    private String campaignId;
    @XmlElement(name="reason", required=false)
    private String reason;

    //Getters and setters        

}

And your web method should look like this:

@WebMethod
public int cancelCampaign(@WebParam(name = "request") YourRequest request) {
   String campaignId = request.getCampaignId();

   return 0;
}

This will tell JAXB to generate minOccurs=1 in your XSD for campaignId element.

Paulius Matulionis
  • 23,085
  • 22
  • 103
  • 143
  • For elements that I set to required=true, JAXB removes the minOccurs property. For required=false, the minOccurs remains present and is set to 0. Does a missing minOccurs property indicate that it is a required field? – Gaurav Sharma Sep 28 '12 at 18:30
  • Another thing that I found out about required=true in @XmlElement is http://stackoverflow.com/questions/2669632/jaxb-required-true-doesnt-seem-to-require – Gaurav Sharma Oct 01 '12 at 13:36
  • This approach results in an optional YourRequest element for me (albeit one with mandatory properties / types). – Brando_Calrissian Oct 24 '16 at 14:01