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.ByteArrayOutputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.net.URI;
24  import java.net.URISyntaxException;
25  import java.util.Arrays;
26  import java.util.Iterator;
27  
28  import org.apache.commons.httpclient.Header;
29  import org.apache.commons.httpclient.HttpClient;
30  import org.apache.commons.httpclient.URIException;
31  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
32  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
33  import org.apache.commons.httpclient.methods.PostMethod;
34  
35  import org.springframework.util.Assert;
36  import org.springframework.ws.WebServiceMessage;
37  import org.springframework.ws.transport.WebServiceConnection;
38  
39  /**
40   * Implementation of {@link WebServiceConnection} that is based on Jakarta Commons HttpClient. Exposes a {@link
41   * PostMethod}.
42   *
43   * @author Arjen Poutsma
44   * @since 1.0.0
45   */
46  public class CommonsHttpConnection extends AbstractHttpSenderConnection {
47  
48      private final HttpClient httpClient;
49  
50      private final PostMethod postMethod;
51  
52      private ByteArrayOutputStream requestBuffer;
53  
54      private MultiThreadedHttpConnectionManager connectionManager;
55  
56      protected CommonsHttpConnection(HttpClient httpClient, PostMethod postMethod) {
57          Assert.notNull(httpClient, "httpClient must not be null");
58          Assert.notNull(postMethod, "postMethod must not be null");
59          this.httpClient = httpClient;
60          this.postMethod = postMethod;
61      }
62  
63      public PostMethod getPostMethod() {
64          return postMethod;
65      }
66  
67      public void onClose() throws IOException {
68          postMethod.releaseConnection();
69          if (connectionManager != null) {
70              connectionManager.shutdown();
71          }
72      }
73  
74      /*
75       * URI
76       */
77  
78      public URI getUri() throws URISyntaxException {
79          try {
80              return new URI(postMethod.getURI().toString());
81          }
82          catch (URIException ex) {
83              throw new URISyntaxException("", ex.getMessage());
84          }
85      }
86  
87      /*
88       * Sending request
89       */
90  
91      protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
92          requestBuffer = new ByteArrayOutputStream();
93      }
94  
95      protected void addRequestHeader(String name, String value) throws IOException {
96          postMethod.addRequestHeader(name, value);
97      }
98  
99      protected OutputStream getRequestOutputStream() throws IOException {
100         return requestBuffer;
101     }
102 
103     protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
104         postMethod.setRequestEntity(new ByteArrayRequestEntity(requestBuffer.toByteArray()));
105         requestBuffer = null;
106         try {
107             httpClient.executeMethod(postMethod);
108         } catch (IllegalStateException ex) {
109             if ("Connection factory has been shutdown.".equals(ex.getMessage())) {
110                 // The application context has been closed, resulting in a connection factory shutdown and an ISE.
111                 // Let's create a new connection factory for this connection only.
112                 connectionManager = new MultiThreadedHttpConnectionManager();
113                 httpClient.setHttpConnectionManager(connectionManager);
114                 httpClient.executeMethod(postMethod);
115             } else {
116                 throw ex;
117             }
118         }
119     }
120 
121     /*
122      * Receiving response
123      */
124 
125     protected int getResponseCode() throws IOException {
126         return postMethod.getStatusCode();
127     }
128 
129     protected String getResponseMessage() throws IOException {
130         return postMethod.getStatusText();
131     }
132 
133     protected long getResponseContentLength() throws IOException {
134         return postMethod.getResponseContentLength();
135     }
136 
137     protected InputStream getRawResponseInputStream() throws IOException {
138         return postMethod.getResponseBodyAsStream();
139     }
140 
141     protected Iterator getResponseHeaderNames() throws IOException {
142         Header[] headers = postMethod.getResponseHeaders();
143         String[] names = new String[headers.length];
144         for (int i = 0; i < headers.length; i++) {
145             names[i] = headers[i].getName();
146         }
147         return Arrays.asList(names).iterator();
148     }
149 
150     protected Iterator getResponseHeaders(String name) throws IOException {
151         Header[] headers = postMethod.getResponseHeaders(name);
152         String[] values = new String[headers.length];
153         for (int i = 0; i < headers.length; i++) {
154             values[i] = headers[i].getValue();
155         }
156         return Arrays.asList(values).iterator();
157     }
158 
159 }