Java ApacheCXF-在输入和输出拦截器之间共享数据

Java ApacheCXF-在输入和输出拦截器之间共享数据,java,cxf,Java,Cxf,我使用ApachCXF作为REST提供者 我想在进入webservice时收集数据,在进入resposne之前收集数据,并在响应中添加一些计算。对于这个问题,为了简单起见,让我们假设我想要得到输入时的开始时间,发送响应之前的结束时间,并将总时间添加到响应中 现在,我该怎么做?我创建了单独运行良好的输入和输出拦截器,但是如何在输出拦截器中使用来自输入拦截器的数据呢 谢谢 伊多布 更新: 我尝试将数据设置为上下文参数 message.setContextualProperty(key,value)

我使用ApachCXF作为REST提供者

我想在进入webservice时收集数据,在进入resposne之前收集数据,并在响应中添加一些计算。对于这个问题,为了简单起见,让我们假设我想要得到输入时的开始时间,发送响应之前的结束时间,并将总时间添加到响应中

现在,我该怎么做?我创建了单独运行良好的输入和输出拦截器,但是如何在输出拦截器中使用来自输入拦截器的数据呢

谢谢 伊多布



更新: 我尝试将数据设置为上下文参数

message.setContextualProperty(key,value);
但我正在努力

message.getContextualProperty(key);
我也试过同样的方法,但只是用

message.put(key,value) and message.get(key)
没用

有人吗

谢谢,,
Idob

您的拦截器可以访问
javax.xml.ws.handler.MessageContext
。这扩展了
映射
,因此您可以将任何需要的内容放入上下文中,然后在请求中访问它:

public boolean handleMessage(final MessageContext context) {
    context.put("my-key", myCustomObject);
            // do whatever else your interceptor does
}
稍后:

public boolean handleMessage(final MessageContext context) {
    MyCustomObject myCustomObject = context.get("my-key");
            // do whatever else your interceptor does
}

您可以在上存储值。CXF为每个请求创建一个
Exchange
对象,作为请求/响应对的输入和输出消息的容器,并使其作为
message.getExchange()
从这两个请求访问

在拦截器中:

public void handleMessage(Message inMessage) throws Fault {
  inMessage.getExchange().put("com.example.myKey", myCustomObject);
}
外拦截器

public void handleMessage(Message outMessage) throws Fault {
  MyCustomObject obj = (MyCustomObject)outMessage.getExchange().get("com.example.myKey");
}
(反之亦然,对于客户端拦截器,out将存储值,in将检索值)。选择一个您知道不会被其他拦截器使用的密钥-包限定名是一个不错的选择。请注意,与
Message
一样,
Exchange
是一个
StringMap
,具有通用的put/get方法,该方法将
作为键,为您提供编译时类型安全性,并使您无需强制转换:

theExchange.put(MyCustomObject.class, new MyCustomObject());
MyCustomObject myObj = theExchange.get(MyCustomObject.class);

但是拦截器必须重写:public void handleMessage(Message Message)抛出错误。它是如何组合的?我尝试了设置:message.setContextalProperty(key,value),但当我尝试设置message.getContextalProperty(key)时,我得到了null。@Idob只有当您的拦截器实现JAX-WS的
javax.xml.WS.handler.handler
时,这才有效。如果您正在实现特定于CXF的
org.apache.CXF.phase.PhaseInterceptor
,它将不起作用。感谢您的时间和帮助,但是message.getExchange().put和get可以正常工作。我非常确定CXF不会同时使用多个线程来处理同一个消息交换,因此是的,它应该是安全的。您没有在拦截器本身上存储任何状态,只存储在exchange上。是的,但在拦截器中设置了message.getExchange().put(Student.class.getSimpleName(),Student);在输出时,我得到消息.getExchange().get(Student.class.getSimpleName());这是同一把钥匙。当两个进程试图同时执行此操作时会发生什么情况?这就是为什么我在代码中使用
com.example
——由您选择其他人不会使用的名称。另一方面,
Exchange
实现了
StringMap
,它提供了通用的put和get方法,其中键是
Class
,允许
Student stu=message.getExchange().get(Student.Class)
而无需强制转换。因此,如果我理解正确,每个应用程序只有一个交换。除非我为每个交换put(即使是在完全相同的类上)提供一个唯一的密钥,否则我不能使用它。如果是这样的话,这对我来说还不够好,因为一切都是无状态的,我无法设置一个唯一的密钥,以后可以再次检索。不,每个请求都有一个
Exchange
。您需要选择一个其他拦截器不会用于同一请求的密钥,但您可以在一个请求到下一个请求中重复使用同一密钥,请记住,从exchange可以获取消息,因此不需要在入站拦截器和出站拦截器之间共享数据。