这是在项目中运用HttpURLConnection发送post请求(我们项目中是用来发送soap),完整的处理,包括如何处理异常。需要注意一个小地方,我们把创建URL放在afterPropertiesSet方法中,是因为这个类只是为下游某一个特定的Service服务的,如果要作用共用的,不能这样做。
- import java.io.BufferedReader;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.net.ConnectException;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.SocketTimeoutException;
- import java.net.URL;
- import org.apache.log4j.Level;
- import org.apache.log4j.Logger;
- import org.springframework.beans.factory.InitializingBean;
- public class HttpClient implements InitializingBean
- {
- private static final String DEBUG_HTTP_RESULT = "Result of calling http service: ";
- private static final String ERROR_DEFAULT_HTTP = "Failed to call HTTP Service at ";
- private static final String ERROR_CONNECTION = "Failed to connect to ";
- private static final String ERROR_TIMEOUT = "Timeout occured connecting to ";
- private static final String ERROR_UNKNOWN_RESPONSE_CODE_RECIEVED = "Unknown Response Code %s recieved: ";
- private static final String ERROR_INTERNAL_ERROR = "Internal Server Error: ";
- private static final String ERROR_BAD_REQUEST = "Bad Request: ";
- private static final String URL_FORMAT = "%s://%s:%s";
- private static final String REQUEST_METHOD_POST = "POST";
- private static final Logger LOGGER = Logger.getLogger(HttpClient.class);
- private String m_hostname = "";
- private String m_protocol = "";
- private String m_port = "";
- //default is set to 10 seconds
- private int m_timeoutMs = 10000;
- private URL endpoint = null;
- /**
- * Must be called after connection params are set
- * @throws MalformedURLException
- */
- public void afterPropertiesSet() throws MalformedURLException
- {
- endpoint = new URL(getHttpEndpoint());
- }
- public byte[] send(byte[] input, int numRetries) throws DataTransportException
- {
- byte[] payload = null;
- for (int i=1; i<=numRetries; i++)
- {
- try
- {
- //create a new connection for each request
- HttpURLConnection connection = (HttpURLConnection) endpoint.openConnection();
- connection.setReadTimeout(m_timeoutMs);
- connection.setConnectTimeout(m_timeoutMs);
- connection.setRequestMethod(REQUEST_METHOD_POST);
- connection.setDoInput(true);
- connection.setDoOutput(true);
- //write our request to the post body using an outputstream
- DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
- wr.write(input);
- wr.flush();
- wr.close();
- //check for success or failure
- handleResponseCodes(connection);
- //how big is our response
- int length = connection.getContentLength();
- LOGGER.debug("bytes received: " + length);
- //read response
- payload = readPayload(connection, length);
- break;
- }
- catch (ConnectException ce)
- {
- hrowDataTransportException(..........)
- }
- catch (SocketTimeoutException ste)
- {
- throwDataTransportException(.....);
- }
- catch (Throwable t)
- {
- throwDataTransportException(i, numRetries, EventLogIds.HTTP_DEFAULT_ERROR,
- ERROR_DEFAULT_HTTP + endpoint, t);
- }
- }
- return payload;
- }
- /**
- * Logs error message and throws exception
- * @param errorCode
- * @param errorMessage
- * @param e
- * @throws CommonHotelException
- */
- private void throwDataTransportException(int currentAttempt, int totalAttempt, int errorCode,
- String errorMessage, Throwable e)
- throws DataTransportException
- {
- if (currentAttempt==totalAttempt)
- {
- throw new DataTransportException(errorMessage, errorCode, e);
- }
- else
- {
- String message = String.format("Http Client attempt %d of %d failed: %s",
- currentAttempt, totalAttempt, errorMessage);
- EventLogEntry.logEvent(LOGGER, Level.WARN, errorCode, message, e);
- }
- }
- /**
- * Checks http error code and message
- * @param errorCode
- * @param errorMessage
- * @param e
- * @throws IOException
- * @throws CommonHotelException
- */
- private void throwDataTransportException(int errorCode, String errorMessage, Throwable e, InputStream errorStream)
- throws DataTransportException, IOException
- {
- //try to read from stderr
- StringBuilder builder = new StringBuilder(errorMessage);
- builder.append(". Details: ");
- if(errorStream != null)
- {
- BufferedReader in = null;
- try
- {
- in = new BufferedReader(new InputStreamReader(errorStream));
- String line = in.readLine();
- while(line != null)
- {
- builder.append(line);
- line = in.readLine();
- }
- }
- catch (IOException e1)
- {
- LOGGER.warn(Utilities.getExceptionStackTrace(e1));
- }
- finally
- {
- if(in != null)
- {
- in.close();
- }
- }
- }
- throw new DataTransportException(builder.toString(), errorCode, e);
- }
- private void handleResponseCodes(HttpURLConnection connection)
- throws DataTransportException, IOException
- {
- int responseCode = connection.getResponseCode();
- String responseMessage = connection.getResponseMessage();
- InputStream errorStream = connection.getErrorStream();
- switch (responseCode)
- {
- case HttpURLConnection.HTTP_OK:
- EventLogEntry.logEvent(LOGGER, Level.DEBUG,
- EventLogIds.HTTP_TRANSFER_SUCCESS, DEBUG_HTTP_RESULT
- + responseMessage);
- break;
- case HttpURLConnection.HTTP_BAD_REQUEST:
- throwDataTransportException(EventLogIds.HTTP_BAD_REQUEST, ERROR_BAD_REQUEST
- + responseMessage, null, errorStream);
- case HttpURLConnection.HTTP_INTERNAL_ERROR:
- throwDataTransportException(EventLogIds.HTTP_INTERNAL_SERVER_ERROR,
- ERROR_INTERNAL_ERROR + responseMessage, null, errorStream);
- default:
- String message = String.format(ERROR_UNKNOWN_RESPONSE_CODE_RECIEVED, responseCode);
- throwDataTransportException(EventLogIds.HTTP_DEFAULT_ERROR,
- message + responseMessage, null, errorStream);
- }
- }
- /**
- * reads all bytes in the response
- *
- * @param connection
- * @param length
- * must specify length of expected payload
- * @throws IOException
- */
- private byte[] readPayload(HttpURLConnection connection, int length) throws IOException
转载于:https://blog.51cto.com/daheyuan/1134221