HttpURLConnection是java的标准类,是抽象类!需要通过URL的openConnection获取其父类URLConnect,之后再次强行转换,获取HttpURLConnection实例。HttpURLConnection有多种通信方法,其中Get和Post最为常用。
关于其他方法的与用途,可参见之前转载的博文
http://blog.csdn.net/daihuimaozideren/article/details/78900895
关于其他方法的简单实用,可参见博文
http://blog.csdn.net/anyoneking/article/details/5177927
关于Get和Post的区别,主要有两点:
1、GET请求是从服务器上获取数据,POST请求是向服务器传送数据。 但没有那么绝对,也可以使用GET发送数据。
2、GET的请求参数放在URL链接中,POST的请求参数放在body中。 也因为这一点,POST比GET安全,因为数据在地址栏上不可见。 GET的URL会有长度上的限制,而POST的数据则可以非常大。
下面是,自己总结的一个HttpURLConnection工具类。
public class HttpUtils {
public enum METHODS{POST,GET};
private static String sessionID=null;
private static String location=null;
private static int responseCode=0;
public static String sendReq(METHODS method,
String urlStr,
Map<String, String> params,
int timeOut,
boolean sessionIDFlag,
boolean cacheFlag,
boolean locationFlag){
String dataOut;
String response=null;
URL url;
try {
//(1)Params Transform
if(params==null){
dataOut=null;
}else {
dataOut=getRequestData(params, "utf-8").toString();
//(2)Put Params Into URL for Get Method
if(method==METHODS.GET){
urlStr=urlStr+"?"+dataOut;
}
}
//(3)get HttpURLConnect Object
url=new URL(urlStr);
HttpURLConnection con=(HttpURLConnection) url.openConnection();
//(4)HttpURLConnect Config
con.setConnectTimeout(timeOut);
con.setReadTimeout(timeOut);
if(method==METHODS.GET){
con.setRequestMethod("GET");
}else {
con.setRequestMethod("POST");
con.setDoOutput(true);
}
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//Set Cache (Optional)
if(cacheFlag){
con.setUseCaches(false);
}
//Set Session ID (Optional)
if(sessionIDFlag){
con.setRequestProperty("Cookie", sessionID==null?"":sessionID);
}
//(5)Send DataIn for POST Method
if(method==METHODS.POST){
if(dataOut!=null){
con.setRequestProperty("Content-Length", String.valueOf(dataOut.getBytes().length));
sendPostDataOut(con,dataOut.getBytes());
}
}
responseCode = con.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK) {
//(6)get Response
response = getResponse(con);
}else if(responseCode==HttpURLConnection.HTTP_MOVED_TEMP || responseCode==HttpURLConnection.HTTP_MOVED_PERM){
//(7)Find Location for redirect while responseCode=302 or 301 (Optional)
if(locationFlag){
saveLocation(con);
}
}
//(7)Find SeesionID (Optional)
if(sessionIDFlag){
saveSessionID(con);
}
} catch (ProtocolException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
return response;
}
private static void saveSessionID(HttpURLConnection con){
List<String> cookies = con.getHeaderFields().get("Set-Cookie");
for (String cookie :
cookies) {
//for PHP service only, if java service, "PHPSESSID" should be modified!
if (cookie.contains("PHPSESSID=")) {
sessionID = cookie.substring(0, cookie.indexOf(";"));
break;
}
}
}
private static void saveLocation(HttpURLConnection con){
location = con.getHeaderField("Location");
}
private static void sendPostDataOut(HttpURLConnection con, byte[] m_Data){
OutputStream outputStream=null;
try {
outputStream = con.getOutputStream();
outputStream.write(m_Data);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String getResponse(HttpURLConnection con){
InputStream is= null;
String m_Response=null;
try {
is = con.getInputStream();
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[]buffer=new byte[1024];
int len=0;
while((len=is.read(buffer))>0){
bos.write(buffer,0,len);
}
bos.flush();
is.close();
byte []result=bos.toByteArray();
m_Response=new String(result);
} catch (IOException e) {
e.printStackTrace();
}
return m_Response;
}
private static StringBuffer getRequestData(Map<String, String> params, String encode) {
StringBuffer stringBuffer = new StringBuffer();
try {
for(Map.Entry<String, String> entry : params.entrySet()) {
stringBuffer.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), encode))
.append("&");
}
//Delete the latest "&"
stringBuffer.deleteCharAt(stringBuffer.length() - 1);
} catch (Exception e) {
e.printStackTrace();
}
return stringBuffer;
}
public String getSessionID(){
return sessionID;
}
public static String getLocation() {
return location;
}
public static int getResponseCode() {
return responseCode;
}
}
这里需要注意以下几点:
(1)openConnection方法,并没有发动连接请求,只是获取一个URLConnection对象。
(2)Url的connect()方法是用来发起连接的。但工具类中并没有调用该方法。原因在于,该方法只是建立连接,但并不发送数据。getOutputStream()方法不仅会创建一个外发的数据流,而其会隐性的建立连接。因此,省去connect()方法,直接使用getOutputStream()。但Get方法无outputstream,因此,个人猜测,getInputStream()方法也有建立隐性连接的功能。
(3)关于调用顺序。首先,创建HttpURLConnection对象。随后,设置各种选项(例如连接超时时间,是否使用缓存,是否读取输出流等)。然后,与服务端建立连接。需要强调的是,如果已经连接成功再设置这些选项将会报错。
(4)post的传输数据是在传输正文中,即outputStream中。但在outputStream关闭时,数据并未发送出去。而是在获取inputStream时发送的。因此,即使outputStream未被关闭,在获取inputStream后再次向outputStream中写入数据,也无法发送出去了。