I use SOAPUI and generate java classes with JAX-WS import.
I have an interface like this
#WebService(name = "test", targetNamespace = "http://lang.java")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
#XmlSeeAlso({
ObjectFactory.class
})
public interface Test{
#WebMethod(action = "https://...action")
#WebResult(name = "getBean", targetNamespace = "http://...getBean", partName = "getBean")
public Bean test(
#WebParam(name = "parameter1", targetNamespace = "http://lang.java", partName = "parameter1")
String parameter1,
#WebParam(name = "parameter2", targetNamespace = "http://lang.java", partName = "parameter2")
String parameter2,
#WebParam(name = "parameter3", targetNamespace = "http://lang.java", partName = "parameter3")
String parameter3,
#WebParam(name = "parameter4", targetNamespace = "http://lang.java", partName = "parameter4")
long parameter4);
}
If I use SOAPBinding.ParameterStyle.WRAPPED the body message generated is
<S:Body>
<ns2:test xmlns:ns2="http://lang.java" xmlns:ns3="http://...getBean">
<ns2:parameter1>1</ns2:parameter1>
<ns2:parameter2>2</ns2:parameter2>
<ns2:parameter3>a</ns2:parameter3>
<ns2:parameter4>1</ns2:parameter4>
</ns2:test>
</S:Body>
If I use SOAPBinding.ParameterStyle.BARE the body message generated is
<S:Body>
<ns2:parameter1 xmlns:ns2="http://lang.java" xmlns:ns3="http://...getBean">1</ns2:parameter1>
</S:Body>
Why is the diference? Why in Bare option it only generates the first parameter? I need that Bare option create all parameters
Its ok! I find the answer here http://www.javajee.com/soap-binding-style-encoding-and-wrapping
Bare option only can use one parameter. When we use Bare, the message request must have zero or one element into Body. The solution is make an object with all parameters we want , and send this object to the method.
Related
I have implemented below soap webservice. The xml response generated doesn't contain xml declaration (<?xml version="1.0" encoding="utf-8"?>). I have tried to implement SOAPHandler, and set below property, but no luck. Please suggest what am I missing?
context.getMessage().setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
Service:
#WebService(targetNamespace = "http://charginggw.org/")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#HandlerChain(file= "/META-INF/handler.xml")
public interface LegacyService {
#WebMethod(operationName = "CheckBalance", action = "http://charginggw.org/CheckBalance")
#WebResult(name = "CheckBalanceResponse", targetNamespace = "")
CheckBalanceResponse checkBalance(#WebParam(name = "CheckBalance") CheckBalanceRequest checkBalanceRequest);
}
Tell me how to read the header in the web server's response via the #WebMethod and #WebResult annotations. Of course, I can do this by SOAPConnection and parsing SOAPMessage, but there is a lot of functionality on javax.jws and I would like to unify everything. I need value from <osb:Backend/>.
Server response:
<soapenv:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<osb:Backend xmlns:osb="http://osb.emias.mos.ru/system">СКУУ</osb:Backend>
<ipaddr xmlns="https:/bis.skyy.soapHeader/">10.0.5.147</ipaddr>
<build xmlns="https:/bis.skyy.soapHeader/">1ec22a8</build>
</env:Header>
<env:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<getEmployeePacketInfoResponse2 xmlns="http://emias.gov.ru/medempregisterservicetypes/1" xmlns:ns1="http://emias.gov.ru/types/1" xmlns:ns0="http://emias.gov.ru/servicetypes/1">
<EmployeeList>
.......
Interface declaration:
#WebResult(name = "Backend", targetNamespace = "http://emias.gov.ru/medempregisterservicetypes/1", partName = "getMedicalEmployeePacketInfo")
#WebMethod
public String getMedicalEmployeePacketInfo2(
#WebParam(partName = "getMedicalEmployeePacketInfoRequest", name = "getEmployeePacketInfoRequest", targetNamespace = "http://emias.gov.ru/medempregisterservicetypes/1")
GetEmployeePacketInfoRequest getMedicalEmployeePacketInfoRequest
) throws FaultMessage;
Request class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"requesterSystemCode",
"healthOrgID",
"employeeList"
})
#XmlRootElement(name = "getEmployeePacketInfoRequest")
public class GetEmployeePacketInfoRequest {
#XmlElement(name = "RequesterSystemCode", required = true)
protected String requesterSystemCode;
#XmlElement(name = "HealthOrgID")
protected String healthOrgID;
#XmlElement(name = "EmployeeList", required = true)
protected GetEmployeePacketInfoRequest.EmployeeList employeeList;
....
Request example:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://emias.gov.ru/medempregisterservicetypes/1">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>SPU/erz</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">emias_erz</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns:getEmployeePacketInfoRequest2>
<ns:RequesterSystemCode>SPU</ns:RequesterSystemCode>
<ns:HealthOrgID>10000430</ns:HealthOrgID>
<ns:EmployeeList>
<ns:EmployeeID>21426012</ns:EmployeeID>
</ns:EmployeeList>
</ns:getEmployeePacketInfoRequest2>
</soapenv:Body>
</soapenv:Envelope>
1. I haven't used jws, and haven't tried this, but it may help:
Try to add header option to your #WebResult annotation.
See https://docs.oracle.com/javaee/6/api/javax/jws/WebResult.html :
public abstract boolean header
"If true, the result is pulled from a message header rather then the message body."
But seems like in order to do so you have to write appropriate class for JAXB (I'm not sure).
2. Instead, I did it straightforward, and used this method:
Your business data is located inside message body - between <getEmployeePacketInfoRequest2/> tags. This is what JAXB creates your GetEmployeePacketInfoResponse class objects from. So, if you want to obtain anything outside this tags, you have to get it from the whole SOAP response. But you don't need to parse it manually - javax.xml.soap.SOAPMessage has inbuilt getSOAPHeader() method, which does what you need. Then just transform it to DOM, and do getElementsByTagName() or getElementsByTagNameNS().
implemented the second sentence
import lombok.val;
....
val soapPart = resp.getSOAPPart();
val soapEnvelope = soapPart.getEnvelope();
val soapHeader = soapEnvelope.getHeader();
val backendNode = soapHeader.getElementsByTagName("osb:Backend");
if (backendNode.getLength() > 0) {
backend = backendNode.item(0).getTextContent();
}
...
You need to use annotated parameter in your class method like this:
#WebResult(name = "Backend", targetNamespace = "http://emias.gov.ru/medempregisterservicetypes/1", partName = "getMedicalEmployeePacketInfo")
#WebMethod
public String getMedicalEmployeePacketInfo2(
#WebParam(partName = "header", name = "ipaddr", targetNamespace = "https:/bis.skyy.soapHeader/", header = true, mode = WebParam.Mode.IN)
String header,
...
#WebParam(partName = "getMedicalEmployeePacketInfoRequest", name = "getEmployeePacketInfoRequest", targetNamespace = "http://emias.gov.ru/medempregisterservicetypes/1")
GetEmployeePacketInfoRequest getMedicalEmployeePacketInfoRequest
) throws FaultMessage;
pay attention to header = true and mode = WebParam.Mode.IN
I am new to CXF. I am using CXF component in mulesoft to create Webservice. WebService is running successfully. But, I want to remove a tag from response.
I have used #ResponseWrapper, #SoapBinding(ParameterStyle=ParameterStyle.BARE). but, these are not resolved my issue.
I have heared that, we can modify soap response(i.e remove tag) by using Outintercepters. If it is can anybody help me to how to use interceptors and what phase we can modify the soap response to remove tag..
Actual Soap Response
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope">
<soap:Body>
<ns2:getMyresponse xmlns:ns2="http://myschema.com">
<return>
<errorcode>1</errorcode>
<errormsg>notsuccesful</errorms>
</return>
</ns2:getMyresponse>
</soap:Body>
</soap:Evelope>
Expected Response
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope">
<soap:Body>
<ns2:getMyresponse xmlns:ns2="http://myschema.com">
<errorcode>1</errorcode>
<errormsg>notsuccesful</errorms>
</ns2:getMyresponse>
</soap:Body>
</soap:Evelope>
SEI class is:
#WebService(targetNamespace = "urn:com.test", name = "GetActivityListInterface")
public interface GetActivityListInterface {
#SOAPBinding(parameterStyle = ParameterStyle.BARE)
#RequestWrapper(localName = "GetMyActivities", targetNamespace = "urn:com.test", className = "com.test.beans.MyActivities")
#WebMethod(operationName = "GetMyActivities", action = "urn:com.test/GetMyActivities")
#ResponseWrapper(localName = "GetMyResponse", targetNamespace = "urn:com.test", className = "com.test.beans.GetMyResponse")
public GetMyActivitiesResponse getMyActivities(
#WebParam(name = "id", partName="id")
java.lang.String id,
#WebParam(name = "date", partName="date")
java.lang.String date);
}
Use an XSL-T to remove the tags that you want to remove from response xml.
Cheers!
Remove the #ResponseWrapper and use #WebResult. Like this
#WebService(targetNamespace = "urn:com.test", name = "GetActivityListInterface")
public interface GetActivityListInterface {
#SOAPBinding(parameterStyle = ParameterStyle.BARE)
#RequestWrapper(localName = "GetMyActivities", targetNamespace = "urn:com.test", className = "com.test.beans.MyActivities")
#WebMethod(operationName = "GetMyActivities", action = "urn:com.test/GetMyActivities")
#WebResult(name = "GetMyResponse", partName="GetMyResponse", targetNamespace = "urn:com.test")
public GetMyActivitiesResponse getMyActivities(
#WebParam(name = "id", partName="id")
java.lang.String id,
#WebParam(name = "date", partName="date")
java.lang.String date);
}
I'm working on a Camel project calling services with CXF.
The services are defined through a wsdl and which I cannot modify it.
I generated classes with wsdl2java: I will have many other remote services, they may change often, so I want to have the POJOs and interfaces to be generated as much as possible.
My generated interface looks like this:
#WebService(targetNamespace = "http://service.company.fr", name = "myService")
#XmlSeeAlso({ObjectFactory.class})
public interface MyService {
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendLetter(
#WebParam(partName = "parameters", name = "sendLetter", targetNamespace = "http://service.company.fr")
SendLetter parameters
) throws MessageServiceException_Exception;
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendWebNotification(
#WebParam(partName = "parameters", name = "sendWebNotification", targetNamespace = "http://service.company.fr")
SendWebNotification parameters
) throws MessageServiceException_Exception;
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#WebResult(name = "sendMessageResponse", targetNamespace = "http://service.company.fr", partName = "parameters")
#WebMethod
SendMessageResponse sendEmail(
#WebParam(partName = "parameters", name = "sendEmail", targetNamespace = "http://service.company.fr")
SendEmail parameters
) throws MessageServiceException_Exception;
}
I defined the CXF Endpoint in an XML file, like this :
<cxf:cxfEndpoint id="serviceEndpoint"
address="http://localhost:9081/soap/service"
serviceClass="fr.company.service.MyService">
<cxf:properties>
<entry key="dataFormat" value="POJO"/>
</cxf:properties>
</cxf:cxfEndpoint>
And finally, I am calling the service in a Camel route :
from(URI_SERVICE)
.process(sendEmailBodyProcessor)
.to("cxf:bean:serviceEndpoint");
The sendEmailBodyProcessor sets the body with a SendEmail object (corresponding to the 3rd service from the interface). If I leave only the service I use in the interface, it works, but if I leave the other services, I get this error:
java.lang.IllegalArgumentException: Part {http://service.company.fr}parameters should be of type fr.company.service.SendLetter, not fr.company.service.SendEmail
at org.apache.cxf.jaxb.io.DataWriterImpl.checkPart(DataWriterImpl.java:292)
at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:220)
at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:117)
at org.apache.cxf.wsdl.interceptors.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
...
I tried using headers like operationName or method etc. but I can't get it to work...
Has anyone a clue on how I can get it to work?
Thanks a lot!
I finally found how to solve my problem!...
In my case, operationName was not enough, I needed to add operationNamespace = "http://service.company.fr" as well!
I have a web service like below, it contains a web method which will return a list of objects:
#WebService(name = "ClubMembershipPortType", serviceName = "ClubMembershipService", portName = "ClubMembershipSoapPort", targetNamespace = "http://club.com/api/ws")
public class ClubMembershipWS {
#WebMethod(operationName = "findClubMembershipsByClubId", action = "urn:findClubMembershipsByClubId")
#WebResult(name = "club_membership")
public List<ClubMembership> findClubMembershipsByClubId(#XmlElement(required=true)
#WebParam(name = "club_id") String clubId,
#WebParam(name = "status") StatusEnum status)
...
...
}
}
The response I got for the api request is like below:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:findClubMembersByClubIdResponse xmlns:ns2="http://club.com/api/ws">
<club_membership>
...
</club_membership>
<club_membership>
...
</club_membership>
</ns2:findClubMembersByClubIdResponse>
</S:Body>
</S:Envelope>
The question is how to use #XmlElementWrapper (or other way?) to make the response like below?
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:findClubMembersByClubIdResponse xmlns:ns2="http://club.com/api/ws">
<club_membership_list>
<club_membership>
...
</club_membership>
<club_membership>
...
</club_membership>
</club_membership_list>
</ns2:findClubMembersByClubIdResponse>
</S:Body>
</S:Envelope>
Did you try this?
#XmlElementWrapper(name="club_membership_list", required=true)
#XmlElement(name="club_membership", required=true)
public List<ClubMembership> findClubMembershipsByClubId(#WebParam(name = "club_id") String clubId,
#WebParam(name = "status") StatusEnum status)
Annotate your method with:
#WebResult(name="club_membership_list", targetNamespace = "http://club.com/api/ws")