I am using WebServices and Apache Camel and using dataFormat as POJO for requesting that webservice. I am successfully able to call the service but I want to log the request and response SOAP message which I am not able to because the SOAP message is created by CXF from the POJO class.
Is there any way in which I can log the request and response SOAP message when dataFormat is POJO?
this is the example how i am logging soap requests and response in my project, hope this helps
BindingProvider bindingProvider = ((BindingProvider) PortType);
List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
handlerChain.add(new SOAPLoggingHandler());
bindingProvider.getBinding().setHandlerChain(handlerChain);
and the class SOAPLoggingHandler
public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> {
// change this to redirect output if desired
public static Logger logger = Logger.getLogger("GetCustomerDataLand");
public Set<QName> getHeaders() {
return null;
}
public boolean handleMessage(SOAPMessageContext smc) {
logToSystemOut(smc);
return true;
}
public boolean handleFault(SOAPMessageContext smc) {
logToSystemOut(smc);
return true;
}
// nothing to clean up
public void close(MessageContext messageContext) {
}
/*
* 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
*/
private void logToSystemOut(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()) + "\nOutbound message:");
} else {
logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()) + "\nInbound message:");
}
SOAPMessage message = smc.getMessage();
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
message.writeTo(stream);
String msg = new String(stream.toByteArray(), "utf-8");
logger.info(toPrettyString(msg));
// message.writeTo(out);
logger.info(""); // just to add a newline
} catch (Exception e) {
logger.info(new SimpleDateFormat("yyyy-MM-dd HH:mm:sss").format(new Date()) + "Exception in handler: "
+ org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(e));
}
}
public String toPrettyString(String xml) {
try {
final InputSource src = new InputSource(new StringReader(xml));
final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src)
.getDocumentElement();
final Boolean keepDeclaration = Boolean.valueOf(xml.startsWith("<?xml"));
final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
final LSSerializer writer = impl.createLSSerializer();
writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
writer.getDomConfig().setParameter("xml-declaration", keepDeclaration);
return writer.writeToString(document);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Related
I am struggling to write test(s) for the following post method (junit/mockito)
POST method
public JSONObject post(final String url, final Map<String, File> fileMap) {
final OkHttpClient client = OkHttpClientSingleton.getInstance();
final MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM);
try {
for (final Map.Entry entry : fileMap.entrySet()) {
final String contentType;
final Path path = Paths.get(((File) entry.getValue()).getAbsolutePath());
contentType = Files.probeContentType(path);
final MediaType FILE_MEDIA_TYPE = MediaType.parse(contentType);
builder.addFormDataPart((String) entry.getKey(), ((File) entry.getValue()).getName(), RequestBody.create(FILE_MEDIA_TYPE, (File) entry.getValue()));
}
} catch (final IOException e) {
e.printStackTrace();
return null;
}
final RequestBody requestBody = builder.build();
final Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
return execute(client, request);
}
and the execute method looks like:
private JSONObject execute(final OkHttpClient client, final Request request) {
try {
final Response response = client.newCall(request).execute();
final String str = Objects.requireNonNull(response.body()).string();
return new JSONObject(str);
} catch (final IOException e) {
e.printStackTrace();
}
return buildErrorResponse("Unable to execute request");
}
I have no "fields" to create mocks for (my usual MO!), any tips muchappreciated. I can force an error easily enough but to test full flow at least until the POST
You can mock the web application that receives the post and verify that the correct data is send. E.g. you can use http://mock-server.com for this.
Hi I am looking into using Java (to be deployed as servlets in Websphere 8.5) to integrate with SSRS. I have looked into some of the sample codes out there and try it out.
private static SoapHeader createExecutionIdSoapHeader(String executionId) {
Document doc = DOMUtils.createDocument();
Element executionHeaderElement = doc.createElement("ExecutionHeader");
executionHeaderElement.setAttribute("xmlns", XML_NAMESPACE);
Element executionIdElement = doc.createElement("ExecutionID");
executionIdElement.setTextContent(executionId);
executionHeaderElement.appendChild(executionIdElement);
SoapHeader soapH = new SoapHeader(new QName(XML_NAMESPACE, "ExecutionHeader"), executionHeaderElement);
return soapH;
}
public static Holder<byte[]> getReportResult(String output_type, String reportFolder, String reportName, ArrayOfParameterValue arrayOfParameterValue) {
Holder<byte[]> result = null;
try {
String historyID = null;
String executionID = null;
ReportExecutionServiceSoap service = getExecutionService();
BindingProvider bp = (BindingProvider) service;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, authenticator.getUsername());
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, authenticator.getPassword());
ExecutionInfo info = new ExecutionInfo();
info = service.loadReport(REPORT_PATH, historyID);
executionID = info.getExecutionID();
List<Header> headers = new ArrayList<Header>();
SoapHeader header = createExecutionIdSoapHeader(executionID);
headers.add(header);
bp.getRequestContext().put(Header.HEADER_LIST, headers);
if (!arrayOfParameterValue.getParameterValue().isEmpty()) {
service.setExecutionParameters(arrayOfParameterValue, "en-us");
}
// Default to return HTML4.0
String deviceInfo = "";
if (output_type == null || output_type.isEmpty()) {
output_type = "HTML4.0";
}
if ("IMAGE".equalsIgnoreCase(output_type)) {
deviceInfo = RENDER_DEVICE_INFO_IMAGE;
} else {
deviceInfo = RENDER_DEVICE_INFO_HTML;
}
result = new Holder<byte[]>();
Holder<String> extension = new Holder<String>();
Holder<String> mimeType = new Holder<String>();
Holder<String> encoding = new Holder<String>();
Holder<ArrayOfWarning> warnings = new Holder<ArrayOfWarning>();
Holder<ArrayOfString> streamIDs = new Holder<ArrayOfString>();
service.render(output_type, deviceInfo, result, extension, mimeType, encoding, warnings, streamIDs);
} catch (Throwable th) {
th.printStackTrace();
}
return result;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
ArrayOfParameterValue arrayOfParameterValue = new ArrayOfParameterValue();
List<ParameterValue> parameters = arrayOfParameterValue.getParameterValue();
ParameterValue parameterValue = new ParameterValue();
parameterValue.setName(PARAMETER_NAME);
parameterValue.setValue(PARAMETER_VALUE);
parameters.add(parameterValue);
Holder<byte[]> result = GenerateReport.getReportResult(REPORT_FORMAT, REPORT_FOLDER, REPORT_NAME,
arrayOfParameterValue);
System.out.println("--------------------------------- Writing to Browser --------------------------------");
ServletOutputStream out = response.getOutputStream();
out.write(result.value);
out.flush();
out.close();
System.out.println("--------------------------------- Writing to File -----------------------------------");
DateFormat df = new SimpleDateFormat("dd_MM_yy_HH_mm_ss_");
Date date = new Date();
String filename = df.format(date) + "SSRS_Report.pdf";
FileOutputStream o = new FileOutputStream("C:\\Users\\keh\\Desktop\\Temp\\" + filename);
o.write(result.value);
o.flush();
o.close();
} catch (Exception e) {
e.printStackTrace();
}
}
When I run the codes, I have this error :
[5/17/17 19:21:02:704 SGT] 000000c4 SystemErr R javax.xml.ws.soap.SOAPFaultException: The session identifier is missing. A session identifier is required for this operation. ---> Microsoft.ReportingServices.Diagnostics.Utilities.MissingSessionIdException: The session identifier is missing. A session identifier is required for this operation.
Any expert out there can point me to a solution pls?
P.S. I have tried to use WSBindingProvider as shown in Surendra Gurjar's Blog and it ran beautifully on an Apache server, but I got a ClassCastException when I deploy it to Websphere.
I am working on web services security, trying to encrypt and sign SOAP messages between the server and the client. I used BouncyCastle, WSS4j and SOAP handlers.
To test my work at first I used the same keystore file on both the server and the client sides.I followed some tutorials on the net and it worked: the messages sent by one side were encrypted and signed and then decrypted successfully on the other side.
But now that I generated different certificates for the server and the client, and imported the client's cert into the servers jks file and vice-versa, I can't seem to figure out how to finish the task. It is still crypting and signing as if it only had a jks file without an imported cert in it. below is the code:
Crypt_handler.java
public class Crypt_handler implements SOAPHandler<SOAPMessageContext> , CallbackHandler{
public Properties prop;
public InputStream input= null;
public Crypt_handler () {
try {
prop=new Properties();
input = new FileInputStream("config.properties");
if(input==null){
System.out.println("Sorry, unable to find " );
return;}
prop.load(input);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean handleMessage(SOAPMessageContext messageContext) {
try {
// got the message from the context
SOAPMessage msg = messageContext.getMessage();
// is outgoing?
Boolean isOutGoing = (Boolean) messageContext
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (isOutGoing) {
// if it is outgoing code and sign
crypt.EncryptUtil.EncryptSOAPEnvelope(msg, prop);
crypt.EncryptUtil.SignSOAPEnvelope(msg, prop);
} else {
// if it is incooming decode and check signature.
crypt.EncryptUtil.CheckSignatureAndDecode(msg, this , prop);
}
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex.getMessage());
}
return true;
}
public boolean handleFault(SOAPMessageContext context) {
System.out.println("Server : handleFault()......");
return true;
}
public void close(MessageContext context) {
System.out.println("Server : close()......");
}
public Set<QName> getHeaders() {
Set<QName> HEADERS = new HashSet<QName>();
HEADERS.add(new QName(WSConstants.WSSE_NS, "Security"));
HEADERS.add(new QName(WSConstants.WSSE11_NS, "Security"));
HEADERS.add(new QName(WSConstants.ENC_NS, "EncryptedData"));
return HEADERS;
}
private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
try {
SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString(reason);
throw new SOAPFaultException(soapFault);
}
catch(SOAPException e) { }
}
#SuppressWarnings("deprecation")
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
String password;
for (Callback cb : callbacks) {
if (cb instanceof WSPasswordCallback) {
WSPasswordCallback pc = (WSPasswordCallback) cb;
try {
password = /*prop.getProperty("password")*/"password";
} catch (Exception e) {
throw new UnsupportedCallbackException(pc, "failure recovering the key in the properties");
}
if (pc.getIdentifer() != null) {
pc.setPassword(password);
}
}
}
}
}
EncryptUtil.java:
public class EncryptUtil{
#SuppressWarnings( { "unchecked", "deprecation" })
public
static void CheckSignatureAndDecode(SOAPMessage msg, CallbackHandler cb,Properties prop) throws WSSecurityException, TransformerConfigurationException, TransformerException, SOAPException, IOException, Exception {
WSSecurityEngine secEngine = new WSSecurityEngine();
WSSignEnvelope signer = new WSSignEnvelope();
String alias = prop.getProperty("alias");// login of jks file
String password = prop.getProperty("password");// password of jks file
signer.setUserInfo("client", password);
Crypto crypto = CryptoFactory.getInstance(prop);
Document doc = toDocument(msg);
//after we set the encrypt stuff the processsecurity does all the work
Vector v = secEngine.processSecurityHeader(doc, null, cb, crypto);
if (v == null) {
throw new Exception("Access not granted.");
}
//put the decoded message into the object
updateSOAPMessage(doc, msg);
}
/**
* Updates the message with the unencrypt form
*/
private static SOAPMessage updateSOAPMessage(Document doc, SOAPMessage message) throws SOAPException {
DOMSource domSource = new DOMSource(doc);
message.getSOAPPart().setContent(domSource);
return message;
}
/**
* Changes the SOAPMessage to a dom.Document.
*/
public static org.w3c.dom.Document toDocument(SOAPMessage soapMsg) throws SOAPException, TransformerException {
Source src = soapMsg.getSOAPPart().getContent();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
DOMResult result = new DOMResult();
transformer.transform(src, result);
return (Document) result.getNode();
}
/**
* Signs a SOAPMessage
*
* #param mensaje
* #throws Exception
*/
#SuppressWarnings("deprecation")
public
static void SignSOAPEnvelope(SOAPMessage mensaje, Properties prop) throws Exception {
// WSSignEnvelope signs a SOAP envelope according to the
// WS Specification (X509 profile) and adds the signature data
// to the envelope.
WSSignEnvelope signer = new WSSignEnvelope();
String alias = prop.getProperty("alias");// "autentiaserver";
String password = prop.getProperty("password");// "changeit";
signer.setUserInfo(alias, password);
Crypto crypto = CryptoFactory.getInstance(prop);
Document doc = toDocument(mensaje);
signer.setMustUnderstand(false);
Document signedDoc = signer.build( doc, crypto);
DOMSource domSource = new DOMSource( signedDoc);
mensaje.getSOAPPart().setContent(domSource);
}
/**
* Codes a SOAPMessage.
*/
#SuppressWarnings("deprecation")
public
static void EncryptSOAPEnvelope(SOAPMessage mensaje,Properties prop) throws Exception {
// WSSignEnvelope signs a SOAP envelope according to the
// WS Specification (X509 profile) and adds the signature data
// to the envelope.
WSEncryptBody encriptador = new WSEncryptBody();
String alias = prop.getProperty("alias");
String password = prop.getProperty("password");
encriptador.setUserInfo(alias, password);
Crypto crypto = CryptoFactory.getInstance(prop);
Document doc = toDocument(mensaje);
encriptador.setMustUnderstand(false);
Document signedDoc = encriptador.build( doc, crypto);
DOMSource domSource = new DOMSource( signedDoc);
mensaje.getSOAPPart().setContent(domSource);
}
}
And here's my config.properties file:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=password
org.apache.ws.security.crypto.merlin.keystore.alias=first
org.apache.ws.security.crypto.merlin.file=/home/user/workspace/crypt_server/keystore.jks
alias=first
password=password
Any help would be appreciated. Thanks in advance.
I have a problem with sending ArrayList from server to my client using JAX-rs. I've got 4 classes:
Demo - there is starting REST server
FileDetails - there are 3 fields storing data
ConfigFiles - it has few methods for files and there is a list of FileDetails objects
RestServer - there is method GET
I've got the following code:
#XmlRootElement(name="FileDetails")
#Path("/easy")
public class RestSerwer {
#GET
#Path("/temporary")
#Produces("text/temporary")
public String methodGet() {
ConfigFiles cf = ConfigFiles.getInstance();
List<FileDetails> files = cf.getList();
try {
JAXBContext ctx = JAXBContext.newInstance(ArrayList.class, FileDetails.class);
Marshaller m = ctx.createMarshaller();
StringWriter sw = new StringWriter();
m.marshal(files, sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return null;
}
}
At client side I've got GetRest:
public class GetRest{
HttpClient client = null;
GetMethod method = null;
private String url = null;
public GetRest(String url) {
this.url = url;
}
public String getBody(String urlDetail){
client = new HttpClient();
method = new GetMethod(url + urlDetail);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
client.executeMethod(method);
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
byte[] responseBody = null;
try {
responseBody = method.getResponseBody();
} catch (IOException e) {
e.printStackTrace();
}finally{
method.releaseConnection();
}
String str = new String(responseBody);
return str;
}
public String getFiles(){
return getBody("/easy/temporary");
}
}
When I try:
GetRest getRestClass = new GetRest("http://localhost:8185");
//List<FileDetails> cf = new ArrayList<FileDetails>();
String xxxx = getRestClass.getFiles(); // TODO
It throws:
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "java.util.ArrayList" as an element because it is missing an #XmlRootElement annotation
At server side.
Anybody can help me?
Thanks
You basically have 2 possibilities: Create you own class which is a wrapper on top of the List or write your own provider and inject it in jersey so that it knows how to marshall/unmarshall the arraylist. Here is a simple code for the first solution:
#XmlRootElement
public class MyListWrapper {
#XmlElement(name = "List")
private List<String> list;
public MyListWrapper() {/*JAXB requires it */
}
public MyListWrapper(List<String> stringList) {
list = stringList;
}
public List<String> getStringList() {
return list;
}
}
How can I add an object into the soap header of a org.springframework.ws.WebServiceMessage
This is the structure I'm looking to end up with:
<soap:Header>
<credentials xmlns="http://example.com/auth">
<username>username</username>
<password>password</password>
</credentials>
</soap:Header>
Basically, you need to use a WebServiceMessageCallback in your client to modify the message after its creation but before it is sent. To rest of the code has been described pretty accurately by #skaffman so the whole stuff might look like this:
public void marshalWithSoapActionHeader(MyObject o) {
webServiceTemplate.marshalSendAndReceive(o, new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
try {
SoapMessage soapMessage = (SoapMessage)message;
SoapHeader header = soapMessage.getSoapHeader();
StringSource headerSource = new StringSource("<credentials xmlns=\"http://example.com/auth\">\n +
<username>"+username+"</username>\n +
<password>"+password"+</password>\n +
</credentials>");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, header.getResult());
} catch (Exception e) {
// exception handling
}
}
});
}
Personally, I find that Spring-WS sucks hard for such a basic need, they should fix SWS-479.
You can do as below:
public class SoapRequestHeaderModifier implements WebServiceMessageCallback {
private final String userName = "user";
private final String passWd = "passwd";
#Override
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
if (message instanceof SaajSoapMessage) {
SaajSoapMessage soapMessage = (SaajSoapMessage) message;
MimeHeaders mimeHeader = soapMessage.getSaajMessage().getMimeHeaders();
mimeHeader.setHeader("Authorization", getB64Auth(userName, passWd));
}
}
private String getB64Auth(String login, String pass) {
String source = login + ":" + pass;
String retunVal = "Basic " + Base64.getUrlEncoder().encodeToString(source.getBytes());
return retunVal;
}
}
Then
Object response = getWebServiceTemplate().marshalSendAndReceive(request, new SoapRequestHeaderModifier());
You need to cast the WebServiceMessage to SoapMessage, which has a getSoapHeader() method you can use to modify the header. In turn, SoapHeader has various methods for adding elements, including getResult() (which can be used as the output of a Transformer.transform() operation).
I tried many options and finally below one worked for me if you have to send soap header with authentication(Provided authentication object created by wsimport) and also need to set soapaction.
public Response callWebService(String url, Object request)
{
Response res = null;
log.info("The request object is " + request.toString());
try {
res = (Response) getWebServiceTemplate().marshalSendAndReceive(url, request,new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage message) {
try {
// get the header from the SOAP message
SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
// create the header element
ObjectFactory factory = new ObjectFactory();
Authentication auth =
factory.createAuthentication();
auth.setUser("****");
auth.setPassword("******");
((SoapMessage) message).setSoapAction(
"soapAction");
JAXBElement<Authentication> headers =
factory.createAuthentication(auth);
// create a marshaller
JAXBContext context = JAXBContext.newInstance(Authentication.class);
Marshaller marshaller = context.createMarshaller();
// marshal the headers into the specified result
marshaller.marshal(headers, soapHeader.getResult());
} catch (Exception e) {
log.error("error during marshalling of the SOAP headers", e);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
You can achieve it by creating key-value map of child elements as well:
final Map<String, String> elements = new HashMap<>();
elements.put("username", "username");
elements.put("password", "password");
Set up namespace and prefix of your child element within the soap header:
final String LOCAL_NAME = "credentials";
final String PREFIX = "";
final String NAMESPACE = "http://example.com/auth";
Then, you can invoke WebServiceTemplate's method marshalSendAndReceive where you override WebServiceMessageCallback's method doWithMessage as follows:
Object response = getWebServiceTemplate().marshalSendAndReceive(request, (message) -> {
if (message instanceof SaajSoapMessage) {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) message;
SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
if (Objects.nonNull(elements)) {
try {
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader soapHeader = soapEnvelope.getHeader();
Name headerElementName = soapEnvelope.createName(
LOCAL_NAME,
PREFIX,
NAMESPACE
);
SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(headerElementName);
elements.forEach((key, value) -> {
try {
SOAPElement element = soapHeaderElement.addChildElement(key, PREFIX);
element.addTextNode(value);
} catch (SOAPException e) {
// error handling
}
});
soapMessage.saveChanges();
} catch (SOAPException e) {
// error handling
}
}
}
});
The above steps result in:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<credentials xmlns="http://example.com/auth">
<password>password</password>
<username>username</username>
</credentials>
</env:Header>
<env:Body>
<!-- your payload -->
</env:Body>
</env:Envelope>
Response response = (Response)getWebServiceTemplate() .marshalSendAndReceive(request, new HeaderModifier());
Create class HeaderModifier and override doWithMessage
public class HeaderModifier implements WebServiceMessageCallback {
private static PrintStream out = System.out;
#Override
public void doWithMessage(WebServiceMessage message) throws IOException {
SaajSoapMessage soapMessage = (SaajSoapMessage) message;
SoapEnvelope soapEnvelope = soapMessage.getEnvelope();
SoapHeader soapHeader = soapEnvelope.getHeader();
//Initialize QName for Action and To
QName action = new QName("{uri}","Action","{actionname}");
QName to = new QName("{uri}","To","{actionname}");
soapHeader.addNamespaceDeclaration("{actionname}", "{uri}");
SoapHeaderElement soapHeaderElementAction = soapHeader.addHeaderElement(action);
SoapHeaderElement soapHeaderElementTo = soapHeader.addHeaderElement(to);
soapHeaderElementAction.setText("{text inside the tags}");
soapHeaderElementTo.setText("{text inside the tags}");
soapMessage.setSoapAction("{add soap action uri}");
soapMessage.writeTo(out);
}
}