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

问题描述:

我使用AXIS 2使用名为ChannelConnectServiceStub的存根调用WS方法。我可以在调用Axis 2中的存根之前将属性设置为MessageContext Java

生成存根和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没有交换多线程 环境中的值。

我试过下面的一个也是因为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()); 
    } 

} 

确保获得ConfigurationContext的单例实例。

当您从ServiceContext需要注意的是获得每个JVM属性对象的共享副本,所以不是“testid”键,使用一个唯一的密钥,

前做的setProperty和getProperty: 在客户端代码存根初始化代替,

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共享属性对象存储的值,以避免内存增长删除不再需要的值。

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

要为不同的消息设置不同的属性,您需要在MessageContext中设置它们。但在客户端存根消息上下文将为空。在Servicecontext中设置属性就像;该属性在服务调用完成之前一直存在。

你可以做的是,从客户端存根,添加一个自定义肥皂标题,并在标头中设置ID ..从处理程序中读取标题。

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

非常感谢您的回答。我在请求中获得了自定义标题。但该服务不会在响应中提供标题。那我该如何在回应中读到它? – namalfernandolk

+0

实际上,如果您在请求中设置标头,则应该能够在处理程序中读取标头,如果该处理程序放置在IN Flow中。如果你的服务没有响应头文件,那么你的处理程序中就不能获得详细信息,如果该处理程序保存在OUTFlow中。 ..所以,你需要确保从服务设置标题 – Ratha

+0

非常感谢。但我无法控制亲爱的服务。我只使用客户端。那么,这意味着在OUT Flow中我没有这些信息吗? – namalfernandolk