SAAJ0537:无效的内容类型。可能是错误消息而不是 SOAP 消息

SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message

目前我正在实现一个用例,我应该在其中创建一个通过 HTTP 协议写入的 soap 客户端。 为了测试同一个用例,我启动了一个模拟服务 运行。现在,当我将我的 SAAJ 实现作为独立的 jar 执行时,我的应用程序运行良好并且没有任何问题。

我目前的问题是,当我将该代码合并到基于 spring 4 的应用程序并将其部署到 Jboss AS 7.1.1 上时,它给我一个错误,如下所示:

12:40:33,992 ERROR [stderr] (ActiveMQ Session Task-1) com.sun.xml.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?

12:40:33,994 ERROR [stderr] (ActiveMQ Session Task-1)   at com.sun.xml.messaging.saaj.soap.MessageImpl.identifyContentType(MessageImpl.java:670)

12:40:33,996 ERROR [stderr] (ActiveMQ Session Task-1)   at com.sun.xml.messaging.saaj.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:100)

12:40:33,997 ERROR [stderr] (ActiveMQ Session Task-1)   at com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:342)

12:40:33,999 ERROR [stderr] (ActiveMQ Session Task-1)   at com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:159)

最初我认为这是由于其他 spring 依赖项导致的问题,因为之前我一直在努力解决同样的问题但是这里不是这种情况,正如您在下面的 pom 条目中看到的那样,我删除了冲突 spring -boot-autoconfigure APIS 从我的 war 构建通过使它们可选。

我的 Maven 依赖项如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.saaj.client</groupId>
    <artifactId>notification</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>notification</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.1.6.RELEASE</spring.version><!-- 3.0.5.RELEASE 4.1.6.RELEASE -->
        <activemq.version>5.14.3</activemq.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>1.4.3.RELEASE</version>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test-autoconfigure</artifactId>
            <version>1.4.3.RELEASE</version>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-spring</artifactId>
            <version>${activemq.version}</version>
        </dependency>
        <!-- 
        <dependency>
            <groupId>com.sun.xml.messaging.saaj</groupId>
            <artifactId>saaj-impl</artifactId>
            <version>1.3</version>
        </dependency>
 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
            <optional>false</optional>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.6</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.6</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.6.3.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.3.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-commons-annotations</artifactId>
            <version>3.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.2.1</version>
        </dependency>
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>8.4-702.jdbc4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-configuration</groupId>
            <artifactId>commons-configuration</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.0.6</version>
        </dependency>

    </dependencies>

</project>

我的 SAAJ 实现如下:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.xml.sax.InputSource;

import com.saaj.client.constants.NotificationConstants;
import com.saaj.client.exception.CustomException;
import com.saaj.client.logger.LoggerManager;

@Component("adapterServiceHelper")
public class AdapterServiceHelper {

    private static Logger logger = LoggerManager.getInstance().getNotificationProcessingLogger();

    public AdapterServiceHelper(){

    }

    public URL getEndpointConnection(String url) throws MalformedURLException, CustomException{
        URL endpoint = null;

        try{
            endpoint = new URL (null, url, new URLStreamHandler () {
                protected URLConnection openConnection (URL url) throws IOException {
                    // The url is the parent of this stream handler, so must create clone
                    URL clone = new URL (url.toString ());
                    URLConnection connection = clone.openConnection ();
                    connection.setRequestProperty("Content-Type",
                            "text/xml");
                    connection.setRequestProperty("Accept",
                            "application/soap+xml, text/*");
                    // If we cast to HttpURLConnection, we can set redirects
                    // connection.setInstanceFollowRedirects (false);
                    connection.setConnectTimeout (5 * 1000);      // 15 sec
                    connection.setReadTimeout (5 * 1000);         // 15 sec
                    // Custom header
                    return connection;
                }});


        }catch(MalformedURLException e){
            throw e;
        }catch(Exception exp){
            exp.printStackTrace();
            throw new CustomException(exp.getMessage(),"Error occured while getting endpoint connection to IP");
        }
        return endpoint;
    }

    //main SAAJ implementation
    public SOAPMessage writeCommand(URL endpoint, String command) throws Exception{

        SOAPMessage soapResponse = null;
        SOAPConnection soapConnection = null;
        InputStream is = null;
        System.out.println("command written is "+command);
        try{
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory
                    .newInstance();
            soapConnection = soapConnectionFactory
                    .createConnection();

            //write to PG over soapConnection can be made generic
            is = new ByteArrayInputStream(command.getBytes());
            SOAPMessage request = MessageFactory.newInstance(
                    SOAPConstants.SOAP_1_1_PROTOCOL).createMessage(
                            new MimeHeaders(), is);

            MimeHeaders headers = request.getMimeHeaders();
            headers.addHeader("Content-Type", "text/xml");
            request.saveChanges();


            soapResponse = soapConnection.call(request, endpoint);
            //soapConnection.close();
            //is.close();
            //process soap response
            printSOAPResponse(soapResponse);
        }
        catch(SOAPException exp)
        {
            exp.printStackTrace();
            logger.error("ERROR while connecting SOAP service" + exp.getMessage());
            throw new Exception("ERROR : SOAPException encountered while writing ");
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("ERROR : SOAPException encountered while writing ");
        } catch (TransformerException e) {
            e.printStackTrace();
            throw new Exception("ERROR : SOAPException encountered while writing ");
        }
        finally{
            soapConnection.close();
            is.close();
        }
        return soapResponse;

    }


    public static void printSOAPResponse(SOAPMessage soapResponse) throws TransformerException, SOAPException {
        TransformerFactory transformerFactory = TransformerFactory
                .newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Source sourceContent = soapResponse.getSOAPPart().getContent();
        StreamResult result = new StreamResult(System.out);
        transformer.transform(sourceContent, result);
    }

}

如果对这个问题有任何建议,请告诉我。

我尝试使用基本的 java.net HTTP 连接来检查我得到的数据,发现我真的得到了模拟服务端口的 html 页面。(localhost:9997) 假设我的服务在 URL 上运行:“http://localhost:9997/mockSoapBinding” 所以我正在获取 URL 的数据:“http://localhost:9997” 而不是公开的 Web 服务。

为了检查是否相同,我使用了以下代码:

public String handleRequest(String method, String url, String xmlPayload,String readTimeout,String connectTimeout,String soapAction) throws IOException {
    HttpURLConnection connection = null;
    OutputStreamWriter wr = null;
    BufferedReader in = null;
    String result = "";

    try {
        URL connectionUrl = new URL(url);
        connection = (HttpURLConnection) connectionUrl.openConnection();
        connection.setRequestMethod(method);
        if ( xmlPayload != null && ! xmlPayload.equals("")) {
            connection.setReadTimeout(Integer.parseInt(readTimeout));
            connection.setConnectTimeout(Integer.parseInt(connectTimeout));
            connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
            /*connection.setRequestProperty("SOAPAction", soapAction);*/
            connection.setDoOutput(true);
            wr = new OutputStreamWriter(connection.getOutputStream());
            wr.write(xmlPayload);
            wr.flush();
        }
        try {
            // getInputStream will throw exception when response code is
            // greater than 400, so we need to getErrorStream
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } catch (Exception e) {
            in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
        }
        StringBuilder bodyBuilder = new StringBuilder();
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            bodyBuilder.append(inputLine);
        }
        in.close();
        result = String.valueOf( bodyBuilder.toString());
        System.out.println(result);

    } catch(Exception e){
        logger.error("Error occured while send message for : " , e);
            }finally {
        if (wr != null) {
            wr.close();
        }
        if (in != null) {
            in.close();
        }
        if ( connection != null ) {
            connection.disconnect();
        }

    }

    return result;
}

请注意,这也是 SAAJ 实施的替代方案。

我在 soap 信封中提供了错误的命名空间时收到了这条错误消息。这可能与接受的答案所描述的效果相同,即请求到达错误 URL.

我发现了一个依赖性问题。

POI 4.0.1 正常,5.0.0 失败,使用这个 pom.xml :

    </dependencies>
        <!-- @see  -->
        <!-- API, java.xml.bind module -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.2</version>
        </dependency>
        
        <!-- Runtime, com.sun.xml.bind module -->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
<!--            <version>5.0.0</version> -->
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
<!--            <version>5.0.0</version> -->
        </dependency>
    </dependencies>