#WebResult annotation is not getting applied - java

I have written simple code for Soap web service in java.
I want to change the return element name to "myReturn" using #WebResult. but its not getting applied.
Below is the code snippet :
package com.mbfs.demo;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.ws.ResponseWrapper;
#WebService(name = "myService")
public class DemoClass {
/*#WebMethod(operationName="demo")
//#WebResult(name = "myresult", targetNamespace="http://demo.mbfs.com")
#WebResult(partName="myresult")
public String demo()
{
return "Hello World";
}
*/
#WebMethod(operationName = "")
#WebResult(name="myResult",partName="myResult")
#ResponseWrapper(localName = "getStringResponse", className =
"getStringResponse")
public String getString() {
//return "Hello World";
Demobean db = new Demobean();
db.setRet_str("Hello World");
return db.getRet_str();
}
}
I want change here
<element name="getStringResponse">
<complexType>
<sequence>
<element name="getStringReturn" type="xsd:string"/>
</sequence>
</complexType>
</element>
element name should be "myReturn".
Please help me to resolve this. By default its taking name as method name +Return.
I am using Openjdk 8 and Tomcat 7.
Let me know if it is issue with the versions.

Related

Jaxb:global binding Double Type Conversion Using XMLAdapter

I have an element defined as an xsd:double. If I try and place a value say 285 into the element and then I marshal it I get an output of 285.0... That is fine .However, if I put a value in of say 285292746, I get an output of 2.85292746E8 when I marshal.
I like something so that double output does not get converted into scientific notation with decimal? Basically I want 285292746 or 2852292746.0000000
java.lang.Double.toString() uses "computerized scientific notation" for certain values which produce isues for xml.
I know double representation of given value is fine. But the fact the value was in exponential format, The system that I am working on is accept my XML but does not know what to do with the exponential value and that causes my program not to work correctly. Changing xsd:double type in WSDL or server is not feasible for me. I am working on client side.
I came across Jaxb:binding for xsd:double type. I am still having hard time to fix the issue to send values double value in non –exponents format.
package com.logger.client
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.DatatypeConverter;
public class JaxbDoubleSerializer extends XmlAdapter<String, Double>
{
public Double unmarshal(String value) {
return ((double)javax.xml.bind.DatatypeConverter.parseDouble(value));
}
public String marshal(Double value) {
if (value == null) {
return null;
}
return (javax.xml.bind.DatatypeConverter.printDouble((double)(double)value));
}
}
I need help how to use DoubleSerializer so that I can pass values without exponents. I tried using xmlAdapter Annotation in my class MyLogClient.java. I need to know how I can solve this situation.
package com.logger.client
import javax.xml.ws.BindingProvider;
import javax.xml.bind.JAXBElement;import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
public class MyLogClient
{
//Private member fields
/** Object factory used to create user-and-role specific objects. */
private static final ObjectFactory _of = new ObjectFactory();
#XmlJavaTypeAdapter(JaxbDoubleSerializer.class)
public JAXBElement<Double> msgFileId;
#XmlJavaTypeAdapter(JaxbDoubleSerializer.class)
public Double dNumber;
public final void createEntry;
(
final String userName,
final String time,
final String logMsgStringId,
final Params logMsgParamsVal,
final Integer logMessageFieldID
)
throws JAXBException
{
JAXBElement<String> username = _of.createParamsParam(userName);
JAXBElement<String> strTime = _of.createLogRequestTime(time);
// Build the LogRequest request.
final LogRequest _LogRequest = _of.createLogRequest();
_LogRequest.setUserName(userName);
_LogRequest.setTime(strTime);
//Following is the main problem
int nMsgArgs = 285292746;
dNumber = Double.parseDouble(Integer.toString(nMsgArgs));
//After parsing double Value I get dNumber is now 2.85292746E8
//MsgFile Id is of Type JAXBElement<Double>
//CreateLogMessageIdentifier takes Double param
//So the main problem is here..the value of double field in soap request
//is being sent in exponential format. I need to send as I explained above
//285292746.
msgFileId = _of.createLogMessageIdentifier(dNumber);
JAXBElement<String> strIdVal = _of.createLogMessageFileId(logMsgStringId);
final LogMessage logMessage = _of.createLogMessage();
JAXBElement<Params> _logMsgParams =_of.createLogMessageParams(logMsgParamsVal);
//Following is where I am trying to use marshall for double type.
JAXBContext context = JAXBContext.newInstance("package com.logger.client ");
context.createMarshaller().marshal(msgFileId, System.out);
logMessage.setIdentifier(msgFileId); //Method takes JAXBElement<Double>
logMessage.setFileId(strIdVal );
logMessage.setParams(_logMsgParams);
JAXBElement<LogMessage> logMsgValue = _of.createLogRequestLogMessage(logMessage);
_LogRequest.setLogMessage(logMsgValue);
// Set the log entry
port.log(_LogRequest); //Request is sent to server.
}
WSDL xsd:type declaration is below:-
<xsd:complexType name="LogMessage">
<xsd:sequence>
<xsd:element name="fileId" type="xsd:string" minOccurs="0" nillable="true" />
<xsd:element name="identifier" type="xsd:double" minOccurs="0" nillable="true" />
<xsd:element name="params" type="tns:Params" minOccurs="0" nillable="true" />
</xsd:sequence>
</xsd:complexType>
Output for identifier field is:-
<identifier> 2.85292746E8</indentifier>
Whereas I want to send as. Because system does accept/recognize following types.
<identifier> 285292746</indentifier>
or
<identifier> 285292746.00000000</indentifier>
You could use an external bindings file like the following:
binding.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:globalBindings>
<jxb:javaType name="java.lang.Double"
xmlType="xs:double"
parseMethod="javax.xml.bind.DatatypeConverter.parseDouble"
printMethod="javax.xml.bind.DatatypeConverter.printDouble" />
</jxb:globalBindings>
</jxb:bindings>
root.xsd
<?xml version="1.0"?>
<xs:schema
elementFormDefault="qualified"
targetNamespace="http://www.example.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="root">
<xs:sequence>
<xs:element name="foo" type="xs:double" />
<xs:element name="bar" type="xs:double" />
</xs:sequence>
</xs:complexType>
</xs:schema>
XJC Call
xjc -d out -b binding.xml root.xsd
Root
The class generated for the root type will have XmlAdapter classes registered on the Double properties:
package com.example;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.w3._2001.xmlschema.Adapter1;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "root", propOrder = {
"foo",
"bar"
})
public class Root {
#XmlElement(required = true, type = String.class)
#XmlJavaTypeAdapter(Adapter1 .class)
#XmlSchemaType(name = "double")
protected Double foo;
#XmlElement(required = true, type = String.class)
#XmlJavaTypeAdapter(Adapter1 .class)
#XmlSchemaType(name = "double")
protected Double bar;
public Double getFoo() {
return foo;
}
public void setFoo(Double value) {
this.foo = value;
}
public Double getBar() {
return bar;
}
public void setBar(Double value) {
this.bar = value;
}
}
Adapter1
The XmlAdapter utilizes the methods you configured in the binding.xml file.
package org.w3._2001.xmlschema;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class Adapter1 extends XmlAdapter<String, Double> {
public Double unmarshal(String value) {
return (javax.xml.bind.DatatypeConverter.parseDouble(value));
}
public String marshal(Double value) {
if (value == null) {
return null;
}
return (javax.xml.bind.DatatypeConverter.printDouble(value));
}
}
The best way might be to use a custom binding (javaType clause) with your JAXB compiler. Documentation can be found here. Depending if you have to marshal and unmarshall doubles, the solution might be as simple as overriding the mapping to something such as a BigDecimal at the global level (with the understanding that although doubles and decimals are totally different things, you seem to want a decimal representation), or to use a datatype converter (the link above gives you examples for all these options).

Object reference not set to an instance of an object for SOAP WebService in Java

I have created one SOAP Application to connect to QuickBooks Desktop via QuickBooksWebConnector. I have given my wsdl url to WebConnector. While calling 1st callback of authentication, connector shows me this error :
QBWC1012: Authentication failed due to following error message.
Object reference not set to an instance of an object. See QWCLog for more details. Remember to turn logging on.
Which ideally means : Object reference not set to an instance of an object.
When I am trying to execute this from SOAPUI or WebServiceExplorer, it shows correct response message as given below :
Request :
<soapenv:Envelope>
<soapenv:Body>
<q0:authenticate>
<q0:strUserName>Admin</q0:strUserName>
<q0:strPassword>Admin</q0:strPassword>
</q0:authenticate>
</soapenv:Body>
</soapenv:Envelope>
Response :
<soapenv:Envelope>
<soapenv:Body>
<authenticateResponse>
<authenticateReturn xsi:type="ns1:ArrayOfString">
<ns1:string>{57F3B9B1-86F1-4fcc-B1EE-566DE1813D20}</ns1:string>
<ns1:string>none</ns1:string>
</authenticateReturn>
</authenticateResponse>
</soapenv:Body>
</soapenv:Envelope>
(Taken from WebServiceExplorer)
As I have searched for this error : It may cause when connector gets something null or invalid in response causes this error.
How to solve this kind of error.
I am new to SOAP Webservice and also new with QuickBooks.
Thanks in advance.
Worked Solution :
I added annotation in method declaration and model class definitions to solve this kind of errors.(shown below)
Annotations for Service Declaration :
#WebService(name = "QBWebConnectorSvcSoap", targetNamespace = "http://developer.intuit.com/")
#XmlSeeAlso({
ObjectFactory.class
})
public interface QBWebConnectorSvcSoap {
#WebMethod(action = "http://developer.intuit.com/authenticate")
#WebResult(name = "authenticateResult", targetNamespace = "http://developer.intuit.com/")
#RequestWrapper(localName = "authenticate", targetNamespace = "http://developer.intuit.com/", className = "com.cantero.quickbooks.ws.Authenticate")
#ResponseWrapper(localName = "authenticateResponse", targetNamespace = "http://developer.intuit.com/", className = "com.cantero.quickbooks.ws.AuthenticateResponse")
public ArrayOfString authenticate(
#WebParam(name = "strUserName", targetNamespace = "http://developer.intuit.com/")
String strUserName,
#WebParam(name = "strPassword", targetNamespace = "http://developer.intuit.com/")
String strPassword);
//same for remaining methods
}
Annotation for Model Classes :
package com.cantero.quickbooks.ws;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <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">
* <sequence>
* <element name="strUserName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="strPassword" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"strUserName",
"strPassword"
})
#XmlRootElement(name = "authenticate")
public class Authenticate {
protected String strUserName;
protected String strPassword;
public String getStrUserName() {
return strUserName;
}
public void setStrUserName(String value) {
this.strUserName = value;
}
public String getStrPassword() {
return strPassword;
}
public void setStrPassword(String value) {
this.strPassword = value;
}
}
For more detail about what to write in these annotations[targetNamespace / webAction / XmlType] you can refer this link :
https://www.connexforquickbooks.com/qbwebservice.asmx?op=authenticate

JAXB renaming attributes by itself

In my XSD I have the following attribute:
<xs:element name="id8digits" type="xs:string" minOccurs="0"/>
But when i use JAXB to generate java-classes it renames it to:
#XmlElement(name = "id8digits", namespace = "my.org.name")
protected String id8Digits; // Capital D instead of lower case d
The XSD is delivered by a third party, and I cannot change the XSD itself. I have read about bindings-files, but even if I rename the attribute to id8digits with a lower case d, JAXB renames it again to upper case D.
I have also tried to use globalbindings and set enableJavaNamingConventions="false" but that does not do the trick.
bindings.xml
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1"><jxb:bindings schemaLocation="XSD.xsd">
<jxb:globalBindings enableJavaNamingConventions="false"/>
<jxb:bindings node="//xs:element[#name='id8digits']">
<jxb:property name="id8digits"/>
</jxb:bindings>
You have problem somewhere else:-
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="Test")
#XmlAccessorType(XmlAccessType.FIELD)
public class Test {
#XmlElement(name = "id8digits", namespace = "my.org.name")
protected String id8Digits;
public String getId8Digits() {
return id8Digits;
}
public void setId8Digits(String id8Digits) {
this.id8Digits = id8Digits;
}
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Test.class);
Marshaller m = jc.createMarshaller();
Test jaxbElement = new Test();
jaxbElement.setId8Digits("Testing");
m.marshal(jaxbElement, System.out);
}
}
output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Test xmlns:ns2="my.org.name"><ns2:id8digits>Testing</ns2:id8digits></Test>

#SOAPBinding(style = Style.RPC) for web methods returning ArrayList

This was my web service code
import java.util.ArrayList;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
#WebService
#SOAPBinding(style=Style.RPC)
public class ProductCatalog {
public ArrayList<String> getProductCategories()
{
ArrayList<String> categories=new ArrayList<String>();
categories.add("books");
categories.add("movies");
categories.add("music");
return categories;
}
}
I have given `#SOAPBinding(style=Style.RPC)` annotation, but this is not showing any effect in generated wsdl..
the generated wsdl is including a schema from external location only
<types>
<xsd:schema>
<xsd:import namespace="http://symp.com/" schemaLocation="http://rajasekhar_pc:9090/NewTestMart/ProductCatalogService?xsd=1"/>
</xsd:schema>
</types>
but when i change the web method return type to String then its working fine like
#WebService
#SOAPBinding(style=Style.RPC)
public class ProductCatalog {
public String getProductCategories()
{
return "Hello World";
}
}
and the wsdl changes and its not refering to any external document
<types/>
<message name="getProductCategories"/>
<message name="getProductCategoriesResponse">
<part name="return" type="xsd:string"/>
</message>
is there any way to get rpc style for return types array list... and even document stlyle soap inded wsdl is returning ArrayList object... i want the data
/////////// updated code///////////
import java.util.ArrayList;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
#WebService
#SOAPBinding(style = Style.RPC)
public class PatientsList {
#WebMethod
public BeanList getpatientList()
{
BeanList bean=new BeanList();
ArrayList<String> patientList=new ArrayList<String>();
patientList.add("ajay");
patientList.add("vijay");
patientList.add("kumari");
bean.setPatientList(patientList);
//return bean;
return bean ;
}
}
import java.util.ArrayList;
public class BeanList {
private ArrayList<String> patientList;
public ArrayList<String> getPatientList() {
return patientList;
}
public void setPatientList(ArrayList<String> patientList) {
this.patientList = patientList;
}
}
even this gives
<types>
<xsd:schema>
<xsd:import namespace="http://symp.com/" schemaLocation="http://rajasekhar_pc:9090/NewTestMart/PatientsListService?xsd=1"/>
</xsd:schema>
</types>
but i want the wsdl to be in RPC style
Use an array instead of an ArrayList as JAXB cannot handle collections as top-level objects, only as properties of beans.
Please note that in JAX-WS RPC/encoded is not supported as a messaging mode. You can use JAX-RPC or Apache Axis V1 , if you want to send SOAP encoded messages or create RPC/encoded style WSDL.

How can I generate a XSD with an xs:element which is optional using JAXB?

My model object look something like this:
#XmlRootElement(name = "appConfig")
#XmlType(propOrder = {})
public class Config implements Serializable {
...
private int advancedFooBar;
...
#XmlElement(name = "advancedfoobar")
public int getAdvancedFooBar() {
return advancedFooBar;
}
public void setAdvancedFooBar(int advancedFooBar) {
this.advancedFooBar = advancedFooBar ;
}
When I generate a schema against this class w/JXC I end up with the following for the above property:
<xs:element name="advancedfoobar" type="xs:int"/>
I'd like this to be an optional element so I tried changing
#XmlElement(name = "advancedfoobar")
to
#XmlElement(name = "advancedfoobar", required=false)
However, that did not result any change to the generated schema. What do I need to do so that the "advancedfoobar" element will be defined as optional in the generated schema?
I am using JDK 1.7.0_U3 on Windows 7 Ultimate x64.
Thanks.
-Noah
WHAT THE JAVADOCS SAY
According to the Javadoc for #XmlElement (see: http://docs.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html#required%28%29)
If required() is false, then the Javabean property is mapped to XML
Schema element declaration with minOccurs="0". maxOccurs is "1" for a
single valued property and "unbounded" for a multivalued property.
The schema definition for advancedfoobar should be minOccurs=0 for the following mappings:
#XmlElement(name = "advancedfoobar")
public int getAdvancedFooBar() {
return advancedFooBar;
}
and
#XmlElement(name = "advancedfoobar", required=false)
public int getAdvancedFooBar() {
return advancedFooBar;
}
BUG IN MOXy AND REFERENCE IMPLEMENTATION
There appears to be a bug in both EclipseLink JAXB (MOXy) and the JAXB reference implementation regarding primitives and optional elements. I have opened the following bug against MOXy.
http://bugs.eclipse.org/395301
WORKAROUND
You can make the property of type Integer instead of int. Or better yet just set the type property on the #XmlElement annotation to be Integer. Any type capable of holding a null value will be optional by default.
Config
package forum13595629;
import java.io.Serializable;
import javax.xml.bind.annotation.*;
#XmlRootElement(name = "appConfig")
#XmlType(propOrder = {})
public class Config implements Serializable {
private int advancedFooBar;
#XmlElement(name = "advancedfoobar", type=Integer.class)
public int getAdvancedFooBar() {
return advancedFooBar;
}
public void setAdvancedFooBar(int advancedFooBar) {
this.advancedFooBar = advancedFooBar;
}
}
Demo
package forum13595629;
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(Config.class);
jc.generateSchema(new SchemaOutputResolver() {
#Override
public Result createOutput(String namespaceUri,
String suggestedFileName) throws IOException {
StreamResult result = new StreamResult(System.out);
result.setSystemId(suggestedFileName);
return result;
}
});
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="config">
<xsd:all>
<xsd:element name="advancedfoobar" type="xsd:int" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="appConfig" type="config"/>
</xsd:schema>

Resources