我可以在调用Axis 2 Java中的存根之前将属性设置为MessageContext

时间:2013-07-15 12:04:42

标签: java web-services wso2 axis2 webservice-client

我正在使用AXIS 2使用名为ChannelConnectServiceStub的存根调用WS方法。

生成存根和ConfigurationContext:

public class TestWSClient {

    private void init() throws Exception {

        String                  proxyUrl                    = "http://subdom.dom.com/testpath/TestConnect.asmx";
        ConfigurationContext    ctx                         = ConfigurationContextFactory.createConfigurationContextFromFileSystem("/rootFolder/Axis2/axis2-1.4.1/repository", "/rootFolder/Axis2/axis2-1.4.1/conf/axis2.xml");
        ChannelConnectServiceStub channelConnectServiceStub = new ChannelConnectServiceStub(ctx,proxyUrl);

        ctx.setProperty("testid", "testidval"); // Approach 1
        channelConnectServiceStub._getServiceClient().getServiceContext().setProperty("testid", "testidval"); // Approach 2

    }
}

我正在使用LogHandler记录消息请求和响应。

LogHandler:

class LogHandler extends AbstractHandler implements Handler {

    @Override
    public InvocationResponse invoke(MessageContext messageContext) throws AxisFault {

        String testID       = null;
        String invokeStr    = null;
        String axisService  = null;
        String action       = null;

        invokeStr       = messageContext.getEnvelope().toString();
        axisService     = messageContext.getAxisService().getName();
        action          = messageContext.getAxisMessage().getAxisOperation().getInputAction();

        testID = (String) messageContext.getProperty("testid");// Approach 1
        testID = (String) messageContext.getServiceContext().getProperty("testid");// Approach 2

        return InvocationResponse.CONTINUE;
    }

}

我想从我创建并调用存根到LogHandler类的点传递属性(“testid”)。我已经提到了我采取的两种方法。

两者都传递了价值。但问题是,有多个客户端线程使用相同的TestWSClient来使用该服务。因此,当涉及到LogHandler时,不同客户端设置的不同值正在交换。 (但是invokeStr,AxisService和action没有这个问题。)

  1. 有没有办法在之前将属性传递给MessageContext 存根被调用?
  2. 任何人都可以帮助从存根获取属性 LogHandler没有在多线程中交换值 环境。
  3. 我在下面尝试了一次,但由于operationContext为NULL而失败。

    OperationContext operationContext = stub._getServiceClient().getLastOperationContext();
    logger.info("operationContext : " + operationContext);
    
    if (operationContext != null) {
    
        MessageContext outMessageContext = operationContext.getMessageContext("Out");
    
        if (outMessageContext != null) {
            logger.info("outMessageContext.getEnvelope().toString() : " + outMessageContext.getEnvelope().toString());
            outMessageContext.setProperty("Portal", getPortal());
        }
    
        MessageContext inMessageContext = operationContext.getMessageContext("In");
        logger.info("inMessageContext : " + inMessageContext);
    
        if (inMessageContext != null) {
            logger.info("inMessageContext.getEnvelope().toString() : " + inMessageContext.getEnvelope().toString());
            inMessageContext.setProperty("Portal", getPortal());
        }
    
    }
    

2 个答案:

答案 0 :(得分:3)

确保获取ConfigurationContext的单例实例。

当您从ServiceContext执行setProperty和getProperty时请注意,您要获取每个jvm的Property对象的共享副本,因此使用唯一键而不是“testid”键,

例如: 在存根文件初始化后的客户端代码中,而不是

channelConnectServiceStub._getServiceClient().getServiceContext()
  .setProperty("testid","testidval");

channelConnectServiceStub._getServiceClient().getServiceContext()
 .setProperty(stub._getServiceClient().getServiceContext().getName(), "testidval");

并检索属性,在loghandler中使用相同的密钥(每个流msgContext.getServiceContext().getName()是唯一的)

而不是

messageContext.getServiceContext().getProperty("testid");

messageContext.getServiceContext()
 .getProperty(msgContext.getServiceContext().getName());

还要注意,当您在jvm共享Property对象上存储值时,为了避免内存增长,请在不再需要时删除该值。

messageContext.getServiceContext()
 .removeProperty(msgContext.getServiceContext().getName();

答案 1 :(得分:1)

要为不同的消息设置不同的属性,您需要在Messagecontext中设置它们。但是在客户端存根消息上下文将为null。在Servicecontext上设置属性就像;在服务调用完成之前,该属性仍处于活动状态。

您可以做的是,从客户端存根中添加自定义soap标头并在标头中设置ID。从处理程序中读取该标头。

ServiceClient serviceClient = stub._getServiceClient();
serviceClient.addStringHeader("xx")