cxf对List型参数的解析问题

48 views
Skip to first unread message

zeng bo

unread,
Sep 27, 2007, 12:01:26 AM9/27/07
to cxf-zh
我有这样一个service,他的方法中带有一个List型的参数:
@WebService
public interface HelloWorld {
String sayHi(String from, List<String> to);
}
用cxf导出之后,当我用Flex给它发送下边的soap包时,cxf就会报错。
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<tns:sayHi xmlns:tns="http://spring.demo/">
<arg0>HelloKitty</arg0>
<arg1>snoopy</arg1>
</tns:sayHi>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

exception如下:
2007/09/27 11:51:17 org.apache.cxf.phase.PhaseInterceptorChain
doIntercept
情報: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Unmarshalling Error : Current state
not START_ELEMENT or END_ELEMENT
at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshallArray(JAXBEncoderDecoder.java:
476)
at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:
280)
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:40)
at
org.apache.cxf.interceptor.DocLiteralInInterceptor.getPara(DocLiteralInInterceptor.java:
233)
at
org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:
119)
at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:
207)
at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:
73)
at
org.apache.cxf.transport.servlet.ServletDestination.doMessage(ServletDestination.java:
79)
at
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:
235)
at
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:
140)
at org.apache.cxf.transport.servlet.CXFServlet.invoke(CXFServlet.java:
278)
at org.apache.cxf.transport.servlet.CXFServlet.doPost(CXFServlet.java:
256)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
290)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
206)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
233)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
175)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
128)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
102)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
109)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
263)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:
844)
at org.apache.coyote.http11.Http11Protocol
$Http11ConnectionHandler.process(Http11Protocol.java:584)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:
447)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IllegalStateException: Current state not
START_ELEMENT or END_ELEMENT
at com.ctc.wstx.sr.BasicStreamReader.getName(BasicStreamReader.java:
721)
at
org.apache.cxf.staxutils.DepthXMLStreamReader.getName(DepthXMLStreamReader.java:
109)
at
org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshallArray(JAXBEncoderDecoder.java:
459)
... 25 more

貌似是cxf不能正确取得List型参数的值。
但是用cxf写的客户端程序访问的时候是没有问题的。
难道是flex生成的soap消息有问题么?

另:如何查看cxf接收到的soap消息的字符串呢?

maomao

unread,
Sep 27, 2007, 12:06:48 AM9/27/07
to cxf-zh
虽然是英文的,但这个页面给你了一些如何debug的技巧,以及工具
http://cwiki.apache.org/CXF20DOC/debugging.html

此外,如果cxf的client 和server可以互通,那肯定就是flex的问题了,
你可以到他们的论坛上看看,他们对list的支持是否有问题, 或者g一下

zeng bo

unread,
Sep 27, 2007, 12:42:37 AM9/27/07
to cxf-zh
但是我以前用的是XFire,它是可以正确解析flex传递过来的soap消息的......
:(

On Sep 27, 12:06 pm, maomao <maoma...@gmail.com> wrote:
> 虽然是英文的,但这个页面给你了一些如何debug的技巧,以及工具http://cwiki.apache.org/CXF20DOC/debugging.html

Willem Jiang

unread,
Sep 27, 2007, 12:52:11 AM9/27/07
to cxf...@googlegroups.com
你的CXF用的是什么版本。
有没有试过新发布的2.0.2 版本?

zeng bo

unread,
Sep 27, 2007, 2:00:31 AM9/27/07
to cxf-zh
呵呵,我用的就是最新的2.0.2啊。
今天刚下的。

WSMonitor在我的机器上不能正常运行,报org.xml.sax.SAXParseException: Premature end of
file.。
可能是因为jdk6的原因。
正在下载SOAP UI。
想看看CXF自己生成的SOAP消息长啥样。。。

On Sep 27, 12:52 pm, Willem Jiang <willem.ji...@gmail.com> wrote:
> 你的CXF用的是什么版本。
> 有没有试过新发布的2.0.2 版本?

zeng bo

unread,
Sep 27, 2007, 2:27:01 AM9/27/07
to cxf-zh
CXF生成的SOAP消息是:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sayHi xmlns:ns1="http://spring.demo/">

<arg0>HelloKitty</arg0>
<arg1>snoopy</arg1>
</ns1:sayHi>
</soap:Body>
</soap:Envelope>

Flex生成的SOAP消息是:


<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<tns:sayHi xmlns:tns="http://spring.demo/">
<arg0>HelloKitty</arg0>
<arg1>snoopy</arg1>
</tns:sayHi>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

没看出有什么区别啊,T_T

zeng bo

unread,
Sep 27, 2007, 2:29:53 AM9/27/07
to cxf-zh
CXF用的是http POST,Flex用的是http GET,跟这个有关系么?

willem

unread,
Sep 27, 2007, 2:41:44 AM9/27/07
to cxf-zh
HTTP Get 和 HTTP Post 走的流程有点不一样, 如果是Get方法会走到 URIMappingInterceptor ,
这个Interceptor会尝试从URI中解析出Operation的参数和其他相关信息。

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

zeng bo

unread,
Sep 27, 2007, 3:10:24 AM9/27/07
to cxf-zh
可是如果没有List类型的参数的话,flex的http GET方式也能成功......

zeng bo

unread,
Sep 27, 2007, 3:15:39 AM9/27/07
to cxf-zh
不好意思,搞错了,Flex取得wsdl的时候用的是get,访问webservice的时候使用是post。
跟CXF一样的。

看来还是SOAP消息解析上的问题。
这两个SOAP消息有什么不一样呢?
:(

zeng bo

unread,
Sep 27, 2007, 4:29:57 AM9/27/07
to cxf-zh
跟踪了一下,好像是在读取了List的数据,在判断List是否结束的时候
(org.apache.cxf.jaxb.JAXBEncoderDecoder)出了问题:
459 while (reader.getName().equals(elName)) {
460 Object obj = u.unmarshal(reader, clazz);
461 if (obj instanceof JAXBElement) {
462 obj = ((JAXBElement)obj).getValue();
463 }
464 ret.add(obj);
465 }

当取得了List的值之后,再次调用reader.getName()时,CXF生成的SOAP消息能顺利通过,而Flex生成的SOAP消息则会报告
错误。
不知道是为什么。。。
:(

Freeman Fang

unread,
Sep 27, 2007, 11:16:14 PM9/27/07
to cxf...@googlegroups.com
Hi,

You can add LoggingIn/OutInterceptor to print out messages you receive
or send.

I assume you are using jax-ws api to publish endpoint, so what you need
do is

EndpointImpl ep = (EndpointImpl) Endpoint.publish("http://localhost/service", service);

ep.getServer().getEndpoint().getInInterceptors().add(new LoggingInInterceptor());
ep.getServer().getEndpoint().getOutInterceptors().add(new LoggingOutInterceptor());

Best Regards

Freeman

zeng bo

unread,
Oct 9, 2007, 3:40:36 AM10/9/07
to cxf-zh
thank you.

On 9月28日, 午前11:16, Freeman Fang <freeman.f...@gmail.com> wrote:
> Hi,

Reply all
Reply to author
Forward
0 new messages