基于Apache CXF的REST服务端如何获取客户端设置的HTTP接收超时
在Apache CXF服务端获取客户端ReceiveTimeout的方法
当然可以实现这个需求!不过得先理清一个关键点:客户端的ReceiveTimeout默认是它本地的超时配置,不会自动通过HTTP请求传递到服务端。所以要拿到这个值,得分两种场景来处理:
场景一:客户端主动传递ReceiveTimeout值
如果你的客户端也是基于Apache CXF开发的,最简单的方式是给客户端加个拦截器,把它本地配置的ReceiveTimeout放到HTTP请求头里,这样服务端就能直接读取了。
给你写个客户端拦截器的示例代码(放在PRE_PROTOCOL阶段最合适,这时候请求还没发出去):
public class ClientTimeoutHeaderInterceptor extends AbstractPhaseInterceptor<Message> { public ClientTimeoutHeaderInterceptor() { super(Phase.PRE_PROTOCOL); } @Override public void handleMessage(Message message) throws Fault { // 从客户端的HTTP管道里拿到ReceiveTimeout配置 HTTPConduit conduit = (HTTPConduit) message.get(Conduit.class); Integer receiveTimeout = conduit.getReceiveTimeout(); if (receiveTimeout != null) { // 把值放到自定义请求头里 Map<String, List<String>> headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS); if (headers == null) { headers = new HashMap<>(); message.put(Message.PROTOCOL_HEADERS, headers); } headers.put("X-Client-Receive-Timeout", Collections.singletonList(receiveTimeout.toString())); } } }
把这个拦截器注册到客户端后,服务端就能在请求头里拿到X-Client-Receive-Timeout的值了。
场景二:服务端通过CXF上下文获取相关超时(注意区分)
如果你的需求其实是想获取服务端自己针对当前请求设置的超时,或者客户端通过CXF特定属性传递的超时,那你提到的PhaseInterceptorChain.getCurrentMessage()确实是核心入口:
- 获取服务端侧的接收超时配置:
Message message = PhaseInterceptorChain.getCurrentMessage(); HTTPDestination destination = (HTTPDestination) message.get(Destination.class); Long serverReceiveTimeout = destination.getReceiveTimeout();
- 如果客户端主动把
ReceiveTimeout放到了CXF的消息属性里(这种情况比较少见,需要客户端配合设置),可以直接从Message中提取:
Integer clientReceiveTimeout = (Integer) message.get(HTTPConstants.RECEIVE_TIMEOUT);
关键对象与拦截器说明
PhaseInterceptorChain.getCurrentMessage():这确实是获取当前请求上下文的核心工具,拿到的Message对象包含了请求的所有上下文信息,包括协议头、传输属性等,完全是你要找的入口。HTTPConduit(客户端):客户端用来配置传输超时的核心对象,ReceiveTimeout、ConnectionTimeout这些配置都存在这里。HTTPDestination(服务端):服务端的HTTP传输目的地对象,保存着服务端自己的超时配置。- 拦截器阶段:客户端建议用
PRE_PROTOCOL阶段添加请求头,服务端可以在PRE_INVOKE阶段拦截请求并提取头信息。
总结一下:如果要拿客户端本地的ReceiveTimeout,必须让客户端主动把这个值传到服务端(比如自定义请求头);如果是服务端自己的超时配置,或者客户端通过CXF属性传递的超时,直接用Message对象就能拿到。
内容的提问来源于stack exchange,提问作者Cristiano Ghersi
相关产品推荐
相关产品推荐

