这是在项目中运用HttpURLConnection发送post请求(我们项目中是用来发送soap),完整的处理,包括如何处理异常。需要注意一个小地方,我们把创建URL放在afterPropertiesSet方法中,是因为这个类只是为下游某一个特定的Service服务的,如果要作用共用的,不能这样做。

Java代码 复制代码 收藏代码
  1. import java.io.BufferedReader;
  2. import java.io.DataOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.net.ConnectException;
  7. import java.net.HttpURLConnection;
  8. import java.net.MalformedURLException;
  9. import java.net.SocketTimeoutException;
  10. import java.net.URL;
  11.  
  12. import org.apache.log4j.Level;
  13. import org.apache.log4j.Logger;
  14. import org.springframework.beans.factory.InitializingBean;
  15.  
  16. public class HttpClient implements InitializingBean
  17. {
  18. private static final String DEBUG_HTTP_RESULT = "Result of calling http service: ";
  19. private static final String ERROR_DEFAULT_HTTP = "Failed to call HTTP Service at ";
  20. private static final String ERROR_CONNECTION = "Failed to connect to ";
  21. private static final String ERROR_TIMEOUT = "Timeout occured connecting to ";
  22. private static final String ERROR_UNKNOWN_RESPONSE_CODE_RECIEVED = "Unknown Response Code %s recieved: ";
  23. private static final String ERROR_INTERNAL_ERROR = "Internal Server Error: ";
  24. private static final String ERROR_BAD_REQUEST = "Bad Request: ";
  25.  
  26. private static final String URL_FORMAT = "%s://%s:%s";
  27.  
  28. private static final String REQUEST_METHOD_POST = "POST";
  29.  
  30. private static final Logger LOGGER = Logger.getLogger(HttpClient.class);
  31.  
  32. private String m_hostname = "";
  33. private String m_protocol = "";
  34. private String m_port = "";
  35.  
  36. //default is set to 10 seconds
  37. private int m_timeoutMs = 10000;
  38.  
  39. private URL endpoint = null;
  40.  
  41. /**
  42. * Must be called after connection params are set
  43. * @throws MalformedURLException
  44. */
  45. public void afterPropertiesSet() throws MalformedURLException
  46. {
  47. endpoint = new URL(getHttpEndpoint());
  48. }
  49.  
  50. public byte[] send(byte[] input, int numRetries) throws DataTransportException
  51. {
  52. byte[] payload = null;
  53.  
  54. for (int i=1; i<=numRetries; i++)
  55. {
  56. try
  57. {
  58. //create a new connection for each request
  59. HttpURLConnection connection = (HttpURLConnection) endpoint.openConnection();
  60. connection.setReadTimeout(m_timeoutMs);
  61. connection.setConnectTimeout(m_timeoutMs);
  62. connection.setRequestMethod(REQUEST_METHOD_POST);
  63. connection.setDoInput(true);
  64. connection.setDoOutput(true);
  65.  
  66. //write our request to the post body using an outputstream
  67. DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
  68. wr.write(input);
  69. wr.flush();
  70. wr.close();
  71.  
  72. //check for success or failure
  73. handleResponseCodes(connection);
  74.  
  75. //how big is our response
  76. int length = connection.getContentLength();
  77. LOGGER.debug("bytes received: " + length);
  78.  
  79. //read response
  80. payload = readPayload(connection, length);
  81. break;
  82. }
  83. catch (ConnectException ce)
  84. {
  85. hrowDataTransportException(..........)
  86. }
  87. catch (SocketTimeoutException ste)
  88. {
  89. throwDataTransportException(.....);
  90. }
  91. catch (Throwable t)
  92. {
  93. throwDataTransportException(i, numRetries, EventLogIds.HTTP_DEFAULT_ERROR,
  94. ERROR_DEFAULT_HTTP + endpoint, t);
  95. }
  96. }
  97. return payload;
  98. }
  99.  
  100. /**
  101. * Logs error message and throws exception
  102. * @param errorCode
  103. * @param errorMessage
  104. * @param e
  105. * @throws CommonHotelException
  106. */
  107. private void throwDataTransportException(int currentAttempt, int totalAttempt, int errorCode,
  108. String errorMessage, Throwable e)
  109. throws DataTransportException
  110. {
  111. if (currentAttempt==totalAttempt)
  112. {
  113. throw new DataTransportException(errorMessage, errorCode, e);
  114. }
  115. else
  116. {
  117. String message = String.format("Http Client attempt %d of %d failed: %s",
  118. currentAttempt, totalAttempt, errorMessage);
  119. EventLogEntry.logEvent(LOGGER, Level.WARN, errorCode, message, e);
  120. }
  121. }
  122.  
  123. /**
  124. * Checks http error code and message
  125. * @param errorCode
  126. * @param errorMessage
  127. * @param e
  128. * @throws IOException
  129. * @throws CommonHotelException
  130. */
  131. private void throwDataTransportException(int errorCode, String errorMessage, Throwable e, InputStream errorStream)
  132. throws DataTransportException, IOException
  133. {
  134. //try to read from stderr
  135. StringBuilder builder = new StringBuilder(errorMessage);
  136. builder.append(". Details: ");
  137. if(errorStream != null)
  138. {
  139. BufferedReader in = null;
  140. try
  141. {
  142. in = new BufferedReader(new InputStreamReader(errorStream));
  143. String line = in.readLine();
  144. while(line != null)
  145. {
  146. builder.append(line);
  147. line = in.readLine();
  148. }
  149. }
  150. catch (IOException e1)
  151. {
  152. LOGGER.warn(Utilities.getExceptionStackTrace(e1));
  153. }
  154. finally
  155. {
  156. if(in != null)
  157. {
  158. in.close();
  159. }
  160. }
  161.  
  162. }
  163. throw new DataTransportException(builder.toString(), errorCode, e);
  164. }
  165.  
  166. private void handleResponseCodes(HttpURLConnection connection)
  167. throws DataTransportException, IOException
  168. {
  169. int responseCode = connection.getResponseCode();
  170. String responseMessage = connection.getResponseMessage();
  171. InputStream errorStream = connection.getErrorStream();
  172.  
  173. switch (responseCode)
  174. {
  175. case HttpURLConnection.HTTP_OK:
  176. EventLogEntry.logEvent(LOGGER, Level.DEBUG,
  177. EventLogIds.HTTP_TRANSFER_SUCCESS, DEBUG_HTTP_RESULT
  178. + responseMessage);
  179. break;
  180. case HttpURLConnection.HTTP_BAD_REQUEST:
  181. throwDataTransportException(EventLogIds.HTTP_BAD_REQUEST, ERROR_BAD_REQUEST
  182. + responseMessage, null, errorStream);
  183. case HttpURLConnection.HTTP_INTERNAL_ERROR:
  184. throwDataTransportException(EventLogIds.HTTP_INTERNAL_SERVER_ERROR,
  185. ERROR_INTERNAL_ERROR + responseMessage, null, errorStream);
  186. default:
  187. String message = String.format(ERROR_UNKNOWN_RESPONSE_CODE_RECIEVED, responseCode);
  188. throwDataTransportException(EventLogIds.HTTP_DEFAULT_ERROR,
  189. message + responseMessage, null, errorStream);
  190. }
  191. }
  192.  
  193.  
  194. /**
  195. * reads all bytes in the response
  196. *
  197. * @param connection
  198. * @param length
  199. * must specify length of expected payload
  200. * @throws IOException
  201. */
  202. private byte[] readPayload(HttpURLConnection connection, int length) throws IOException