`
cyril0513
  • 浏览: 15559 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

使用HttpConnection发送Post请求

阅读更多
这是在项目中运用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
	{
		byte[] payload = new byte[length];
		//read all bytes
		//TODO: need a way to break loop in error cases
		
		InputStream is = null;
		try{
			is = connection.getInputStream();
			int bytesRemaining = length;
			while( bytesRemaining > 0)
			{
				int off = length - bytesRemaining;
				int avail = is.available();
				int bytesRead = is.read(payload, off, avail);
				bytesRemaining -= bytesRead;
			}
		}
		finally{
			if(is != null)
			{
				is.close();
			}
		}
		return payload;
	}

	private String getHttpEndpoint()
	{
		return String.format(URL_FORMAT, m_protocol, m_hostname, m_port);
	}
	
	/**
	 * Set hostname we are sending to
	 * @param hostname
	 */
	public void setHostname(String hostname)
	{
		m_hostname = hostname;
	}

	/**
	 * Set protocol.  eg. "http"
	 * @param protocol
	 */
	public void setProtocol(String protocol)
	{
		m_protocol = protocol;
	}

	/**
	 * Set port
	 * @param port
	 */
	public void setPort(String port)
	{
		m_port = port;
	}

	public void setTimeoutMs(int timeoutMs)
	{
		m_timeoutMs = timeoutMs;
	}

}
分享到:
评论

相关推荐

    j2me Http Get和Post请求总结

    在“TestHttpGetPost”这个压缩包中,可能包含了示例代码或者测试用例,用于演示如何在J2ME程序中实现GET和POST请求。这些代码可能包括创建连接、设置请求头、发送数据以及接收响应的步骤,对于初学者来说是很好的...

    python做get和post请求

    - `httplib.HTTPConnection.request('POST', url, body=data)`:对于POST请求,`body`参数通常包含要发送的数据。 3. **http.client模块**(Python 3): - `http.client.HTTPConnection.request('GET', url)` 和...

    Python3模拟curl发送post请求操作示例

    在Python3中,模拟curl发送POST请求通常是为了与服务器进行数据交互,例如调用API接口或者发送JSON格式的数据。这个过程可以通过`requests`库来实现,但有时可能需要使用更低级别的HTTP客户端,如`http.client`。...

    Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能

    程序会持续运行直到达到设定的持续时间,每轮运行都会启动10个线程,每个线程间隔1秒发送POST请求。 这个例子展示了如何结合使用Python的多线程和异步特性,以及`http.client`模块来实现高效的数据传输。值得注意的...

    python发送HTTP请求的方法小结

    3. **POST 请求:** 同 GET 请求一样使用 `request` 方法,但需要传递额外的参数和头部信息。 4. **响应处理:** 获取响应并读取数据。 ### 总结 通过上述示例,我们可以看到 Python 提供了强大的工具来发送各种...

    HTTP上传和下载C++封装类支持GET、POST多种方式

    对于上传功能,尤其是上传二进制数据,如图片或文件,需要将文件内容读取并转换为字节流,然后通过POST请求发送。C++可以使用`fstream`库来读取文件,并结合`std::stringstream`处理字节流。在`HttpConnection`类中...

    python通过get,post方式发送http请求和接收http响应的方法

    本篇内容将详细探讨如何使用Python中的`urllib`模块和`urllib2`模块(针对Python 2.x版本)来实现GET与POST请求的发送,并接收HTTP响应。 #### 1. 测试用CGI环境设置 为了更好地演示如何使用Python发送HTTP请求并...

    httpClient httpPost httpGet 所需jar包

    POST请求常用于向服务器发送数据,例如提交表单或上传文件。HttpPost对象允许我们设置请求头、URL以及请求体内容。 3. HttpGet:HttpGet是HttpClient库的另一个关键类,用于执行HTTP GET请求。GET请求通常用于获取...

    Python-gzipencoding实例如何压缩HTTP请求发送到web服务并处理

    在发送POST或PUT请求时,我们可能需要发送JSON或其他结构化数据。为这些数据添加gzip压缩,可以使用`gzip`模块的`compress`函数。以下是一个例子: ```python import gzip import json import requests data...

    在无线J2ME设备上实现超文本传输协议

    同样,发送HTTP POST请求的过程类似,只是在建立连接后,还需要写入POST数据到HttpConnection的OutputStream。POST请求常用于提交表单数据或上传文件,数据包含在请求体中,而不是像GET请求那样包含在URL中。 在...

    android httpconnection上传文件

    HTTPConnection是Java标准API中对HTTP协议的一个简单实现,适用于发送GET、POST和PUT等请求。 在Android中,由于安全性考虑,直接使用HttpURLConnection可能会遇到权限问题。因此,我们通常会在AndroidManifest.xml...

    python3.x上post发送json数据

    接下来,使用http.client库的HTTPConnection类创建一个到指定服务器的连接,然后使用request方法发送POST请求。发送请求后,调用getresponse方法获取服务器响应,然后读取并打印响应内容。 示例中也提到了,使用...

    J2ME手机登陆程序

    在描述的登陆程序中,客户端部分会使用MIDP的javax.microedition.io.Connector类来建立网络连接,并使用HttpConnection接口来发送POST请求。POST请求通常用于提交表单数据,如用户名和密码。以下是一个简单的示例: ...

    用J2ME与ASP建立数据库连接.rar_http in j2me_j2me_j2me 3d_j2me asp

    3. **发送数据**:如果使用POST请求,需要写入请求体,如数据库查询参数。使用`OutputStream os = conn.openOutputStream();`写入数据,然后关闭输出流。 4. **读取响应**:通过`InputStream is = conn....

    探索J2ME:用GCF通信

    2. POST请求允许通过单独的数据流发送大量数据到服务器,如提交Web表单。虽然数据不是直接在URL中显示,但仍然可能不安全。 3. HEAD请求仅用于获取服务器关于请求的元数据,不返回请求的数据本身,通常用于检查资源...

    关于Python实现短信验证码注册登录的Python - http.client.py、Python - Requests.py文件.zip

    然后,通过`request()`方法发送POST请求,将用户的电话号码和必要的API密钥等信息作为请求体发送出去,以请求生成验证码。收到服务器返回的验证码后,通常会将其存储在服务器端,以便后续验证用户输入的验证码。 接...

    http.rar_HTTP 网页

    5. **发送请求**:使用`HttpConnection`的`.setRequestMethod()`方法指定请求类型(GET或POST),然后调用`connect()`来实际发起请求。 6. **读取响应**:成功发送请求后,`HttpConnection`对象返回的输入流可以...

    httplib用法.

    无论是发起GET请求还是POST请求,亦或是处理HTTP响应,`htllib`都能很好地胜任。本文将详细探讨`httplib`模块的使用方法及其内部提供的主要类型和方法。 #### 二、HTTPConnection 类 `HTTPConnection` 是 `httplib...

Global site tag (gtag.js) - Google Analytics