How to convert SOAP request and response in XML format? - web-services

I've set up a SOAP WebServiceProvider in JAX-WS, but I'm having trouble figuring out how to get request and response in XML format from a SOAP request and response. Here's a sample of the code I've got right now, and where I'm trying to grab the XML:
package com.ewb.socialbanking.creditcardMain;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.client.core.SoapActionCallback;
import com.ewb.socialbanking.creditcardws.GetCcNumber;
import com.ewb.socialbanking.creditcardws.GetCcNumberResponse;
import com.safenet.wsdl.LoginUser;
/*THIS IS HOW I AM GIVING THE REQUEST :
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(CreditCardConfig.class);
ctx.refresh();
CreditCardClient cCClient = ctx.getBean(CreditCardClient.class);
GetCcNumber cCNumber = new GetCcNumber();
ObjectFactory enrollObjFactory = new ObjectFactory();
cCNumber.setT24Cif(enrollObjFactory.createString("abc"));
cCNumber.setLinkId(enrollObjFactory.createString("def"));
cCNumber.setCcCif(enrollObjFactory.createString("ghi"));
cCNumber.setMsgRefNo(enrollObjFactory.createString("jkl"));
GetCcNumberResponse valueForRes = cCClient.getCreditCardDetails(cCNumber);*/
public class CreditCardClient extends WebServiceGatewaySupport {
public GetCcNumberResponse getCreditCardDetails(GetCcNumber request) {
//I want here request in xml format??
System.out.println("req : "+request);
//Right now it is coming as :
//req : com.ewb.socialbanking.creditcardws.GetCcNumber#5d534f5d
GetCcNumberResponse response = null;
try {
response = (GetCcNumberResponse) getWebServiceTemplate()
.marshalSendAndReceive(
request,
new SoapActionCallback(
"http://F9M9MV1RENTAL:8088/mocksoap/GetCcNumber"));
} catch (Exception e) {
e.printStackTrace();
}
//I want here response in xml format??
System.out.println("res : "+response);
//Right now it is coming as :
//res : com.ewb.socialbanking.creditcardws.GetCcNumberResponse#514646ef
return response;
}
}

JAX-WS services return JAXB objects. If you want to marshall that object to an outputstream, you simply use the JAXB API.
Marshaller m = JAXBContext.newInstance(GetCcNumberResponse.class).createMarshaller();
m.marshal(response, System.out);

I've tried by my self, and it works. If you want to get the SOAP message, a good way to do it is using a handler at server side. The following is my handler.
package com.documentType.handler;
import java.io.IOException;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class TestHandler implements SOAPHandler<SOAPMessageContext> {
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean handleFault(SOAPMessageContext arg0) {
// TODO Auto-generated method stub
return false;
}
// this method will be called twice (in and out)
#Override
public boolean handleMessage(SOAPMessageContext context) {
// true if the msg is going out
Boolean outBoundMsg = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
try {
if (outBoundMsg) {
System.out.println("this is response");
context.getMessage().writeTo(System.out);
} else {
System.out.println("this is request");
context.getMessage().writeTo(System.out);
}
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
#Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}
The output in console is as the following
this is request
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Header/><S:Body><ns2:echo xmlns:ns2="http://ws.documentType.com/"><arg0>yoyoyo</arg0></ns2:echo></S:Body></S:Envelope>
this is response
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:echoResponse xmlns:ns2="http://ws.documentType.com/"><return>echo: yoyoyo</return></ns2:echoResponse></S:Body></S:Envelope>
If you have difficulty to add a handler, follow the following tutorial
http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-server-side/
http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/
http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-testing-for-client-and-server-side/

Related

Extract SOAP custom header information

I want to read request header from SOAP incoming request in my Java code for some authorization purpose. I found few work-arounds like using SOAPHandlers and . Code as below :
`package com.cerillion.ccs.framework;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
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;
import org.apache.log4j.Logger;
public class ApiSoapHandler implements SOAPHandler<SOAPMessageContext> {
private static final Logger logger = Logger.getLogger(ApiSoapHandler.class.getName());
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
logger.debug("Inside ApiSoapHandler");
try {
SOAPMessage message = context.getMessage();
SOAPHeader header = message.getSOAPHeader();
message.saveChanges();
} catch (SOAPException e) {
logger.error("Error occurred while adding credentials to SOAP header.",
e);
}
return true;
}
#Override
public Set<QName> getHeaders() {
/* QName securityTokenHeader = new QName("urn:com.intertech.secty", "token");
//new QName(“urn:com.intertech.secty”,“username”);
HashSet<QName> headers = new HashSet<QName>();
headers.add(securityTokenHeader);
return headers;*/
return null;
} }`
I ma really curious about to have some other simple alternative rather than writing entire handler just for fetching custom header tag. Is this the only way to read SOAP request header ? Any leads are really appreciated

No 'Access-Control-Allow-Origin' header is present on the requested resource.

I'm using SpringMVC.I want to call an XML file with web service in order to parse it later.The problem is that I can't access the XML file, I have got this error:No 'Access-Control-Allow-Origin' header is present on the requested resource.I have tried the solution below:
I created a new class which purpose is to add Access-Control-Allow-Origin' header on the requested ressource.This is the class
package com.mycompany.myapp;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JsonpFilter implements Filter {
private String functionName;
#Override
public void destroy() {
}
#Override
public void doFilter(ServletRequest request, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("This filter can "
+ " only process HttpServletRequest requests");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (isJSONPRequest(httpRequest)) {
ServletOutputStream out = response.getOutputStream();
out.println(getCallbackMethod(httpRequest) + "(");
chain.doFilter(request, response);
out.println(");");
response.setContentType("text/javascript");
} else {
response.addHeader("Access-Control-Allow-Origin", "*");
chain.doFilter(request, response);
}
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
this.functionName = filterConfig.getInitParameter("encoding");
if(this.functionName == null || this.functionName.length() <= 0) {
this.functionName = "callback";
}
}
private String getCallbackMethod(HttpServletRequest httpRequest) {
return httpRequest.getParameter(this.functionName);
}
private boolean isJSONPRequest(HttpServletRequest httpRequest) {
String callbackMethod = getCallbackMethod(httpRequest);
return (callbackMethod != null && callbackMethod.length() > 0);
}
}
then I add the these two lines in my web.xml file:
<display-name>DataServices</display-name>
<filter>
<filter-name>JSONPRequestFilter</filter-name>
<filter-class> com.mycompany.myapp.JsonpFilter</filter-class>
<init-param>
<param-name>functionName</param-name>
<param-value>callback</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>JSONPRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I don't have any complilation problem, but I still have the same error in the console at the execution time.So, the 'Access-Control-Allow-Origin' header isn't taken into account.
Please,If you can find out what is wrong with my program, or suggest me another solution, I will be thankful
To do this implement this interface
org.springframework.web.servlet.HandlerInterceptor
here is an example
#Component
public class CORSInterceptor implements HandlerInterceptor{
private static final Log LOG = LogFactory.getLog(CORSInterceptor.class);
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
LOG.trace("sending headers");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
LOG.trace("afterCompletion is called");
}
}
Then add this line to your application context
<mvc:interceptors>
<bean class="com.elm.mb.rest.interceptors.CORSInterceptor" />
</mvc:interceptors>

Adding username and password to soap header in Java by using PasswordText Type and axis2

I want to add username and password to soap header in java by using PasswordText Type and axis2.
Code snippet I use
public static void WSSPasswordAuthentication(org.apache.axis2.client.ServiceClient client, String endPointUrl, String username, String password) throws CSException{
OMFactory omFactory = OMAbstractFactory.getOMFactory();
OMElement omSecurityElement = omFactory.createOMElement(new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"), null);
OMElement omusertoken = omFactory.createOMElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "UsernameToken","wsse"), null);
OMElement omuserName = omFactory.createOMElement(new QName("", "Username", "wsse"), null);
omuserName.setText(username);
OMElement omPassword = omFactory.createOMElement(new QName("", "Password", "wsse"), null);
omPassword.addAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",null );
omPassword.setText(password);
omusertoken.addChild(omuserName);
omusertoken.addChild(omPassword);
omSecurityElement.addChild(omusertoken);
client.addHeader(omSecurityElement);
}
And resultant header :
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsu:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><Username>erapor</Username><Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</Password></wsu:UsernameToken></wsse:Security>
But
The header I want : <soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:Username>erapor</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header>
Otherwise I couldn't use the header
How can I modify?
You can use plain JAXWS if you have an option to resolve this instead of using AXIS2 on the client side. This is generic and easy to add these kind of security headers.
In your JDK 6.0 HOME (This example works only from JDK 6.0 and above)
jdk1.6.0_26\bin\wsimport is an utility available
You can create the stub using the wsimport utility
wsimport -keep -verbose http://localhost:8080/<WebserviceName>/services/<WebserviceName>?wsdl
Create a message handler
MessageHandler.java
package com.secure.client;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class MessageHandler implements SOAPHandler<SOAPMessageContext>{
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public Set getHeaders() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
try {
boolean outMessageIndicator = (Boolean) soapMessageContext
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outMessageIndicator) {
SOAPEnvelope envelope = soapMessageContext.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("wsuser");
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("wspwd");
}
} catch (Exception ex) {
throw new WebServiceException(ex);
}
return true;
}
}
Create HeaderHandlerResolver.java
package com.secure.client;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
public class HeaderHandlerResolver implements HandlerResolver {
#SuppressWarnings("unchecked")
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
MessageHandler hh = new MessageHandler();
handlerChain.add(hh);
return handlerChain;
}
}
You can create the client code using stub
Client.java
import javax.xml.ws.BindingProvider;
import com.secure.HelloService;
import com.secure.HelloServiceException;
import com.secure.HelloServicePortType;
public class Client {
public static void main(String[] args) {
HelloService service = new HelloService();
service.setHandlerResolver(new HeaderHandlerResolver());
HelloServicePortType port = service.getHelloServiceHttpSoap11Endpoint();
// Use the BindingProvider's context to set the endpoint
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/<WebserviceName>/services/<WebserviceName>");
System.out.println(port.getVersion());
try {
System.out.println(port.getHello("Zack"));
} catch (HelloServiceException e) {
e.printStackTrace();
}
}
}

How to send a XML request with httpclient and receive a file? (Java)

I need to send a XML request to a webservice which was not developed using SOAP protocoal. The webservice only works with pure XML request/answer, so there is not WSDL. The webservice will answer with a gzip file which I have to download. Can anyone help me please? I started with the code below. Thanks!
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class Teste {
public static void main(String[] args)
{
boolean success = XMLDataPost();
System.out.println(success);
}
private static boolean XMLDataPost(){
boolean success = false;
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httpPost = new HttpPost("http://webservice.blablabla.com.br");
StringEntity reqEntity = new StringEntity("<RequestVeiculo><login>02566288000191</login><senha>159828</senha></RequestVeiculo>");
reqEntity.setContentType("text/xml");
reqEntity.setChunked(true);
httpPost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
if(response.getStatusLine().getStatusCode() == 200){
success = true;
}
if (resEntity != null) {
System.out.println("Tamanho: " + resEntity.getContentLength());
System.out.println("Chunked?: " + resEntity.isChunked());
}
EntityUtils.consume(resEntity);
}
catch (Exception e) {
System.out.println(e);
}
finally {
httpclient.getConnectionManager().shutdown();
}
return success;
}
}

Using cookies from httpclient in webview

In my app I'm sending a device ID to a server using http post and I'm getting a session ID back. Now I need to get the session cookie in my webviewclient. I did some research and found this:
Android WebView Cookie Problem
The problem is the solution doesn't work for me. I keep getting an error on this line:
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
The method getCookieStore() is undefined for HttpClient type. I should have all the right libraries loaded, so I don't know why I keep getting an error.
Here is my code, maybe someone will be able help me implement a solution to get the session cookie into my webview.
Thanks in advance!
package mds.DragonLords;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class Home extends Activity {
WebView mWebView;
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
private String tmDevice;
private String sid;
private String url;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
tmDevice = "2" + tm.getDeviceId();
postData();
url = "myserver"+sid.substring(5);
setContentView(R.layout.web);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new HelloWebViewClient());
mWebView.loadUrl(url);
}
public void postData() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("myserver");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("uid", tmDevice));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
inputStreamToString(response.getEntity().getContent());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
private void inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sid = total.toString();
}
}
I've just ran into the same thing. I know it's an old post, but maybe it'll help somebody else.
The problem is in declaration of postData().
That line now is :
HttpClient httpclient = new DefaultHttpClient();
It should be:
DefaultHttpClient httpclient = new DefaultHttpClient();
see this: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/DefaultHttpClient.html