如果想取消已经发布的服务,应该怎么做?

3 views
Skip to first unread message

SkyTiger

unread,
Apr 23, 2008, 9:51:11 PM4/23/08
to cxf-zh
RT

SkyTiger

unread,
Apr 23, 2008, 9:58:36 PM4/23/08
to cxf-zh
直接调用server的stop是否可以?

SkyTiger

unread,
Apr 23, 2008, 9:59:42 PM4/23/08
to cxf-zh
还是serverRegistry.unregister?

On Apr 24, 6:58 am, SkyTiger <darktemplars...@gmail.com> wrote:
> 直接调用server的stop是否可以?

willem

unread,
Apr 23, 2008, 10:10:55 PM4/23/08
to cxf-zh
调用server的stop方法就行了,serverRegistry 会在bus shutdown的时候 调用server的stop方法。
具体代码可见
https://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/endpoint/ServerRegistryImpl.java

姜宁 (Willem)
--------------------------------
http://willem.bokeland.com

SkyTiger

unread,
Apr 23, 2008, 10:14:37 PM4/23/08
to cxf-zh
STOP会不会将Destination也关闭了呢?

我目前的情况是多个服务共享一个URL,通过截取器来区分不同的服务实例,这样的情况下STOP也管用吗?

On Apr 24, 7:10 am, willem <willem.ji...@gmail.com> wrote:
> 调用server的stop方法就行了,serverRegistry 会在bus shutdown的时候 调用server的stop方法。
> 具体代码可见https://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/core/src/main...
>
> 姜宁 (Willem)
> --------------------------------http://willem.bokeland.com

willem

unread,
Apr 23, 2008, 10:23:31 PM4/23/08
to cxf-zh
我的回答还是调用server 的stop方法,
具体的代码在[1], server会判断对应的Message Observer是不是MultipleEndpointObserver,如果是,
会做相应处理的。

BTW, 建议你还是把CXF的code下下来,建一个工程,这样研究API,代码都比较方便。

[1]https://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/core/src/
main/java/org/apache/cxf/endpoint/ServerImpl.java


姜宁 (Willem)
--------------------------------
http://willem.bokeland.com

SkyTiger

unread,
Apr 24, 2008, 3:58:51 AM4/24/08
to cxf-zh
问题:

关闭后,客户端调用错误:
信息: Interceptor has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
at
org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:
187)
at
org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:
56)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:
207)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:402)
at org.apache.cxf.transport.http.HTTPConduit
$WrappedOutputStream.handleResponse(HTTPConduit.java:1948)
at org.apache.cxf.transport.http.HTTPConduit
$WrappedOutputStream.close(HTTPConduit.java:1791)
at
org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:
66)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:
575)
at org.apache.cxf.interceptor.MessageSenderInterceptor
$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:
62)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:
207)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:254)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:205)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:
73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:
135)
at $Proxy50.serverSayHi(Unknown Source)

请注意这里有响应信息,ClientImpl.onMessage(ClientImpl.java:402),只是信息结构不正确!如果服务关闭了,
这个响应的消息到底是什么呢?

willem

unread,
Apr 24, 2008, 4:11:15 AM4/24/08
to cxf-zh
你是把所有的endpoint的Server都stop了吗?

还有你可以通过配置LoggingInterceptor来输出相关的日志信息。这里有相关的文档[1]。

[1] http://cwiki.apache.org/CXF20DOC/debugging.html

姜宁 (Willem)
--------------------------------
http://willem.bokeland.com

SkyTiger

unread,
Apr 24, 2008, 5:27:36 AM4/24/08
to cxf-zh
我是使用CXF的CALLBACK的例子,只是我在使用回调接口的时候给出的版本值不是事先制定的1或是2,而是其他值,这时就会出现上面的问题; 按
照正常的情况应该返回服务不存在的错误!

SkyTiger

unread,
Apr 24, 2008, 5:28:34 AM4/24/08
to cxf-zh
就算是没有全部STOP,也不应该返回消息格式不对的错误啊!

On Apr 24, 1:11 pm, willem <willem.ji...@gmail.com> wrote:
> 你是把所有的endpoint的Server都stop了吗?
>
> 还有你可以通过配置LoggingInterceptor来输出相关的日志信息。这里有相关的文档[1]。
>
> [1]http://cwiki.apache.org/CXF20DOC/debugging.html
>
> 姜宁 (Willem)
> --------------------------------http://willem.bokeland.com

SkyTiger

unread,
Apr 24, 2008, 5:34:31 AM4/24/08
to cxf-zh
看看消息吧:
信息: Outbound Message:
--------------------------------------
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/
envelope/"><soap:Header><version xmlns="http://apache.org/
callback">789</version></soap:Header><soap:Body><callback_message
xmlns="http://apache.org/callback">z00118703</callback_message></
soap:Body></soap:Envelope>--------------------------------------

2008-4-24 17:31:59 org.apache.cxf.interceptor.LoggingInInterceptor
handleMessage
信息: Inbound Message
--------------------------------------
Headers: {transfer-encoding=[chunked], Server=[Jetty(6.1.5)]}
Message:

--------------------------------------

返回的消息好怪异啊!

我的服务断监听的是version 为123和456的服务
而客户端调用的version是789,结果就是这个样子了!

SkyTiger

unread,
Apr 24, 2008, 5:37:39 AM4/24/08
to cxf-zh
这是我的WSDL文件:就是那个03版本可以编译,而05版本不能编译的那个:
<wsdl:types>
<schema targetNamespace="http://apache.org/callback"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">
<xsd:import namespace="http://www.w3.org/2005/08/addressing"
schemaLocation="/schemas/wsdl/ws-addr.xsd"/>
<element name="callback_message" type="xsd:string"/>
<element name="RegisterCallback"
type="references:EndpointReferenceType"/>
<element name="returnType" type="xsd:string"/>
<element name="version" type="xsd:string"/>
</schema>
</wsdl:types>
<wsdl:message name="server_sayHi">
<wsdl:part element="tns:version" name="xHeader"/>
<wsdl:part element="tns:callback_message" name="return_message"/>
</wsdl:message>
<wsdl:message name="register_callback">
<wsdl:part element="tns:RegisterCallback" name="callback_object"/>
</wsdl:message>
<wsdl:message name="returnMessage">
<wsdl:part element="tns:returnType" name="the_return"/>
</wsdl:message>
<wsdl:portType name="CallbackPortType">
<wsdl:operation name="ServerSayHi">
<wsdl:input message="tns:server_sayHi" name="ServerSayHiRequest"/
>
<wsdl:output message="tns:returnMessage"
name="ServerSayHiResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="ServerPortType">
<wsdl:operation name="RegisterCallback">
<wsdl:input message="tns:register_callback"
name="RegisterCallbackRequest"/>
<wsdl:output message="tns:returnMessage"
name="RegisterCallbackResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CallbackPortType_SOAPBinding"
type="tns:CallbackPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/
soap/http"/>
<wsdl:operation name="ServerSayHi">
<soap:operation soapAction="" style="document"/>
<wsdl:input>
<soap:header message="tns:ServerSayHiRequest" part="xHeader"
use="literal" />
<soap:body parts="return_message" use="literal" />
</wsdl:input>
<wsdl:output name="ServerSayHiResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="ServerPortType_SOAPBinding"
type="tns:ServerPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/
soap/http"/>
<wsdl:operation name="RegisterCallback">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="RegisterCallbackRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="RegisterCallbackResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CallbackService">
<wsdl:port binding="tns:CallbackPortType_SOAPBinding"
name="CallbackPort">
<soap:address location="http://localhost:9005/CallbackContext/
CallbackPort"/>
</wsdl:port>
</wsdl:service>
<wsdl:service name="SOAPService">
<wsdl:port binding="tns:ServerPortType_SOAPBinding" name="SOAPPort">
<soap:address location="http://localhost:9000/SoapContext/
SoapPort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>


我的本意是通过头中的VERSION信息来区分不同的服务
下面是截取器的代码:
public class MediatorInInterceptor extends
AbstractEndpointSelectionInterceptor {

public MediatorInInterceptor() {
super(Phase.POST_STREAM);
addBefore(StaxInInterceptor.class.getName());
}

@Override
protected Endpoint selectEndpoint(Message message, Set<Endpoint>
eps) {

InputStream is =
message.getContent(InputStream.class);
if (is == null) {
return null;
}
try {
CachedOutputStream bos = new CachedOutputStream(4096);
IOUtils.copy(is, bos);
is.close();
message.setContent(InputStream.class,
bos.getInputStream());
String encoding = (String)message.get(Message.ENCODING);
XMLStreamReader xsr;
xsr =
StaxInInterceptor.getXMLInputFactory(message).createXMLStreamReader(bos.getInputStream(),
encoding);
while (true) {
xsr.nextTag();
if ("version".equals(xsr.getName().getLocalPart())) {
break;
}
}
String version = xsr.getElementText();
for (Endpoint ep : eps) {
if(version != null){
if (version.equals(ep.get("CallBackID"))) {
System.out.println("version from server: " + version);
return ep;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

我想知道为什么回有上面那种奇怪的错误?

willem

unread,
Apr 24, 2008, 8:37:48 AM4/24/08
to cxf-zh
WSDL的问题还没有看(得请做tool的兄弟看看了),就看了MediatorInInterceptor 的问题。
在AbstractEndpointSelectionInterceptor[1] 的 handleMessage 代码如下

public void handleMessage(Message message) throws Fault {
Exchange ex = message.getExchange();
Set<Endpoint> endpoints =
CastUtils.cast((Set)ex.get(MultipleEndpointObserver.ENDPOINTS));

Endpoint ep = selectEndpoint(message, endpoints);

if (ep == null) {
return;
}

......
}

在没有找到Endpoint之后就直接返回了,照理说在这里只要throw 一个SoapFault就可以把错误信息返回了。
但是由于没有找到正确的endpoint,没法获得FaultObserver 这样的客户端发过来的消息就有去无回了。
建议你还是在CXF JIRA[2]上面报一个bug吧, CXF 2.0.x 和 2.1 都有这个bug。

[1]https://svn.apache.org/repos/asf/incubator/cxf/trunk/rt/core/src/
main/java/org/apache/cxf/interceptor/
AbstractEndpointSelectionInterceptor.java
[2]https://issues.apache.org/jira/browse/CXF

姜宁 (Willem)
--------------------------------
http://willem.bokeland.com


SkyTiger

unread,
Apr 24, 2008, 11:53:09 PM4/24/08
to cxf-zh
提了!
Reply all
Reply to author
Forward
0 new messages