SOAPConnection不处理gzip响应

时间:2011-07-05 03:01:03

标签: web-services soap gzip

我正在使用SOAPConnection来调用基于SOAP的Web服务。请求通过标头中的“Accept-Encoding:gzip,deflate”发送。 我使用fiddler来获取响应,它被压缩,但在反序列化消息时,SOAPConnection发出错误消息“无效的utf-8”消息。

我尝试了正常的http帖子,http响应能够正确解压缩响应。我是否需要在SOAPConnection上设置一些属性以使其处理gzip消息?

4 个答案:

答案 0 :(得分:1)

我发现这个片段正在完成这项工作

        SOAPMessage response = conn.call(finalRequest, aUrl);

        // The response is gzip encoded, so decompress the response.
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.writeTo(out);
        byte[] barr = out.toByteArray();
        InputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(barr));
        Reader decoder = new InputStreamReader(gzipStream, "UTF-8");
        BufferedReader buffered = new BufferedReader(decoder);
        int n = 0;
        char[] cbuf = new char[1024];
        Writer w = new StringWriter();
        while ((n = buffered.read(cbuf)) != -1) {
            w.write(cbuf,0,n);
        }
        // the writer now contains unzipped message.
        System.out.println(w.toString());

答案 1 :(得分:0)

你看到了吗?

SOAPMessage - SOAPConnection - gzip - how to

此外,如果您使用AXIS2,它具有内置功能,可以使用MTOM压缩base64编码的二进制内容:

http://axis.apache.org/axis2/java/core/docs/mtom-guide.html

答案 2 :(得分:0)

只需完成该片段 - 如果您想使用解压缩的SOAPMessage,则需要将其加载到新消息中。

SOAPMessage responseCompressed = connection.call(reqMessage, endpoint);
ByteArrayOutputStream out = new ByteArrayOutputStream();
responseCompressed.writeTo(out);
byte[] barr = out.toByteArray();
InputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(barr));

这是神奇的线条

SOAPMessage response = factory.createMessage(responseCompressed.getMimeHeaders(), gzipStream);

工厂是您的MessageFactory。

现在响应将像没有gzip标头一样运行。你只需将它放入。

答案 3 :(得分:0)

GZIP请求,服务器形式的响应:

如果服务器启用了GZip,则服务器发送gzip-compress文本数据。为此,我们需要一个带有Http标头的请求:

  • 请求:我们必须发送包含 Accept-Encoding: gzip 标头的HTTP请求。
  • 响应:如果启用了gzip,则服务器应返回 Content-Encoding: gzip 标头。

Soap WebServies:

使用SOAPConnectiona请求WebService并获取response in GZIP compressed格式:

public static String getGZIP(byte[] zipBytes) {
    try {
        GZIPInputStream gzipInput = new GZIPInputStream( new ByteArrayInputStream(zipBytes) );
        return IOUtils.toString(gzipInput);
    } catch (IOException e) {
        throw new UncheckedIOException("Error while decompression!", e);
    }
}
public static void getSOAPConnection(SOAPMessage soapMsg) throws Exception {
    System.out.println("\n===== SOAPConnection =====");
    
    MimeHeaders headers = soapMsg.getMimeHeaders();
    headers.addHeader("SoapBinding", serverDetails.get("SoapBinding") );
    headers.addHeader("MethodName", serverDetails.get("MethodName") );
    headers.addHeader("SOAPAction", serverDetails.get("SOAPAction") );
    headers.addHeader("Content-Type", serverDetails.get("Content-Type")); // InBound
    headers.addHeader("Accept-Encoding", serverDetails.get("Accept-Encoding")); // OutBound

    if (soapMsg.saveRequired()) soapMsg.saveChanges();
     
    /*SOAPMessage message = MessageFactory.newInstance().createMessage(headers, new ByteArrayInputStream(TSOXML.getBytes()));*/
    SOAPConnectionFactory newInstance = SOAPConnectionFactory.newInstance();
    javax.xml.soap.SOAPConnection connection = newInstance.createConnection();

    SOAPMessage resp = connection.call(soapMsg, getURL( serverDetails.get("SoapServerURI") ));
    MimeHeaders mimeHeaders = resp.getMimeHeaders();
    String[] header = mimeHeaders.getHeader("Content-Encoding");
    String contentEoncoding = "";
    if (header != null && header.length > 0) contentEoncoding = header[0].toString();
    System.out.println("Content:"+contentEoncoding);

    if (contentEoncoding.equalsIgnoreCase("GZIP")) {
        System.out.println("SOAP Message in GZIP");

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        resp.writeTo(out);
        byte[] zipBytes = out.toByteArray();
        String gZipString= getGZIP(zipBytes);
        System.out.println("Response:"+ gZipString);

        SOAPMessage soapMessage = getSOAPMessagefromDataXML(gZipString);
        System.out.println("SOAP Message Object:\n"+soapMessage);

        getSOAPXMLasString(soapMessage);
    } else {
        getSOAPXMLasString(resp);
    }
}

使用HTTPCline请求SOAP WS。 SOAPUI请求的方式:

public static void getHttpURLConnection_Core(SOAPMessage soapMsg) throws Exception {
    System.out.println("\n===== java.net.HttpURLConnection =====");
    
    URL url = new URL(null, serverDetails.get("SoapServerURI"));
    String protocol = url.getProtocol();
    System.out.println("Protocol: "+protocol);
    
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT));
    
    HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
    connection.setReadTimeout(5 * 1000);
    connection.setConnectTimeout(5 * 1000);
    connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(true);
    
    //String authString = username + ":" + password; // Authorization: Basic ZW9uMDE5XzAxOkVsaWFfMTIz
    //String authMsg = "Basic " + Base64.encode(authString.getBytes());
    //connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.AUTHORIZATION, authMsg);
    ((HttpURLConnection) connection).setRequestMethod("POST");
    
    connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.ACCEPT, "text/xml");
    connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.9");
    
    connection.setRequestProperty("MethodName", serverDetails.get("MethodName") );
    connection.setRequestProperty("SOAPAction", serverDetails.get("SOAPAction") );

    connection.setRequestProperty("HTTP_ACCEPT_ENCODING", "gzip, deflate, br");
    connection.setRequestProperty("Accept-Encoding", serverDetails.get("Accept-Encoding"));

    String soapxmLasString = getSOAPXMLasString(soapMsg);
    connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE, "text/xml");// serverDetails.get("Content-Type")
    connection.setRequestProperty( "Content-Length", String.valueOf(soapxmLasString.length()));
    
    DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
    try {
        dataOutputStream.writeBytes(soapxmLasString);
    } finally {
        dataOutputStream.close();
    }
    
    long start = System.currentTimeMillis();
    
    long end = System.currentTimeMillis();
    String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
    System.out.println("TIme taken Date:"+date+", Time:"+ (end-start));
    String contentEncoding = connection.getContentEncoding();
    System.out.println("Encoding:"+ contentEncoding);
    
    int responseCode = connection.getResponseCode();
    String responseMessage = connection.getResponseMessage();
    
    System.out.println("Response Code: " + responseCode + " " + responseMessage);
    
    String xmlRply = null ;
    String requestStatus = "Fail";
    if (responseCode == HttpURLConnection.HTTP_OK) {
        requestStatus = "Pass";
        
        InputStream inputStream = connection.getInputStream();
        xmlRply = getStreamContent(inputStream, contentEncoding);
    } else { // Response Code: 500 Internal Server Error
        InputStream errorStream = connection.getErrorStream();
        xmlRply = getStreamContent(errorStream, contentEncoding);
    }
    System.out.println("Reply: " + xmlRply);
    System.out.println("Request Status:"+ requestStatus);
}
public static String getStreamContent(InputStream input, String encoding) throws IOException {
    byte[] httpRply;
    String rply;
    httpRply = IOUtils.toByteArray(input);
    System.out.println("Byte Array:"+httpRply.toString());
    if (encoding == null) {
        rply = new String(httpRply);
    } else if ( encoding.equalsIgnoreCase("GZIP") ) {
        rply = getGZIP(httpRply);
    } else { // "ISO-8859-1", ";TF-8"
        rply = new String(httpRply, encoding);
    }
    return rply;
}

工作示例,其中服务器以GZIP格式响应。

public class SOAP_Weather {

    static final String PROXY_ADDRESS = "Proxy_*****.net";
    static final int PROXY_PORT = 9400;
    
    static HashMap<String, String> serverDetails = new HashMap<>();
    static {
        // https://graphical.weather.gov/xml/ : conus
        serverDetails.put("SoapServerURI", "https://graphical.weather.gov:443/xml/SOAP_server/ndfdXMLserver.php");
        serverDetails.put("SoapWSDL", "https://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl");
        serverDetails.put("SoapXML", "<ndf:CornerPoints xmlns:ndf=\"https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><sector xsi:type=\"xsd:string\">conus</sector></ndf:CornerPoints>");
        serverDetails.put("SoapBinding", "ndfdXMLBinding");
        serverDetails.put("MethodName", "CornerPoints");
        serverDetails.put("SOAPAction", "https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#CornerPoints");
        
        serverDetails.put("User-Agent", "Apache-HttpClient");
        serverDetails.put("Accept-Encoding", "gzip,deflate,sdch");
        serverDetails.put("Content-Type", "text/xml;charset=UTF-8");
    }
    public static void main(String[] args) throws Exception {
        callSoapService();
    }
    public static void callSoapService( ) throws Exception{
        String xmlData = serverDetails.get("SoapXML");
        
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        dbFactory.setIgnoringComments(true);
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
            Document docBody = dBuilder.parse(ips);
            //docBody.createElementNS(DSIG_NS, "ds");
            
        System.out.println("Data Document: "+docBody.getDocumentElement());
        
        // Protocol 1.1=SOAP-ENV Content-Type:text/xml; charset=utf-8, 1.2=env Content-Type:application/soap+xml; charset=utf-8
        MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        SOAPMessage soapMsg = messageFactory.createMessage();
        
        SOAPPart soapPart = soapMsg.getSOAPPart();
        SOAPEnvelope soapEnv = soapPart.getEnvelope();
        SOAPBody soapBody = soapEnv.getBody();
        
        soapBody.addDocument(docBody);
        
        // Invoke the webService.
        System.out.println("Request SOAP Message:");
        soapMsg.writeTo(System.out);
        System.out.println("\n");
        
        // Protocol 1.1=SOAP-ENV Content-Type:text/xml; charset=utf-8, 1.2=env Content-Type:application/soap+xml; charset=utf-8
        SOAPEnvelope envelope = soapMsg.getSOAPPart().getEnvelope();
        if (envelope.getElementQName().getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/envelope/")) {
            System.out.println("SOAP 1.1 NamespaceURI: http://schemas.xmlsoap.org/soap/envelope/");
            serverDetails.put("Content-Type", "text/xml; charset=utf-8");
        } else {
            System.out.println("SOAP 1.2 NamespaceURI: http://www.w3.org/2003/05/soap-envelope");
            serverDetails.put("Content-Type", "application/soap+xml; charset=utf-8");
        }
        getSOAPConnection(soapMsg); // Disadvantage 1:
        getHttpURLConnection_Core(soapMsg);
    }
    
    private static URL getURL(String endPointUrl) throws MalformedURLException {
        URL endpoint = new URL(null, endPointUrl, new URLStreamHandler() {
            protected URLConnection openConnection(URL url) throws IOException {
                URL clone = new URL(url.toString());
    
                URLConnection connection = null;
                if (PROXY_ADDRESS != null && PROXY_PORT != 0 ) { // https://stackoverflow.com/a/22533464/5081877
                    Socket socket = new Socket();
                    SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
                    socket.connect(sockaddr, 10000);
                    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(socket.getInetAddress(), PROXY_PORT));
                    if (proxy.address().toString().equals("0.0.0.0/0.0.0.0:80") || proxy.address().toString() != null) {
                        System.out.println("Connection through proxy ...");
                        connection = clone.openConnection(proxy);
                    } else {
                        connection = clone.openConnection();
                    }
                } else {
                    connection = clone.openConnection();
                }
                
                connection.setConnectTimeout(5 * 1000); // 5 sec
                connection.setReadTimeout(5 * 1000); // 5 sec
                return connection;
            }
        });
        return endpoint;
    }
    public static String getSOAPXMLasString(SOAPMessage soapMsg) throws SOAPException, IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        soapMsg.writeTo(out);
        // resp.writeTo(System.out);
        String strMsg = new String(out.toByteArray());
        System.out.println("Soap XML: "+ strMsg);
        return strMsg;
    }
    public static SOAPMessage getSOAPMessagefromDataXML(String saopBodyXML) throws Exception {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        dbFactory.setIgnoringComments(true);
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        InputSource ips = new org.xml.sax.InputSource(new StringReader(saopBodyXML));
        Document docBody = dBuilder.parse(ips);
        System.out.println("Data Document: "+docBody.getDocumentElement());
        
        MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        SOAPMessage soapMsg = messageFactory.createMessage();
        
        SOAPBody soapBody = soapMsg.getSOAPPart().getEnvelope().getBody();
        soapBody.addDocument(docBody);
        
        return soapMsg;
    }

    // SOPAConneciton and HTTPClien connection functions
}