Changing JAX-WS default XML namespace prefix - java

I've generated source codes for an old Web Service using JAX-WS 2.1.7. When I call this service the generated soap message is something like this:
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header>
</env:Header>
<env:Body>
...
</env:Body>
</env:Envelope>
But the old web service only accepts this format:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
...
</soap:Body>
</soap:Envelope>
As you see the prefix is "soap" instead "env" and there is no header so i got an error complaining about "soap:Body" is required. I can't change the old web service and need to send compatible soap messages. how can i change the prefix to "soap" and also remove "Header"?

You need to create a class that implements SOAPHandler<SOAPMessageContext> and that includes something like this:
public boolean handleMessage(final SOAPMessageContext context)
{
final Boolean isSoapResponse = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!isSoapResponse)
{
try
{
final SOAPMessage soapMsg = context.getMessage();
soapMsg.getSOAPPart().getEnvelope().setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:soap", "http://schemas.xmlsoap.org/soap/envelope/");
soapMsg.getSOAPPart().getEnvelope().removeAttributeNS("http://schemas.xmlsoap.org/soap/envelope/", "env");
soapMsg.getSOAPPart().getEnvelope().removeAttribute("xmlns:env");
soapMsg.getSOAPPart().getEnvelope().setPrefix("soap");
soapMsg.getSOAPBody().setPrefix("soap");
soapMsg.getSOAPPart().getEnvelope().getHeader().detachNode();
}
catch (SOAPException e)
{
e.printStackTrace();
}
}
return true;
}
Then create a handler.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>test.MySoapHandler</handler-name>
<handler-class>test.MySoapHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
And add an annotation to your web service:
#HandlerChain(file = "handler.xml")

Related

JAX-WS fault: throw superclass of exception

I want to throw subclasses of MyCustomException but for the superclass to be transferred across the web service; however, the subclass is transferred, instead. I have tried adding the annotation WebFault to the classes with no effect. I have provided an example of what is currently happening and an example of what I want to happen instead.
The exceptions.
public class MyCustomException extends Exception {
String text;
public static class CustomInner extends MyCustomException {
public CustomInner1() {
super("inner");
}
}
public MyCustomException(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
The web service implementation. NB: I don't want to change what is being thrown here.
#Stateless(name = "MyService", mappedName = "MyService")
#LocalBean
#WebService(targetNamespace = "http://my.org/ns/")
public class MyService {
#WebMethod
public String throwCustomInnerException() throws MyCustomException {
throw new MyCustomException.CustomInner();
}
#WebMethod
public String throwCustomException() throws MyCustomException {
throw new MyCustomException("text");
}
}
The XML for throwCustomException() call using the web service.
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>pack.MyCustomException</faultstring>
<detail>
<ns2:MyCustomException xmlns:ns2="http://my.org/ns/">
<text>text</text>
</ns2:MyCustomException>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>
The XML for throwCustomInnerException() call using the web service.
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>pack.CustomInner</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
What I want to happen is the following, when throwCustomInnerException() is called using the web service:
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>pack.MyCustomException</faultstring>
<detail>
<ns2:MyCustomException xmlns:ns2="http://my.org/ns/">
<text>inner1</text>
</ns2:MyCustomException>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>
You can change the method:
#WebMethod
public String throwCustomInnerException() throws MyCustomException {
throw new MyCustomException.CustomInner();
}
to:
#WebMethod
public String throwCustomInnerException() throws MyCustomException {
throw new MyCustomException(CustomInner.getClass().getSimpleName());
}

How to handle multiple SOAP requests in the same envelope using Java Web Service?

I currently have a web service with the method:
#Override
#WebResult(Name="OIPResponse")
public Map<String, Object> getOIP(#WebParam(name = "invoice") String invoiceNumber,#WebParam(name = "part") String partNumber)
The normal SOAP request I use to call it looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:oip="http://oip.mycompany.com/">
<soapenv:Header/>
<soapenv:Body>
<oip:getOIP>
<invoice>41587182</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
</soapenv:Body>
</soapenv:Envelope>
and the response is something like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getOIPResponse xmlns:ns2="http://oip.mycompany.com/">
<OIPResponse>
<entry>
<key>ERR_CODE</key>
</entry>
<entry>
<key>SELLING_OU</key>
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">null</value>
</entry>
...
</OIPResponse>
</ns2:getOIPResponse>
</soap:Body>
</soap:Envelope>
I've tested this and it works fine. Now I am wondering if there is a way to include multiple requests in the same SOAP envelope like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:oip="http://oip.mycompany.com/">
<soapenv:Header/>
<soapenv:Body>
<oip:getOIP>
<invoice>41587182</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587183</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587184</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
<oip:getOIP>
<invoice>41587185</invoice>
<part>9ZF2A5-570</part>
</oip:getOIP>
</soapenv:Body>
</soapenv:Envelope>
and get back something like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getOIPResponse xmlns:ns2="http://oip.mycompany.com/">
<OIPResponse>
...
</OIPResponse>
<OIPResponse>
...
</OIPResponse>
<OIPResponse>
...
</OIPResponse>
...
</ns2:getOIPResponse>
</soap:Body>
</soap:Envelope>
Is there any way to do this?
I ended up creating a POJO called OIPRequest that contained the two parameters I need (invoice and part number) and a new method getOIPMultiple which takes an array of OIPRequests as an input parameter.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class OIPRequest {
public String invoiceNumber, partNumber;
public OIPRequest(String invoice, String part) {
invoiceNumber = invoice;
partNumber = part;
}
public OIPRequest() {
invoiceNumber = "";
partNumber = "";
}
}
This makes the request look like this:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<getMultipleOIP xmlns="http://oip.mycompany.com/">
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
<OIPRequest xmlns="">
<invoiceNumber>41587182</invoiceNumber>
<partNumber>9ZF2A5-570</partNumber>
</OIPRequest>
</getMultipleOIP>
</Body>
</Envelope>

How to remove namespace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

I have this on my request soapenv:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
I want to remove xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Can I do that from my Service_BindingStub?
Maybe can set org.apache.axis.client.Call object with some property... I don't know.
If your issue to have xsi namespace in the root so extend SoapSerializationEnvelope and then override method: write like:
#Override
public void write(XmlSerializer writer) throws IOException {
// writer.setPrefix("i", this.xsi);
writer.setPrefix("d", this.xsd);
writer.setPrefix("c", this.enc);
writer.setPrefix("v", this.env);
writer.startTag(this.env, "Envelope");
writer.startTag(this.env, "Header");
this.writeHeader(writer);
writer.endTag(this.env, "Header");
writer.startTag(this.env, "Body");
this.writeBody(writer);
writer.endTag(this.env, "Body");
writer.endTag(this.env, "Envelope");
}

java paypal merchant sdk recurring payment invalid token

Hi I'm trying to create a Paypal Recurring Pyament using the JAVA Merhant SDK but I keep having "invalid token" when trying to call "createRecurringPaymentsProfile" method.
Here are the Request and Response
For SetExpressCheckout Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:ebay:api:PayPalAPI"
xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:cc="urn:ebay:apis:CoreComponentTypes"
xmlns:ed="urn:ebay:apis:EnhancedDataTypes">
<soapenv:Header>
<ns:RequesterCredentials>
<ebl:Credentials>
<ebl:Username>XXX</ebl:Username>
<ebl:Password>XXX</ebl:Password>
<ebl:Signature>XXX</ebl:Signature>
</ebl:Credentials>
</ns:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<ns:SetExpressCheckoutReq>
<ns:SetExpressCheckoutRequest>
<ebl:Version>109.0</ebl:Version>
<ebl:SetExpressCheckoutRequestDetails>
<ebl:ReturnURL>http://127.0.0.1:8888/ReturnURL</ebl:ReturnURL>
<ebl:CancelURL>http://127.0.0.1:8888/CancelURL</ebl:CancelURL>
<ebl:BillingAgreementDetails>
<ebl:BillingType>RecurringPayments</ebl:BillingType>
<ebl:BillingAgreementDescription>Buyer is billed at "USD1.00" per month
</ebl:BillingAgreementDescription>
</ebl:BillingAgreementDetails>
<ebl:PaymentDetails>
<ebl:OrderTotal currencyID="USD">1.00</ebl:OrderTotal>
<ebl:ItemTotal currencyID="USD">1</ebl:ItemTotal>
<ebl:ButtonSource>PayPal_SDK</ebl:ButtonSource>
<ebl:NotifyURL>/NotifyURL</ebl:NotifyURL>
<ebl:PaymentAction>Sale</ebl:PaymentAction>
</ebl:PaymentDetails>
</ebl:SetExpressCheckoutRequestDetails>
</ns:SetExpressCheckoutRequest>
</ns:SetExpressCheckoutReq>
</soapenv:Body>
This the response
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes"
xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI">
<SOAP-ENV:Header>
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"></Security>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType">
<Username xsi:type="xs:string"></Username>
<Password xsi:type="xs:string"></Password>
<Signature xsi:type="xs:string"></Signature>
<Subject xsi:type="xs:string"></Subject>
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body id="_0">
<SetExpressCheckoutResponse xmlns="urn:ebay:api:PayPalAPI">
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2014-04-05T22:23:40Z</Timestamp>
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Success</Ack>
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">6c19207a14fd</CorrelationID>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">109.0</Version>
<Build xmlns="urn:ebay:apis:eBLBaseComponents">10463669</Build>
<Token xsi:type="ebl:ExpressCheckoutTokenType">EC-1X212344K9178491M</Token>
</SetExpressCheckoutResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
In CreateRecurringPaymentsProfile Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:ebay:api:PayPalAPI"
xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:cc="urn:ebay:apis:CoreComponentTypes"
xmlns:ed="urn:ebay:apis:EnhancedDataTypes">
<soapenv:Header>
<ns:RequesterCredentials>
<ebl:Credentials>
<ebl:Username>XXX</ebl:Username>
<ebl:Password>XXX</ebl:Password>
<ebl:Signature>XXX</ebl:Signature>
</ebl:Credentials>
</ns:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<ns:CreateRecurringPaymentsProfileReq>
<ns:CreateRecurringPaymentsProfileRequest>
<ebl:Version>109.0</ebl:Version>
<ebl:CreateRecurringPaymentsProfileRequestDetails>
<ebl:Token>EC-1X212344K9178491M</ebl:Token>
<ebl:RecurringPaymentsProfileDetails>
<ebl:BillingStartDate>2014-04-06T13:21:36Z</ebl:BillingStartDate>
</ebl:RecurringPaymentsProfileDetails>
<ebl:ScheduleDetails>
<ebl:Description>Buyer is billed at "USD1.00" per month</ebl:Description>
<ebl:PaymentPeriod>
<ebl:BillingPeriod>Month</ebl:BillingPeriod>
<ebl:BillingFrequency>12</ebl:BillingFrequency>
<ebl:Amount currencyID="USD">1.00</ebl:Amount>
</ebl:PaymentPeriod>
</ebl:ScheduleDetails>
</ebl:CreateRecurringPaymentsProfileRequestDetails>
</ns:CreateRecurringPaymentsProfileRequest>
</ns:CreateRecurringPaymentsProfileReq>
</soapenv:Body>
</soapenv:Envelope>
The response was an "invalid token"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="urn:ebay:apis:CoreComponentTypes"
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:ed="urn:ebay:apis:EnhancedDataTypes"
xmlns:ebl="urn:ebay:apis:eBLBaseComponents" xmlns:ns="urn:ebay:api:PayPalAPI">
<SOAP-ENV:Header>
<Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext" xsi:type="wsse:SecurityType"></Security>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType">
<Username xsi:type="xs:string"></Username>
<Password xsi:type="xs:string"></Password>
<Signature xsi:type="xs:string"></Signature>
<Subject xsi:type="xs:string"></Subject>
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>
<SOAP-ENV:Body id="_0">
<CreateRecurringPaymentsProfileResponse xmlns="urn:ebay:api:PayPalAPI">
<Timestamp xmlns="urn:ebay:apis:eBLBaseComponents">2014-04-05T22:28:11Z</Timestamp>
<Ack xmlns="urn:ebay:apis:eBLBaseComponents">Failure</Ack>
<CorrelationID xmlns="urn:ebay:apis:eBLBaseComponents">50e773299b36f</CorrelationID>
<Errors xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:ErrorType">
<ShortMessage xsi:type="xs:string">Invalid Token</ShortMessage>
<LongMessage xsi:type="xs:string">The token is invalid</LongMessage>
<ErrorCode xsi:type="xs:token">11502</ErrorCode>
<SeverityCode xmlns="urn:ebay:apis:eBLBaseComponents">Error</SeverityCode>
</Errors>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">109.0</Version>
<Build xmlns="urn:ebay:apis:eBLBaseComponents">10433064</Build>
<CreateRecurringPaymentsProfileResponseDetails xmlns="urn:ebay:apis:eBLBaseComponents"
xsi:type="ebl:CreateRecurringPaymentsProfileResponseDetailsType">
<ProfileID xsi:type="xs:string"></ProfileID>
<TransactionID xsi:type="xs:string"></TransactionID>
</CreateRecurringPaymentsProfileResponseDetails>
</CreateRecurringPaymentsProfileResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm sure that the CreateRecurringPaymentsProfile Request token is the response token from SetExpressCheckout.
To answer my question.
OrderTotal should be seto to "0" and ItemTotal should be removed in SetExpressCheckout Request.
But the "invalid token error" is not very helpful error message.
After you SetExpressCheckOutResponse include the following code,
Map<String, String> sdkConfig = new HashMap<String, String>();
sdkConfig.put("mode", "sandbox");
sdkConfig.put("mode", "sandbox");
sdkConfig.put("acct1.UserName", apiUsername);
sdkConfig.put("acct1.Password", apiPassword);
sdkConfig.put("acct1.Signature", apiSignature);
SimpleDateFormat formatterR = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:sssz");
CreateRecurringPaymentsProfileReq createRecurringPaymentsProfileReq = new CreateRecurringPaymentsProfileReq();
CreateRecurringPaymentsProfileRequestType createRecurringPaymentsProfileRequest = new CreateRecurringPaymentsProfileRequestType();
RecurringPaymentsProfileDetailsType recurringPaymentsProfileDetails = new RecurringPaymentsProfileDetailsType();
recurringPaymentsProfileDetails.setBillingStartDate(formatterR.format(new Date()));
recurringPaymentsProfileDetails.setSubscriberName("YOUR SUBSCRIBER NAME");
BasicAmountType billingAmount = new BasicAmountType(CurrencyCodeType.USD, "1.00");
//I Take as MONTHLY Recurrence
//So that i set periodType as MONTH, frequency as 1 (for every month) and billing amount here i sent as 1 USD
BillingPeriodDetailsType paymentPeriod = new BillingPeriodDetailsType(BillingPeriodType.MONTH, Integer.parseInt("1"), billingAmount);
ScheduleDetailsType scheduleDetails = new ScheduleDetailsType("Description about payment", paymentPeriod); //description, paymentPeriod object
CreateRecurringPaymentsProfileRequestDetailsType createRecurringPaymentsProfileRequestDetails = new CreateRecurringPaymentsProfileRequestDetailsType(recurringPaymentsProfileDetails, scheduleDetails);
AddressType addressType = new AddressType();
addressType.setStateOrProvince("STATE");
addressType.setCityName("CITY");
addressType.setCountryName("COUNTRY");
PersonNameType personName = new PersonNameType();
personName.setFirstName("SUBSCRIBER FIRST NAME");
personName.setLastName("SUBSCRIBER LAST NAME");
PayerInfoType payerInfoType = new PayerInfoType();
payerInfoType.setAddress(addressType);
payerInfoType.setPayerName(personName);
CreditCardDetailsType creditCard = new CreditCardDetailsType();
//creditCard.setCreditCardType(CreditCardTypeType.VISA);
// Credit Card Number
creditCard.setCreditCardNumber("CARD NO");//4442662639546634
// Credit Card Expiration Month
creditCard.setExpMonth(12);//Integer.parseInt("12")
// Credit Card Expiration Year
creditCard.setExpYear(Integer.parseInt(2016);//Integer.parseInt("2016")
creditCard.setCVV2("CVV CODE");
creditCard.setCardOwner(payerInfoType);
createRecurringPaymentsProfileRequestDetails.setCreditCard(creditCard);
createRecurringPaymentsProfileRequest
.setCreateRecurringPaymentsProfileRequestDetails(createRecurringPaymentsProfileRequestDetails);
createRecurringPaymentsProfileReq
.setCreateRecurringPaymentsProfileRequest(createRecurringPaymentsProfileRequest);
PayPalAPIInterfaceServiceService service = null;
try {
service = new PayPalAPIInterfaceServiceService(sdkConfig);
} catch (Exception e) {
LOGGER.info("Error Message : " + e.getMessage());
}
CreateRecurringPaymentsProfileResponseType createRecurringPaymentsProfileResponse = null;
try {
// ## Making API call
// Invoke the appropriate method corresponding to API in service
// wrapper object
createRecurringPaymentsProfileResponse = service
.createRecurringPaymentsProfile(createRecurringPaymentsProfileReq);
} catch (Exception e) {
LOGGER.info("Error Message : " + e.getMessage());
}
String ProfileID = "";
// ## Accessing response parameters
// You can access the response parameters using getter methods in
// response object as shown below
// ### Success values
if (createRecurringPaymentsProfileResponse.getAck().getValue()
.equalsIgnoreCase("success")) {
// A unique identifier for future reference to the details of
// this recurring payment.
ProfileID = createRecurringPaymentsProfileResponse
.getCreateRecurringPaymentsProfileResponseDetails()
.getProfileID();
LOGGER.info("Profile ID:"+ProfileID);
//mes = "approved";
}
// ### Error Values
// Access error values from error list using getter methods
else {
List<ErrorType> errorList = createRecurringPaymentsProfileResponse
.getErrors();
LOGGER.info("API Error Message : "
+ errorList.get(0).getLongMessage());
//mes = "error";
}
I hope this will helps you...

WebService with Apache CXF and custom headers

I created a web service using Apache cfx and spring, it works, but I need that the response include this header
<?xml version="1.0" encoding="UTF-8"?>
Right now the response is like this.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:postEncuestaResponse xmlns:ns2="http://webservice.atomsfat.com/">
<respuestaEncuesta>
<dn>12315643154</dn>
<encuestaPosted>true</encuestaPosted>
<fecha>2009-09-30T16:32:33.163-05:00</fecha>
</respuestaEncuesta>
</ns2:postEncuestaResponse>
</soap:Body>
</soap:Envelope>
But should be like this
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:postEncuestaResponse xmlns:ns2="http://webservice.atomsfat.com/">
<respuestaEncuesta>
<dn>12315643154</dn>
<encuestaPosted>true</encuestaPosted>
<fecha>2009-09-30T16:32:33.163-05:00</fecha>
</respuestaEncuesta>
</ns2:postEncuestaResponse>
</soap:Body>
</soap:Envelope>
This is the configuration of the beans of spring that expose the service.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint
id="encuestas"
implementor="webservice.serviceImpl"
address="/Encuestas" >
</jaxws:endpoint>
</beans>
this is the interface
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
#WebService
public interface Encuestas {
#WebResult(name= "respuestaEncuesta")
RespuestaEncuestaMsg postEncuesta (#WebParam(name = "encuestaMsg") EncuestaMsg message);
}
Any ideas ?
Or use CXF build-in configuration capabilities.
Just add this IN your CXF Spring config :
<jaxws:properties>
<entry key="org.apache.cxf.stax.force-start-document">
<bean class="java.lang.Boolean">
<constructor-arg value="true"/>
</bean>
</entry>
</jaxws:properties>
Check the following
How can I add soap headers to the request/response?
Adding JAX-WS handlers to web services
Converting JAX-WS handlers to Apache CXF interceptors
then decide for one of the options and implement a handler/interceptor which adds what you need.
Well I implement a Handler, first I downloaded the examples from CXF and modified the logging Handler, and it works.
The configuration of spring :
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint
id="encuestas"
implementor="com.webservice.EncuestasImpl"
address="/Encuestas">
<jaxws:handlers>
<bean class="com.webservice.HeaderHandler"/>
</jaxws:handlers>
</jaxws:endpoint>
And the code this is the code for the handler.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.webservice;
import java.io.PrintStream;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
/*
* This simple logical Handler will output the payload of incoming
* and outgoing messages.
*/
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
private PrintStream out;
public HeaderHandler() {
setLogStream(System.out);
}
protected final void setLogStream(PrintStream ps) {
out = ps;
}
public void init(Map c) {
System.out.println("LoggingHandler : init() Called....");
}
public Set<QName> getHeaders() {
return null;
}
public boolean handleMessage(SOAPMessageContext smc) {
System.out.println("LoggingHandler : handleMessage Called....");
logToSystemOut(smc);
return true;
}
public boolean handleFault(SOAPMessageContext smc) {
System.out.println("LoggingHandler : handleFault Called....");
logToSystemOut(smc);
return true;
}
// nothing to clean up
public void close(MessageContext messageContext) {
System.out.println("LoggingHandler : close() Called....");
}
// nothing to clean up
public void destroy() {
System.out.println("LoggingHandler : destroy() Called....");
}
/*
* Check the MESSAGE_OUTBOUND_PROPERTY in the context
* to see if this is an outgoing or incoming message.
* Write a brief message to the print stream and
* output the message. The writeTo() method can throw
* SOAPException or IOException
*/
protected void logToSystemOut(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean)
smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
out.println("\nOutbound message:");
} else {
out.println("\nInbound message:");
}
SOAPMessage message = smc.getMessage();
try {
message.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
message.writeTo(out);
out.println();
} catch (Exception e) {
out.println("Exception in handler: " + e);
}
}
}
Note: that in the try I use MessageContext.MESSAGE_OUTBOUND_PROPERTY like Justin suggested.
Folowing the links provided by jitter, I went to http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest%252Fresponse%253F and found the following solution:
// My object of the custom header
AuthenticationHeader aut = new AuthenticationHeader();
aut.setUserName("ws");
aut.setPassword("ws123");
IntegrationWS integration = new IntegrationWS();
List<Header> headers = new ArrayList<Header>();
Header dummyHeader;
try {
dummyHeader = new Header(new QName("http://www.company.com/ws/", "AuthenticationHeader"), auth, new JAXBDataBinding(AuthenticationHeader.class));
} catch (JAXBException e) {
throw new IllegalStateException(e);
}
headers.add(dummyHeader);
IntegrationWSSoap soapPort = integration.getIntegrationWSSoap12();
//client side:
((BindingProvider)soapPort).getRequestContext().put(Header.HEADER_LIST, headers);
ArrayOfBrand arrayBrand = soapPort.syncBrands();
I don't have Apache CXF specific knowledge, but the jax-ws way to add the xml declaration seems to be to make a handler and use SOAPMessage.setProperty() to turn that feature on:
message.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
You should be able to add a jax-ws handler to your endpoint by adding a jaxws:handlers element in that spring config.

Categories

Resources