aspose file tools*
The moose likes Web Services and the fly likes Extract SOAP object from HttpServletRequest Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Web Services
Bookmark "Extract SOAP object from HttpServletRequest" Watch "Extract SOAP object from HttpServletRequest" New topic
Author

Extract SOAP object from HttpServletRequest

Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi all,
new to WS. How do you extract the SOAP object from a HttpServletRequest.

Mat
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41863
    
  63
I think you have that the wrong way around. If you're dealing with SOAP, then most implementations are based on servlets, and will provide access to the HttpServletRequest object in some way. But that is not generally necessary, as SOAP operates on a higher level than HTTP.

I'm not sure what you mean by "SOAP object", though - SOAP is a protocol, which can be (and has been) implemented in any number of ways. What exactly are you trying to do?


Ping & DNS - my free Android networking tools app
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Ulf,

Im currently using acegi authentication entry point filter to capture the SOAP requests being passed into my existing web application.

public void commence(ServletRequest request,
ServletResponse response,
AuthenticationException authException)
throws IOException, ServletException

If a web service call is detected via

if (!StringUtil.isEmpty(req.getServletPath())&&
(req.getServletPath().indexOf("/services")!=-1))

then a RequestDispatcher dispatcher.forward(request, response)
is done to pass the soap request to Axis2 engine.

Other requests that are not ws are asked to authenticate via SSO.

Each WS soap request contains a user id that needs to be logged.
Logging needs to be done before the dispatcher.forward statement.

How can I get hold of the user id

William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12785
    
    5
If the ID you want to extract is in the SOAP formatted message that is the body of the resource, you have your work cut out for you.

The SOAP servelet is going to want to see an unaltered input stream that forms the SOAP message so your filter will have to:

1. capture the complete SOAP message as text
2. parse out the ID you want
3. create an custom class extension of HttpServletRequestWrapper than can take the complete SOAP message from 1. and form a new InputStream that can be handed to the SOAP servlet. In other words, the servlet gets your custom wrapper instead of the original HttpServletRequest object.

See the servlet JavaDocs and good luck!

Bill
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi William,
just to get me started, how do I capture the complete SOAP message as text from the request
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41863
    
  63
That's what the getInputStream and getReader methods do.
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Ulf and William,
would the following work to extract the soap package?

import org.apache.axis2.context.MessageContext;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.transport.TransportUtils;

protected void simulateLogin(HttpServletRequest request)throws Exception
{

InputStream inStream=request.getInputStream();
SOAPEnvelope soap= TransportUtils.createSOAPMessage(MessageContext.getCurrentMessageContext(), inStream, request.getContentType());

//Extract the user id from the soap package
}

Mat
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Ulf,
managed to get the personId using the following:-

protected void simulateLogin(HttpServletRequest request)throws Exception
{
InputStream inStream=request.getInputStream();
InputStreamReader reader = new InputStreamReader(inStream);
BufferedReader bReader = new BufferedReader(reader);
String soapBody=bReader.readLine();
String personId =getMessageValue("personId",soapBody);
}

but after calling the above I pass the soap req/resp to the Axis2 engine as follows:-

RequestDispatcher dispatcher = request.getRequestDispatcher(requestURI);
dispatcher.forward(request, response);

This usually works ok, but since I have called simulateLogin I get the following error:-
org.apache.axis2.AxisFault: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog at [row,col {unknown-source}]: [1,0] on server

Do I need to clone the HttpServletRequest going into simulateLogin due to it doing a read

I have tried writting the following to clone HttpServletRequest but this did not work

class CustomRequestWrapper implements Cloneable
{
private HttpServletRequest request=null;

public CustomRequestWrapper(HttpServletRequest request)
{this.request=request;}
public CustomRequestWrapper(){ }

public HttpServletRequest getHttpServletRequest(){
return request;
}
public Object clone()
{
CustomRequestWrapper clone = new CustomRequestWrapper();
clone.request=request;
return clone;
}
}


Any ideas



Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41863
    
  63
You'll need to implement the full step #3 William mentions above. Just making a copy of the request object pointer accomplishes nothing.
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Bill/Ulf,

followed the above and get the following error:-
org.apache.axis2.AxisFault: java.lang.ClassCastException on server

The code I used was as follows:-

class CustomRequestWrapper extends HttpServletRequestWrapper
{
private String soapMessage=null;

public CustomRequestWrapper(HttpServletRequest request)
{
super(request);
}

public void setSoapMessage(String soapMessage){
this.soapMessage= soapMessage;
}

/**
* This method should override the getInputStream from (HttpServletRequestWrapper extends ServletRequestWrapper)
*/
public ServletInputStream getInputStream() throws java.lang.IllegalStateException, java.io.IOException
{

if(soapMessage==null) return null;

java.io.InputStream in = null;
try{
in = new StringBufferInputStream(soapMessage);

}catch(Exception ex){

}

return (ServletInputStream)in;

}
}//CustomRequestWrapper

I think that Axis2 engine sees the class exception on calling the follwoing line:-
(ServletInputStream)in

I'm not sure how to convert the StringBufferInputStream into a ServletInputStream .




Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 41863
    
  63
Mat Anthony wrote:I'm not sure how to convert the StringBufferInputStream into a ServletInputStream

You can't. You'll need to subclass ServletInputStream and implement the read method, like its javadocs suggest.
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Bill/Ulf,
got it working at last with the following code:-

class CustomRequestWrapper extends HttpServletRequestWrapper
{
private String soapMessage=null;

public CustomRequestWrapper(HttpServletRequest request)
{
super(request);
}

public void setSoapMessage(String soapMessage){
this.soapMessage= soapMessage;
}

public ServletInputStream getInputStream() throws java.lang.IllegalStateException, java.io.IOException
{
if(soapMessage==null) return null;
StringBufferInputStream in = null;
try{
in = new StringBufferInputStream(soapMessage);

}catch(Exception ex){

}
return new BufferedServletInputStream(in);

}
}

private class BufferedServletInputStream extends ServletInputStream {

private StringBufferInputStream bais;
public BufferedServletInputStream(StringBufferInputStream bais) {
this.bais = bais;
}

public int available() {
return this.bais.available();
}

public int read() {
return this.bais.read();
}

public int read(byte[] buf, int off, int len) {
return this.bais.read(buf, off, len);
}
}

Thanks for all your help
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12785
    
    5
Congratulations on mastering one of the tricky but powerful aspects of the servlet API!



Bill
Harika Mamidi
Greenhorn

Joined: Jul 09, 2013
Posts: 2
Hi Mat Anthony,
I am facing the same problem that you have posted. I tried creating wrapper , but how were you able to extract the soap message from the servlet request to set it in CustomRequestWrapper ?

Thanks,
Harika
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Harika,
I did not extract the soap message from the CustomRequestWrapper, but used it to forward onto the Axis soap engine. This approach was used because if you read from the original request that comes in you cannot then forward the same object. Anyway this is how you extract the soap message from the original request.



Hope this helps

Mat

Harika Mamidi
Greenhorn

Joined: Jul 09, 2013
Posts: 2
Hi Mat,
Thats was a quick reply, it worked , i was trying to create a wrapper and extract soap message, and i was sending my original request for axis2 processing.

Thanks a lot!
Mat Anthony
Ranch Hand

Joined: May 21, 2008
Posts: 236
Hi Harika,
hope you don't mind , but a bit of advice. I developed several succ web services using axis2 but found it heavy going. Started off by creating a wsdl then generated all the back end code. Init I started
to come across issues with extracting user cred from the soap env, just like you are experiencing. Other issues occurred such as implementing security modules. In the last couple of months I have
moved away from Axis2 and I'm now using spring ws with Castor as the Marsh/UnMarsh. Spring allows you to extract user credtial without having to worry about wrappers. It also allows you to implement
Security on your web services via configuration files that can point to trust stores. If your backend services use spring/ hibernate you're laughing. Give it a go.

Mat
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Extract SOAP object from HttpServletRequest