0

我正在使用 Spring 3.1.1 和他们的 OXM 东西,使用 RestTemplate 将请求发布到另一台服务器。我正在使用一个名为 ClassTermCollection 的类作为它的请求和响应端,并且它使用 @XmlRootElement 等进行了注释,并且一直到今天都可以正常工作。但是,当 JAXB 尝试创建请求时,突然出现以下错误(即,在对服务器进行 http 调用之前,在客户端引发了此错误)。

谷歌几乎没有透露任何关于这个特定错误的有用信息,而且 - 更糟糕的是 - Sun 显然没有将源代码发送到抛出异常的类,使用 JDK ......所以我什至无法一直调试对此的根源,以准确确定正在发生的事情。

编辑:(参见stacktrace下面的附加评论)

[错误] org.springframework.http.converter.HttpMessageNotWritableException:无法写入 [pmt.model.collections.ClassTermCollection@6576fac];嵌套异常是 org.springframework.oxm.MarshallingFailureException: JAXB 编组异常;嵌套异常是 javax.xml.bind.MarshalException: org.springframework.http.converter.xml.MarshallingHttpMessageConverter.writeToResult(MarshallingHttpMessageConverter.java:134) [ERROR] at unsupported javax.xml.parser.transform.Result parameter [ERROR] at org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter.writeInternal(AbstractXmlHttpMessageConverter.java:66) [错误] 在 org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:179) [错误] 在 org.springframework。网络客户端。HttpConnection.handleRequest(HttpConnection.java:505) [错误] 在 org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843) [错误] 在 org.mortbay.jetty.HttpParser.parseNext(HttpParser.java: 647)[错误]在org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:205)[错误]在org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)[错误]在org.mortbay。 io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395) [ERROR] at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488) [ERROR] 原因:org.springframework.oxm.MarshallingFailureException: JAXB 编组异常;嵌套异常是 javax.xml.bind.MarshalException: org.springframework.oxm.jaxb 中不支持的 javax.xml.parser.transform.Result 参数 [ERROR]。

好的,在网上找到了 com.sun.xml.internal.bind.v2.runtime.MarshallerImpl 的源代码1,现在我看到(有点)发生了什么。该代码查看 Result 实例,如果它是 StreamResult(在我的情况下),它会尝试取消引用 StreamResult 的 outputstream、writer 和 systemId 字段,并使用这些值来构造 Writer。如果它们都为空,它会落入方法的底部并抛出“不支持的格式”异常,这就是发生在这里。

在此之上,在 Spring org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter 类中,我们到达构造 StreamResult 的这一行,将 outputMessage.getBody() 的结果传递给 StreamResult 构造函数。我在这里得到空值,因此问题从下面冒出来。

@Override protected final void writeInternal(T t, HttpOutputMessage outputMessage) throws IOException { writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody())); }

解决了

得到这个工作......我忘记了它原来是什么的所有细节;但这基本上是一个疯狂的情况,一个同事添加了一些子类化 HttpClient 类的代码,而他的类没有完全履行接口的约定,当被我的代码调用时,它导致了这个错误。这是看起来像 JAXB 错误的奇怪情况之一,但事实证明它与 JAXB 完全无关。

4

2 回答 2

4

您的问题是,当您实例化 StreamResult 时,您必须为其提供一种存储将写入其中的数据的方法。您应该按照以下方式做一些事情:

StreamResult res=new StreamResult(new ByteArrayOutputStream());

ByteArrayOutputStream 将根据需要增长。

于 2012-07-04T20:32:51.660 回答
1

查看 Spring 的源代码,Marshaller 抱怨它不支持 StreamResult 对象。它绝对支持这个对象,但是您可能遇到的是一个类加载问题,其中使用了从错误的 JAR 或由错误的类加载器加载的 StreamResult。

于 2012-05-03T08:32:51.103 回答