I have a SOAP web service implementation on Jboss 4.2.3. I want to add a version number check for the service. Whenever a client makes a call, I will pass the client version number. I will write an interceptor at the server that would check the client version number. If it is a client with a different version number, I would not process the request.
What I want to know is if there is a way to pass the version number from the client in some context parameter other than adding it in the web service method signature?
In general, if I want to pass some custom META-DATA from client to server, how do I do it ?
In general, if I want to pass some custom META-DATA from client to
server, how do I do it ?
This can be achieved through SOAP Message Handlers both side (Client and Server ) in Jax-WS .
Client Side:
The custom-meta-data , like version number, UUID , Signature information can be added via SOAP Headers.
1..Write a VersionNumberHandler as shown below.
public class VersionNumberHandler implements SOAPHandler<SOAPMessageContext> {
private static final String LoggerName = "ClientSideLogger";
private Logger logger;
private final boolean log_p = true; // set to false to turn off
public VersionNumberHandler() {
logger = Logger.getLogger(LoggerName);
}
public boolean handleMessage(SOAPMessageContext ctx) {
if (log_p)
logger.info("handleMessage");
// Is this an outbound message, i.e., a request?
Boolean request_p = (Boolean) ctx
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// Manipulate the SOAP only if it's a request
if (request_p) {
// Get the Version Number from some property file ,
// to place in the message header.
String versionNumber = "v1.0";
try {
SOAPMessage msg = ctx.getMessage();
SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
SOAPHeader hdr = env.getHeader();
// Ensure that the SOAP message has a header.
if (hdr == null)
hdr = env.addHeader();
QName qname = new QName("http://ticket.example.com/",
"versionnumber");
SOAPHeaderElement helem = hdr.addHeaderElement(qname);
// In SOAP 1.2, setting the actor is equivalent to
// setting the role.
helem.setActor(SOAPConstants.URI_SOAP_ACTOR_NEXT);
helem.setMustUnderstand(true);
helem.addTextNode(versionNumber);
msg.saveChanges();
// For tracking, write to standard output.
msg.writeTo(System.out);
} catch (SOAPException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
}
return true; // continue down the chain
}
public boolean handleFault(SOAPMessageContext ctx) {
if (log_p)
logger.info("handleFault");
try {
ctx.getMessage().writeTo(System.out);
} catch (SOAPException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
return true;
}
public Set<QName> getHeaders() {
if (log_p)
logger.info("getHeaders");
return null;
}
public void close(MessageContext messageContext) {
if (log_p)
logger.info("close");
}
2..Mention this class in the Handler-Chain.xml.
<javaee:handler>
<javaee:handler-class>
com.example.client.handler.VersionNumberHandler
</javaee:handler-class>
</javaee:handler>
3..Add the handler-chain in the client (Stub) also.
#WebServiceClient(name = "TicketWSImplService", targetNamespace = "http://ticket.example.com/", wsdlLocation = "http://localhost:8080/ticket?wsdl")
#HandlerChain(file = "handler-chain.xml")
public class TicketWSImplService extends Service {
#WebMethod
public void method(){
}
Here, we are adding a new header element "versionnumber" and mustunderstand=true, which means the server/intermediaries has to process this element, otherwise Jax-WS-Runtime will throw SOAP Fault exception to the client. Now we need to write a Validator(SOAP Handler) at the server side to validate this version number which is being passed by the clients.
Server Side:
1..Write a VersionNumberValidator as shown below.
public class VersionNumberValidator implements SOAPHandler<SOAPMessageContext> {
#SuppressWarnings("unused")
#Override
public boolean handleMessage(SOAPMessageContext ctx) {
// Is this an inbound message, i.e., a request?
Boolean response_p = (Boolean) ctx
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// Manipulate the SOAP only if it's incoming.
if (!response_p) {
try {
SOAPMessage msg = ctx.getMessage();
SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
SOAPHeader hdr = env.getHeader();
// Ensure that the SOAP message has a header.
if (hdr == null) {
generateSOAPFault(msg, "No message header.");
return true;
}
Iterator mustUnderstandHeaders = msg.getSOAPHeader()
.examineMustUnderstandHeaderElements(
"http://schemas.xmlsoap.org/soap/actor/next");
String value = null;
while (mustUnderstandHeaders.hasNext()) {
Node next = (Node) mustUnderstandHeaders.next();
System.out.println("mustUnderstandHeaders name:"
+ next.getValue());
if (next.getNodeName().equalsIgnoreCase("versionnumber"))
value = next.getValue();
if (value != null && !value.equalsIgnoreCase("v1.0")) {
generateSOAPFault(msg, "Version Number Mismatch");
}
}
// For tracking, write to standard output.
msg.writeTo(System.out);
} catch (SOAPException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
}
return true; // continue down the chain
}
#Override
public boolean handleFault(SOAPMessageContext ctx) {
return true; // do continue down the chain
}
// For now, no-ops.
#Override
public Set<QName> getHeaders() {
Set<QName> headers = new HashSet<QName>();
QName qName = new QName("http://ticket.example.com/", "versionnumber");
headers.add(qName);
return headers;
}
#Override
public void close(MessageContext messageContext) {
}
private void generateSOAPFault(SOAPMessage msg, String reason) {
try {
SOAPBody body = msg.getSOAPBody();
SOAPFault fault = body.addFault();
QName fault_name = new QName(
SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE, "UltimateReceiver");
fault.setFaultCode(fault_name);
fault.setFaultRole("http://ticket.example.com/versionNumber_validator");
fault.addFaultReasonText(reason, Locale.US);
} catch (SOAPException e) {
}
}
2..Mention this class in the Handler-Chain-server.xml.
<javaee:handler>
<javaee:handler-class>
com.example.client.handler.VersionNumberValidator
</javaee:handler-class>
</javaee:handler>
3..Publish the webservices.
Now, the every client request will be having "version number =v1.0", At the server side , you will be validating this value is correct or not. If it is not correct, SOAPFaultException will be thrown.
You could add it to the http-headers but that would mean your client would need to do this which also means they can change it and give you wrong numbers causing issues on the server. It's only as reliable as the messages being sent in.
Either way, this isn't the right way to restrict access to your Web Service, you should use http basic authentication or if it's version differences then you should create multiple version endpoints giving clients access to the versions they need.
Also, JBoss 4.2.3 is so old it might not even work. See [1]
Mus
[1] https://community.jboss.org/message/534711
It's a bad idea to try to add out-of-band metadata to a web service. Just pick a new URL for each version if the data structures are incompatible. If they are compatible, put the version number inside the request.
This way you can still support interoperation with all different libraries and not require your clients to find a new hoop to jump through for each toolkit.
Related
I have created SOAP client in pure java. Also I have implemented SOAPHandler to trace the SOAP requests and responses. But when I see the sysouts the header part is missing in the request.
Note that I am calling an enterprise service and that requires a mandatory security header for the service to be called. I am getting proper response with my security header back in the response and also is being sysout.
What could be the issue for blank header trace from SOAPHandler ? Below is my handler code:
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
private static final Logger log = LoggerFactory.getLogger(SOAPLoggingHandler.class);
public boolean handleMessage(SOAPMessageContext context) {
log.info("handleMessage");
logToSystemOut(context);
return true;
}
public boolean handleFault(SOAPMessageContext context) {
log.info("SOAP Fault Occur");
logToSystemOut(context);
return true;
}
public void close(MessageContext context) {
log.info("close");
}
public Set<QName> getHeaders() {
log.info("getHeaders");
return null;
}
protected void logToSystemOut(SOAPMessageContext smc) {
final Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
final String message = !outboundProperty.booleanValue() ? "Web Service Response\n" : "Web Service Request\n";
logMessage(smc, message);
}
protected void logToSystemOut(SOAPMessageContext smc, String message) {
logMessage(smc, message);
}
private void logMessage(SOAPMessageContext smc, String message) {
try {
final ByteArrayOutputStream oStream = new ByteArrayOutputStream();
final Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(smc.getMessage().getSOAPPart()), new StreamResult(oStream));
oStream.close();
log.info(message + new String(oStream.toByteArray()));
} catch (final Exception e) {
log.warn("Failed to log web service message", e);
}
//some custom logging going on below - could be ignored
SomeLogger someLoggerObj = SomeLogger.getInstance();
try {
someLoggerObj.logSomeMessage(smc, message);
} catch (SOAPException e) {
log.error("SOAP Exception occurred :", e);
} catch (TransformerException e) {
log.error("TransformerException Exception occurred :", e);
}
}
}
My Header is seen as:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
I've experienced this week exactly the same issue, I have a chain of 5 SOAP calls with also TLS and SAML, and a mix of services implemented with AXIS and CXF, running aunder the same Tomcat 9 on OpenJDK 11. The issue happened only on production server (RedHat server) and I was not able to reproduce it on my development machine, the header was completely dropped by the java client and it was not possible to debug on the server.
I ended up installing on the target server a dedicated Tomcat 8.5 on JDK 1.8 to run CXF service separated from AXIS ones.
Hope this helps if someone has such a complex configuration, it's not a solution but a workaround.
Sorry for multiple edits.Should have reviewed before posting
I am using the getRequest method provided by MessageContext (org.springframework.ws.context.MessageContext) to retrieve the backend soap request in an interceptor that extends ClientInterceptor. This is beind done within handleRequest method. I am fetching this to log the request into a file. When I do this , the security section within the header which has the user id and password is also getting logged. I would like to remove this before logging. Are there any available mechanisms to remove this element or should I manipulate the String in order to take the element out?
#Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
getPayloadFromSoapMessage((SoapMessage) messageContext.getRequest());
}
protected String getPayloadFromSoapMessage(SoapMessage message) {
String payload = "Error parsing";
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
message.writeTo(bos);
payload = bos.toString();
} catch (IOException e) {
LOG.error("Error parsing the SoapMessage", e);
}
return payload;
}
Using CXF interceptor, I want to alter the response body which is being sent to the client as response. (I want to add some more nodes)
My interceptor is configured as an outgoing interceptor, is being invoked but the body is empty.
public class AlterOutBodyInterceptor extends AbstractSoapInterceptor {
private SAAJOutInterceptor saajOut = new SAAJOutInterceptor();
public AlterOutBodyInterceptor() {
super(Phase.PRE_MARSHAL);
getBefore().add(SAAJOutInterceptor.class.getName());
}
public void handleMessage(SoapMessage message) throws Fault {
SOAPMessage doc = message.getContent(SOAPMessage.class);
if (doc == null) {
saajOut.handleMessage(message);
doc = message.getContent(SOAPMessage.class);
// it is executed
}
try {
SOAPBody body = doc.getSOAPBody();
// here, body doesn't contain anything that the client gets
} catch (SOAPException e) {
e.printStackTrace();
}
}
}
I am doing trial-error with getBefore - getAfter and Phases, but without luck. Thanks in advance!
The solution is as here:
(we checked cxf sources because it contains a lot of interceptors, we got the ideas from there)
public class Interceptor extends AbstractPhaseInterceptor<Message> {
private ObjectFactory objectFactory = new ObjectFactory();
public Interceptor() {
super(Phase.PRE_LOGICAL);
addBefore(HolderOutInterceptor.class.getName());
}
#Override
public void handleMessage(Message message) {
MessageContentsList outObjects = MessageContentsList.getContentsList(message);
Assert.isTrue(outObjects.size() == 1);
Object outObject = outObjects.get(0);
// object is our soap response
}
}
This question is related to the integration of PayPal API with Java using SOAP request/response model.
The following method consist in establish the request parameters and return the response string, in this case the token. I watch several examples of how suppose to do the request call, but those methods were created for less versions (this version is "109.0", the other examples I saw were 80, 60 even 40).
Anyway, I downloaded the .wsdl file from PayPal, created the client java classes with SOAPUI and JAX-WS web services style, saved the project and opened with MyEclipse. I imported the PayPal certificate on my Java TomCat Server aswell, using keytool import on cacerts file of java.
The following method suppose to be the request method to return the String value:
public String setExpressCheckout(String returnURL, String cancelURL) throws ErrorGeneral {
PayPalAPIInterfaceService pp = new PayPalAPIInterfaceService();
UserIdPasswordType login = new UserIdPasswordType();
login.setUsername("carlos.martinez_api1.netijam.com");
login.setPassword("1389974315");
login.setSignature("AFcWxV21C7fd0v3bYYYRCpSSRl31AI-ujedgZR8zf1CorgeJpph2tssY");
String token = "";
String ackString;
// following class is generated by wsdl2java utility Service class
final PayPalAPIAAInterface expressCheckoutPort = pp.getPayPalAPIAA();
final Binding binding = ((BindingProvider) expressCheckoutPort).getBinding();
List<Handler> handlersList = new ArrayList<Handler>();
// now, adding instance of Handler to handlersList which should do our job:
// creating header instance
CustomSecurityHeaderType headerObj = new CustomSecurityHeaderType();
UserIdPasswordType credentials = new UserIdPasswordType();
credentials.setUsername("carlos.martinez_api1.netijam.com");
credentials.setPassword("1389974315");
credentials.setSignature("AFcWxV21C7fd0v3bYYYRCpSSRl31AI-ujedgZR8zf1CorgeJpph2tssY");
headerObj.setCredentials(credentials);
ObjectFactory objectFactory = new ObjectFactory();
// creating JAXBElement from headerObj
final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);
handlersList.add(new SOAPHandler<SOAPMessageContext>() {
#Override
public boolean handleMessage(final SOAPMessageContext context) {
try {
// checking whether handled message is outbound one as per Martin Strauss answer
final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(requesterCredentials, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
#Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
// ... default implementations of other methods go here
});
// as per Jean-Bernard Pellerin's comment setting handlerChain list here, after all handlers were added to list
binding.setHandlerChain(handlersList);
try {
SetExpressCheckoutReq sECR = new SetExpressCheckoutReq();
SetExpressCheckoutRequestType sECRDT = new SetExpressCheckoutRequestType();
sECRDT.setVersion("109.0");
SetExpressCheckoutRequestDetailsType details = new SetExpressCheckoutRequestDetailsType();
PaymentDetailsType paymentDetails = new PaymentDetailsType();
paymentDetails.setOrderDescription("Integrating Stuff Test Order");
paymentDetails.setInvoiceID("INVOICE-" + Math.random());
BasicAmountType orderTotal = new BasicAmountType();
orderTotal.setCurrencyID(CurrencyCodeType.EUR);
orderTotal.setValue("120.00");
paymentDetails.setOrderTotal(orderTotal);
paymentDetails.setPaymentAction(PaymentActionCodeType.SALE);
List<PaymentDetailsType> listaDetallesPago = new ArrayList<PaymentDetailsType>();
listaDetallesPago.add(paymentDetails);
details.setPaymentDetails(listaDetallesPago);
details.setReturnURL(returnURL);
details.setCancelURL(cancelURL);
sECRDT.setSetExpressCheckoutRequestDetails(details);
sECR.setSetExpressCheckoutRequest(sECRDT);
SetExpressCheckoutResponseType response = expressCheckoutPort.setExpressCheckout(sECR);
ackString = response.getAck().value();
System.out.println(ackString);
token = response.getToken();
for (ErrorType msg : response.getErrors()) {
System.out.println(msg.getLongMessage());
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
// get the token from the response
return token;
}
And this is the error that I receive:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1959)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at com.sun.xml.ws.transport.http.client.HttpClientTransport.getOutput(HttpClientTransport.java:92)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:110)
at com.sun.xml.ws.protocol.soap.ClientMUPipe.process(ClientMUPipe.java:72)
at com.sun.xml.ws.handler.HandlerPipe.process(HandlerPipe.java:134)
at com.sun.xml.ws.handler.HandlerPipe.process(HandlerPipe.java:134)
at com.sun.xml.ws.client.Stub.process(Stub.java:125)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:127)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:238)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:212)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:110)
at com.sun.proxy.$Proxy39.setExpressCheckout(Unknown Source)
at capsula.SetExpressCheckoutService.setExpressCheckout(SetExpressCheckoutService.java:168)
at capsula.SetExpressCheckoutService.main(SetExpressCheckoutService.java:56)
I tried to search on every part of the web to find a solution but I cannot. I read a lot of examples from PayPal but It doesn't tell anything about new versions, because in old version there is an easy way to make the request including the credentials on the request and not doing that shitty part of:
ObjectFactory objectFactory = new ObjectFactory();
// creating JAXBElement from headerObj
final JAXBElement<CustomSecurityHeaderType> requesterCredentials = objectFactory.createRequesterCredentials(headerObj);
handlersList.add(new SOAPHandler<SOAPMessageContext>() {
#Override
public boolean handleMessage(final SOAPMessageContext context) {
try {
// checking whether handled message is outbound one as per Martin Strauss answer
final Boolean outbound = (Boolean) context.get("javax.xml.ws.handler.message.outbound");
if (outbound != null && outbound) {
// obtaining marshaller which should marshal instance to xml
final Marshaller marshaller = JAXBContext.newInstance(CustomSecurityHeaderType.class).createMarshaller();
// adding header because otherwise it's null
final SOAPHeader soapHeader = context.getMessage().getSOAPPart().getEnvelope().addHeader();
// marshalling instance (appending) to SOAP header's xml node
marshaller.marshal(requesterCredentials, soapHeader);
}
} catch (final Exception e) {
throw new RuntimeException(e);
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
#Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
// ... default implementations of other methods go here
});
// as per Jean-Bernard Pellerin's commententer code here setting handlerChain list here, after all handlers were added to list
binding.setHandlerChain(handlersList);
Because I'm not sure if this is settle correctly.
All help will be appreciated. Thanks! =)
The problem was in my own generated classes when I tried to call the webservice, I couldnt pass the CustomSecurityHeader and was because the class APIService wasn't generated correctly. For this case, and after an investigation I figured out what happened.
At first I was using soapUI program to autogenerate the classes sending the .wsdl file that Paypal gives to developers. But, the important thing that I didnt do it’s stablishing a custom argument necessary to do a correct generated code:
-XadditionalHeaders -Xnocompile
This was extracted for an other tutorial who use “wsimport” command (for Jax-WS library generated code) and the guy who uses this command added those arguments aswell. The complete line is. I could either use a Terminal Console command like this:
wsimport -keep -XadditionalHeaders -Xnocompile -p paypal.test Desktop/PayPalSvc.wsdl/
To generate the correct classes and pass the CustomSecurityHeader.
My present code to do a correct request is:
String usuario = "carlos.martinez_api1.netijam.com";
String password = "XEDdsafXSCE4";
String firma = "A6aFJz-KhDsdf7f-668iCsdfweFplAcbDlof-vWP5wsdfsdEAy9T-d.";
//Make encapsulated object of my own class cabeceraPeticiones
CabeceraPeticiones cabeceraPeticiones = CabeceraPeticiones.getInstanceCabecera(usuario, password, firma);
//Call the method that takes the header in the format that webservice needs
Holder<CustomSecurityHeaderType> cabeceraSeguridad = cabeceraPeticiones.getCabecera();
//Set the connection params to work properly and the webservice method that I want to execute
PayPalAPIInterfaceService pp = new PayPalAPIInterfaceService();
GetExpressCheckoutDetailsReq gECR = new GetExpressCheckoutDetailsReq();
GetExpressCheckoutDetailsRequestType gECDRT = new GetExpressCheckoutDetailsRequestType();
PayPalAPIAAInterface expressCheckoutPort = pp.getPayPalAPIAA();
((BindingProvider) expressCheckoutPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://api-aa-3t.sandbox.paypal.com/2.0/");
//I take the response from the webservice operation that I execute, passing the header and the webservice request param
GetExpressCheckoutDetailsResponseType response = expressCheckoutPort.getExpressCheckoutDetails(gECR, cabeceraSeguridad);
I am writing a java axis client, how could I persist raw xml into data base, till now I have found two ways of logging raw xml, but they are for console or to a file, but I need to persist each request and response into mysql database, where I could use connection as a user parameter.
here is what I have done already.
log raw ws xml to console
log raw ws xml to a file
Well I have found a solution, First we need to use the Custom handler as I mentioned earlier(1), we can set property in the message context
like
public class FedexWsHandler extends GenericHandler {
public QName[] getHeaders() {
return null;
}
public boolean handleRequest(MessageContext context) {
try {
SOAPMessageContext smc = (SOAPMessageContext) context;
SOAPMessage reqMsg = smc.getMessage();
context.setProperty("req-msg", reqMsg);
} catch (Exception ex) {
ex.printStackTrace();
}
return true;
}
public boolean handleResponse(MessageContext context) {
try {
SOAPMessageContext smc = (SOAPMessageContext) context;
SOAPMessage reqMsg = smc.getMessage();
context.setProperty("res-msg", reqMsg);
} catch (Exception ex) {
ex.printStackTrace();
}
return true;
}
}
and then in out client we can get that property and do what ever you want to do, like
MyServiceLocator locator = new MyServiceLocator();
MyService service = locator.getMyService();
service.getResults("foo", "bar"); // call the service
// I want to get that message I have set in request and response handler methods
MessageContext ctx = locator.getCall().getMessageContext();
SOAPMessage reqMsg = (SOAPMessage) requestContext.getProperty("req-msg");
SOAPMessage resMsg = (SOAPMessage) requestContext.getProperty("res-msg");
But it is not a safe way to do that as this is not Thread Safe. as per its docs
.... so if any one can suggest me some better solution.
JAXB Marshaller : StringWriter output has a truncated tag value
Please have a look on the above post, you can convert the xml to java string and and than you can use any mysql data type which can hold your xml converted to string. you can use blob if the string in very large.