【问题标题】:saaj exception - Unable to parse content type: nullsaaj 异常 - 无法解析内容类型:null
【发布时间】:2012-10-24 08:36:24
【问题描述】:

我对 web 服务还很陌生,并且正在研究发送和接收附件(二进制文件)的 SAAJ 示例。我可以在客户端发送文件时让它工作,但在它请求它时不能。我在客户端遇到异常:
错误:“序言中不允许内容。” 2012 年 10 月 24 日 13:59:28 com.sun.xml.internal.messaging.saaj.soap.EnvelopeFactory createEnvelope 严重:SAAJ0511:无法从给定源创建信封 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:无法从给定源创建信封

有人有什么想法吗???我的客户端代码如下:

SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection con = scf.createConnection();
SOAPFactory soapFactory = SOAPFactory.newInstance();
MessageFactory mf = MessageFactory.newInstance();

SOAPMessage msg = mf.createMessage();
SOAPHeader header = msg.getSOAPHeader();
header.detachNode();

SOAPBody body = msg.getSOAPBody();
Name bodyName = soapFactory.createName(
"remoteOpen", "remoteOpen", 
"http://schemas.remoteOpen.com/remoteOpen");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
SOAPElement projectName = bodyElement.addChildElement("projectName");
projectName.addTextNode("filename");

msg.saveChanges();

// create the endpoint and send the message
URL endpoint = new URL("http://localhost:8080/RemoteSaveProject/OpenServlet");
SOAPMessage response = con.call(msg, endpoint);
con.close();

SOAPBody responseBody = response.getSOAPBody();
SOAPElement ackElem = (SOAPElement)responseBody.getFirstChild();
String acknowledgement = ackElem.getValue();

服务器代码如下所示:

MimeHeaders mimeHeaders = new MimeHeaders();
Enumeration en = request.getHeaderNames();
while (en.hasMoreElements()) 
{
     String headerName = (String)en.nextElement();
     String headerVal = request.getHeader(headerName);
     StringTokenizer tk = new StringTokenizer(headerVal, ",");
     while (tk.hasMoreTokens()){
          mimeHeaders.addHeader(headerName, tk.nextToken().trim());
     }
}
SOAPMessage message = mf.createMessage(mimeHeaders, request.getInputStream());
SOAPBody body = message.getSOAPBody();

Name bodyName = soapFactory.createName(
                "remoteOpen", "remoteOpen", 
                "http://schemas.remoteOpen.com/remoteOpen");

        Iterator projects = body.getChildElements(bodyName);
        SOAPElement project = (SOAPElement)projects.next();
        Iterator projectNameIter = project.getChildElements(soapFactory.createName("projectName"));
        SOAPElement projectNameEle = (SOAPElement)projectNameIter.next();
        String projectName = projectNameEle.getValue();
        File file = new File(projectName);

        SOAPMessage reply = mf.createMessage();
        SOAPHeader header = reply.getSOAPHeader();
        header.detachNode();
        SOAPBody replyBody = reply.getSOAPBody();
        SOAPBodyElement bodyElement = replyBody.addBodyElement(soapFactory.createName("ack"));
        bodyElement.addTextNode("OK");

        DataHandler dh = new DataHandler(new FileDataSource(file));
        AttachmentPart attachment = reply.createAttachmentPart(dh);
        attachment.setContentId("123");
        reply.addAttachmentPart(attachment);
        reply.saveChanges();

        response.setStatus(HttpServletResponse.SC_OK);
        putHeaders(reply.getMimeHeaders(), response);

        response.setContentType("text/xml");
        ServletOutputStream replyOS = response.getOutputStream();
        reply.writeTo(replyOS);
        replyOS.flush();
        replyOS.close();  

putHeaders 看起来像:

Iterator it = headers.getAllHeaders();

    while (it.hasNext()) 
    {
        MimeHeader header = (MimeHeader) it.next();
        String[] values = headers.getHeader(header.getName());

        if (values.length == 1) 
        {
            res.setHeader( header.getName(), header.getValue());
        } 
        else 
        {
            StringBuffer concat = new StringBuffer();
            int i = 0;

            while (i < values.length) 
            {
                if (i != 0)
                {
                    concat.append(',');
                }
                concat.append(values[i++]);
            }
            res.setHeader(header.getName(), concat.toString());
        }
    }

【问题讨论】:

  • 您是否发布了正确的客户端代码?哪一行抛出错误 (SOAPMessage response = con.call(msg, endpoint);)?
  • 它是正确的客户端代码,虽然它看起来像是来自服务器端......它发生在:SOAPMessage response = con.call(msg, endpoint);
  • 如果在该行上抛出错误,则意味着服务器收到了请求,处理了它并返回了响应。该错误表明服务器返回的数据/消息不是预期的格式。尝试通过 telnet 连接到服务器并检查响应 - 它的格式是否正确,是否包含您期望的所有信息?
  • 这是有道理的,当我添加一行将内容类型设置为 application/octet-stream 时,它再次爆炸,但显示不同的消息:SEVERE: SAAJ0537: Invalid Content-Type。可能是错误消息而不是 SOAP 消息
  • 是否有任何关于 servlet 将二进制文件附加到 SOAP 回复的示例?

标签: web-services saaj


【解决方案1】:

如果您像我一样使用 Google 应用引擎,问题是 GAE 不支持 com.sun.xml.internal.messaging.saaj.packaging.mime.internet.ParameterList,它在 javax.xml.soap.SOAPConnection.call() 的调用链内部某处使用。所以你必须使用一种解决方法。

我个人是通过使用java.net.HttpURLConnection 而不是javax.xml.soap.SOAPConnection 并手动发送和解析 SOAP 消息来实现的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-24
    • 2023-02-04
    • 1970-01-01
    • 2018-11-11
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多