Is it possible to use jax-ws to generate xml, but NOT send it out

4.8k Views Asked by At

So here's the scenario: We have PeopleSoft and want to send messages back and forth from salesforce. Unfortunately PeopleSoft doesn't have a tool like wsimport which consumes a wsdl and generates classes for you. There is something that consumes wsdl's, but all it does it generate stub message objects. A developer would still have to write the code to manually generate the xml message string.

I obviously don't want to do all of that. So I know that java can be called from within PeopleSoft. I also know I could send messages just using the generated classes, but I would like to use the message monitoring features built in to PeopleSoft.

So a possible solution that I am thinking of will:

  1. call the webservice method in java (without sending out the message)
  2. Grab the xml
  3. send the xml via peoplesoft mechanisms
  4. grab the response xml
  5. pass the response xml back into the response java class
  6. Use java classes to grab values within the xml

Am I crazy or is this possible?

p.s. i am a newbie java developer

Here's my handler class to grab the xml, but need some way to preventing message being sent out.

public class LoggingHandler implements SOAPHandler<SOAPMessageContext> {
 // change this to redirect output if desired
private static PrintStream out = System.out;
private String xmlOut = null;

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) {
}

public String getXmlOut() {
    return xmlOut;
}

/*
 * 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);


    SOAPMessage message = smc.getMessage();
    try {
        ByteArrayOutputStream baOut = new ByteArrayOutputStream();
        message.writeTo(baOut);
        xmlOut = new String(baOut.toByteArray());


    } catch (Exception e) {
        out.println("Exception in handler: " + e);
    }
}

}
3

There are 3 best solutions below

0
On

One of the solutions might be to replace the SocketFatory of JAX-WS. Roughly it will look like this:

javax.net.SocketFactory socketFactory = new MySocketFactory();
Service service = Service.create(new URL(wsdl), new QName(namespace, servicename));
Dispatch<SOAPMessage> dispatch = service.createDispatch(methodToBeCalled, SOAPMessage.class, Service.Mode.MESSAGE);
dispatch.getRequestContext().put(com.sun.xml.ws.developer.JAXWSProperties.SSL_SOCKET_FACTORY, socketFactory);
// or ((BindingProvider) Service.getPort(SEIInterface.class)).getRequestContext().put(...);

And in MySocketFactory you are free to create sockets that will pipe the message to another channel.

6
On

There is a systematic way of doing so in Java web services, JAX-WS. Just apply interceptor pattern using SOAP Handler. The handler class will intercept the message in handleMessage(SOAPMessageContext mc) method, do whatever you want to do with XML body of SOAP Envelope. and stop SOAPMessage further processing.

Then, you can treat the XML as you like (e.g. sending via peoplesoft mechanism). And when response come back from peoplesoft, bypass the outbound handler chain ... (I really have to look how to by pass a chain). I am just rolling the idea, you have to make POC. I never did so, otherwise I would have share code. But this is absolutely doable.

1
On

When you say that you only need the XML, are you talking about the SOAP message or just the request/response types? I'm not sure if your are talking about the second case, but if you only wanted the XML, why not using JAXB directly?

If that's the case, you could extract the schemas from the WSDL, generate your types (let's say you have RequestA and ResponseA for an operation "A" in the WSDL) and use JAXB's marshaller/unmarshaller to serialize/parse the XML. Then send it through the protocol that you want.