是否可能使用jax-ws生成xml,但不发送出去?

5
所以这里是情景: 我们有PeopleSoft并想要在Salesforce之间来回发送消息。不幸的是,PeopleSoft没有像wsimport这样的工具,可以消费一个wsdl并为您生成类。虽然有一些消费wsdl的东西,但它只会生成桩消息对象。开发人员仍然需要编写代码来手动生成xml消息字符串。
显然,我不想做所有这些。我知道在PeopleSoft内部可以调用Java。我也知道我可以使用生成的类仅发送消息,但我想使用PeopleSoft内置的消息监视功能。
因此,我正在考虑的可能解决方案将:
  1. 在Java中调用webservice方法(而不发送消息)
  2. 获取xml
  3. 通过PeopleSoft机制发送xml
  4. 抓取响应xml
  5. 将响应xml传递回响应Java类
  6. 使用Java类在xml中获取值
我疯了还是这可能?
附言:我是一个新手Java开发人员。 这是我的处理程序类来获取xml,但需要一些方法来防止消息被发送出去。
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个回答

2
在Java Web服务中,有一种系统化的方法可以实现此功能,即使用JAX-WS应用拦截器模式。使用SOAP处理程序来应用拦截器模式。处理程序类将在handleMessage(SOAPMessageContext mc)方法中拦截消息,并对SOAP信封的XML正文进行任何您想要的操作。然后停止进一步处理SOAP消息。

然后,您可以自由处理XML(例如通过peoplesoft机制发送)。当从peoplesoft返回响应时,请绕过出站处理程序链...(我真的必须查看如何绕过链)。我只是在思考这个想法,您需要进行概念验证。我从未这样做过,否则我会共享代码。但这绝对是可行的。


如果您正在编写新的Web服务端点,请优先选择基于提供程序的机制而不是SEI JAX-WS机制,因为SEI用于更高级别的抽象,并且您希望使用生成的XML进行工作。 - Asif Shahzad
我已经通过查看示例实现了一个处理程序类,但不确定如何停止SOAP消息的进一步处理。有什么提示吗?这是我的处理程序类:public boolean handleMessage(SOAPMessageContext smc) { logToSystemOut(smc); return true; } private void logToSystemOut(SOAPMessageContext smc) { SOAPMessage message = smc.getMessage(); try { ByteArrayOutputStream baOut = new ByteArrayOutputStream(); message.writeTo(baOut); xmlOut = new String(baOut.toByteArray()); } } - willard
我认为你是从PeopleSoft调用由SalesForce提供的服务。因此,你应该在客户端定义处理程序,因为你想拦截客户端运行时生成的SOAP消息(以便通过PeopleSoft机制传递)。你所定义的处理程序的方式用于在服务器端定义处理程序。客户端处理程序的定义方式不同。请参见http://bit.ly/zGerml 以了解一个想法。 - Asif Shahzad
  1. 在您定义的处理程序中,您没有检查您是在处理出站消息还是入站消息。您最初对获取出站消息的 XML(在 PeopleSoft 端)感兴趣,所以只需添加 if((Boolean) lmc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {... }。
- Asif Shahzad
处理程序的进一步处理可以通过从handleMessage(..)返回“false”来终止。但主要问题是,您不仅想停止进一步处理。您希望暂停进一步处理,通过另一种方式获取响应,然后从某个入站消息恢复处理。不知道如何做:(这非常棘手+有趣。 - Asif Shahzad
我可以停止处理。我只需要一种将原始XML返回到生成的响应对象中的方法,以便我可以从那里读取我的值。感谢您的所有回复! - willard

1

其中一个解决方案可能是替换 JAX-WS 的 SocketFatory。大致上看起来会像这样:

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(...);

MySocketFactory 中,您可以自由地创建套接字,将消息传输到另一个通道。

1

当你说你只需要XML时,你是指SOAP消息还是仅请求/响应类型?我不确定你是否在谈论第二种情况,但如果你只想要XML,为什么不直接使用JAXB呢?

如果是这种情况,你可以从WSDL中提取模式,生成你的类型(假设你有一个名为“A”的操作的RequestA和ResponseA),并使用JAXB的marshaller/unmarshaller来序列化/解析XML。然后通过你想要的协议发送它。


直接使用JAXB会需要很多的努力,因为我们不仅需要消息的XML表示,还需要完整的SOAP消息,以便服务端点能够理解。其次,当JAX-WS运行时也可以做到这一点时,我们应该探索/重用它,而不是重新发明轮子。 - Asif Shahzad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接