View Javadoc

1   /*
2    * Copyright 2007 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.transport.http;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.util.Iterator;
23  import java.util.zip.GZIPInputStream;
24  
25  import org.springframework.util.FileCopyUtils;
26  import org.springframework.util.StringUtils;
27  import org.springframework.ws.transport.AbstractSenderConnection;
28  import org.springframework.ws.transport.FaultAwareWebServiceConnection;
29  import org.springframework.ws.transport.WebServiceConnection;
30  
31  /**
32   * Abstract base class for {@link WebServiceConnection} implementations that send request over HTTP.
33   *
34   * @author Arjen Poutsma
35   * @since 1.0.0
36   */
37  public abstract class AbstractHttpSenderConnection extends AbstractSenderConnection
38          implements FaultAwareWebServiceConnection {
39  
40      /** Buffer used for reading the response, when the content length is invalid. */
41      private byte[] responseBuffer;
42  
43      public final boolean hasError() throws IOException {
44          return getResponseCode() / 100 != 2;
45      }
46  
47      public final String getErrorMessage() throws IOException {
48          StringBuffer buffer = new StringBuffer();
49          String responseMessage = getResponseMessage();
50          if (StringUtils.hasLength(responseMessage)) {
51              buffer.append(responseMessage);
52          }
53          buffer.append(" [");
54          buffer.append(getResponseCode());
55          buffer.append(']');
56          return buffer.toString();
57      }
58  
59      /*
60       * Receiving response
61       */
62      protected final boolean hasResponse() throws IOException {
63          int responseCode = getResponseCode();
64          if (HttpTransportConstants.STATUS_ACCEPTED == responseCode ||
65                  HttpTransportConstants.STATUS_NO_CONTENT == responseCode) {
66              return false;
67          }
68          long contentLength = getResponseContentLength();
69          if (contentLength < 0) {
70              if (responseBuffer == null) {
71                  responseBuffer = FileCopyUtils.copyToByteArray(getRawResponseInputStream());
72              }
73              contentLength = responseBuffer.length;
74          }
75          return contentLength > 0;
76      }
77  
78      protected final InputStream getResponseInputStream() throws IOException {
79          InputStream inputStream;
80          if (responseBuffer != null) {
81              inputStream = new ByteArrayInputStream(responseBuffer);
82          }
83          else {
84              inputStream = getRawResponseInputStream();
85          }
86          return isGzipResponse() ? new GZIPInputStream(inputStream) : inputStream;
87      }
88  
89      /** Determine whether the response is a GZIP response. */
90      private boolean isGzipResponse() throws IOException {
91          Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_ENCODING);
92          if (iterator.hasNext()) {
93              String encodingHeader = (String) iterator.next();
94              return encodingHeader.toLowerCase().indexOf(HttpTransportConstants.CONTENT_ENCODING_GZIP) != -1;
95          }
96          return false;
97      }
98  
99      /** Returns the HTTP status code of the response. */
100     protected abstract int getResponseCode() throws IOException;
101 
102     /** Returns the HTTP status message of the response. */
103     protected abstract String getResponseMessage() throws IOException;
104 
105     /** Returns the length of the response. */
106     protected abstract long getResponseContentLength() throws IOException;
107 
108     /** Returns the raw, possibly compressed input stream to read the response from. */
109     protected abstract InputStream getRawResponseInputStream() throws IOException;
110 
111     /*
112      * Faults
113      */
114 
115     public final boolean hasFault() throws IOException {
116         return HttpTransportConstants.STATUS_INTERNAL_SERVER_ERROR == getResponseCode() && isXmlResponse();
117     }
118 
119     /** Determine whether the response is a XML message. */
120     private boolean isXmlResponse() throws IOException {
121         Iterator iterator = getResponseHeaders(HttpTransportConstants.HEADER_CONTENT_TYPE);
122         if (iterator.hasNext()) {
123             String contentType = ((String) iterator.next()).toLowerCase();
124             return contentType.indexOf("xml") != -1;
125         }
126         return false;
127     }
128 
129     public final void setFault(boolean fault) {
130     }
131 
132 }