出处:https://www.cnblogs.com/libertycode/p/5979260.html
From https://developer.android.com/reference/java/net/HttpURLConnection.html
HttpUrlConnection:
A URLConnection with support for HTTP-specific features. See the spec for details.
Uses of this class follow a pattern:
HttpURLConnection
by calling URL.openConnection()
and casting the result to HttpURLConnection
.setDoOutput(true)
if they include a request body. Transmit data by writing to the stream returned by getOutputStream()
.getInputStream()
. If the response has no body, that method returns an empty stream.HttpURLConnection
should be closed by calling disconnect()
. Disconnecting releases the resources held by a connection so they may be closed or reused.中文释义:
一个支持HTTP特定功能的URLConnection。
使用这个类遵循以下模式:
1.通过调用URL.openConnection()来获得一个新的HttpURLConnection对象,并且将其结果强制转换为HttpURLConnection.
2.准备请求。一个请求主要的参数是它的URI。请求头可能也包含元数据,例如证书,首选数据类型和会话cookies.
3.可以选择性的上传一个请求体。HttpURLConnection实例必须设置setDoOutput(true),如果它包含一个请求体。通过将数据写入一个由getOutStream()返回的输出流来传输数据。
4.读取响应。响应头通常包含元数据例如响应体的内容类型和长度,修改日期和会话cookies。响应体可以被由getInputStream返回的输入流读取。如果响应没有响应体,则该方法会返回一个空的流。
5.关闭连接。一旦一个响应体已经被阅读后,HttpURLConnection 对象应该通过调用disconnect()关闭。断开连接会释放被一个connection占有的资源,这样它们就能被关闭或再次使用。
从上面的话以及最近的学习可以总结出:
关于HttpURLConnection的操作和使用,比较多的就是GET和POST两种了
主要的流程:
URL url=new URL("http://www.baidu.com"); HttpURLConnection connection= (HttpURLConnection) url.openConnection();
常用方法:
setDoInput
setDoOutput
setIfModifiedSince:设置缓存页面的最后修改时间(参考自:http://blog.csdn.net/stanleyqiu/article/details/7717235)
setUseCaches
setDefaultUseCaches
setAllowUserInteraction
setDefaultAllowUserInteraction
setRequestMethod:HttpURLConnection默认给使用Get方法
常用方法:
setRequestProperty(key,value)
addRequestProperty(key,value)
setRequestProperty和addRequestProperty的区别就是,setRequestProperty会覆盖已经存在的key的所有values,有清零重新赋值的作用。而addRequestProperty则是在原来key的基础上继续添加其他value。
常用设置:
设置请求数据类型:
connection.setRequestProperty("Content-type","application/x-javascript->json");//json格式数据 connection.addRequestProperty("Content-Type","application/x-www-form-urlencoded");//默认浏览器编码类型,http://www.cnblogs.com/taoys/archive/2010/12/30/1922186.html connection.addRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);//post请求,上传数据时的编码类型,并且指定了分隔符 Connection.setRequestProperty("Content-type", "application/x-java-serialized-object");// 设定传送的内容类型是可序列化的java对象(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
connection.addRequestProperty("Connection","Keep-Alive");//设置与服务器保持连接 connection.addRequestProperty("Charset","UTF-8");//设置字符编码类型
connect
getOutputStream
在这里getOutStream会隐含的进行connect,所以也可以不调用connect
getContent (https://my.oschina.net/zhanghc/blog/134591)
getHeaderField:获取所有响应头字段
getInputStream
getErrorStream:若HTTP响应表明发送了错误,getInputStream将抛出IOException。调用getErrorStream读取错误响应。
实例:
get请求:
public static String get(){ String message=""; try { URL url=new URL("http://www.baidu.com"); HttpURLConnection connection= (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5*1000); connection.connect(); InputStream inputStream=connection.getInputStream(); byte[] data=new byte[1024]; StringBuffer sb=new StringBuffer(); int length=0; while ((length=inputStream.read(data))!=-1){ String s=new String(data, Charset.forName("utf-8")); sb.append(s); } message=sb.toString(); inputStream.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } return message; }
post请求:
public static String post(){ String message=""; try { URL url=new URL("http://119.29.175.247/wikewechat/Admin/Login/login.html"); HttpURLConnection connection= (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setConnectTimeout(30000); connection.setReadTimeout(30000); connection.setRequestProperty("Content-type","application/x-javascript->json"); connection.connect(); OutputStream outputStream=connection.getOutputStream(); StringBuffer sb=new StringBuffer(); sb.append("email="); sb.append("[email protected]&"); sb.append("password="); sb.append("1234&"); sb.append("verify_code="); sb.append("4fJ8"); String param=sb.toString(); outputStream.write(param.getBytes()); outputStream.flush(); outputStream.close(); Log.d("ddddd","responseCode"+connection.getResponseCode()); InputStream inputStream=connection.getInputStream(); byte[] data=new byte[1024]; StringBuffer sb1=new StringBuffer(); int length=0; while ((length=inputStream.read(data))!=-1){ String s=new String(data, Charset.forName("utf-8")); sb1.append(s); } message=sb1.toString(); inputStream.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } return message; }
下载文件或图片到外部存储:
public boolean isExternalStorageWritable(){ String state= Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)){ return true; } return false; }
private void doSDCard(){ if (isExternalStorageWritable()){ new Thread(){ @Override public void run() { try { File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath()); if (!file.exists()){ file.mkdirs(); } File newFile=new File(file.getPath(),System.currentTimeMillis()+".jpg"); // newFile.createNewFile(); URL url = new URL("http://images.csdn.net/20150817/1.jpg"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); InputStream inputStream = connection.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(newFile.getAbsolutePath()); byte[] bytes = new byte[1024]; int len = 0; while ((len = inputStream.read(bytes)) != -1) { fileOutputStream.write(bytes); } inputStream.close(); fileOutputStream.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } } }.start(); }else { AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setMessage("外部存储不可用!"); builder.create().show(); } }
post上传图片和表单数据:
public static String uploadFile(File file){ String message=""; String url="http://119.29.175.247/uploads.php"; String boundary="7786948302"; Mapparams=new HashMap<>(); params.put("name","user"); params.put("pass","123"); try { URL url1=new URL(url); HttpURLConnection connection= (HttpURLConnection) url1.openConnection(); connection.setRequestMethod("POST"); connection.addRequestProperty("Connection","Keep-Alive"); connection.addRequestProperty("Charset","UTF-8"); connection.addRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在 // http正文内,因此需要设为true, 默认情况下是false; connection.setDoOutput(true); //设置是否从httpUrlConnection读入,默认情况下是true; connection.setDoInput(true); // Post 请求不能使用缓存 ? connection.setUseCaches(false); connection.setConnectTimeout(20000); DataOutputStream dataOutputStream=new DataOutputStream(connection.getOutputStream()); FileInputStream fileInputStream=new FileInputStream(file); dataOutputStream.writeBytes("--"+boundary+"\r\n"); // 设定传送的内容类型是可序列化的java对象 // (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException) dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + URLEncoder.encode(file.getName(),"UTF-8")+"\"\r\n"); dataOutputStream.writeBytes("\r\n"); byte[] b=new byte[1024]; while ((fileInputStream.read(b))!=-1){ dataOutputStream.write(b); } dataOutputStream.writeBytes("\r\n"); dataOutputStream.writeBytes("--"+boundary+"\r\n"); try { Set keySet=params.keySet(); for (String param:keySet){ dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" +encode(param)+"\"\r\n"); dataOutputStream.writeBytes("\r\n"); String value=params.get(param); dataOutputStream.writeBytes(encode(value)+"\r\n"); dataOutputStream.writeBytes("--"+boundary+"\r\n"); } }catch (Exception e){ } InputStream inputStream=connection.getInputStream(); byte[] data=new byte[1024]; StringBuffer sb1=new StringBuffer(); int length=0; while ((length=inputStream.read(data))!=-1){ String s=new String(data, Charset.forName("utf-8")); sb1.append(s); } message=sb1.toString(); inputStream.close(); fileInputStream.close(); dataOutputStream.close(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } return message; } private static String encode(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value,"UTF-8"); }
这里需要指出:
通过chrome的开发工具截取的头信息可以看到:
通过post上传数据时,若除了文本数据以外还要需要上传文件,则需要在指定每一条数据的Content-Disposition,name,若是文件还要指明filename,并在每条数据传输的后面用“--”加上boundary隔开,并且需要在第四行用“\r\n”换行符隔开,在最后一行也要用“--”加上boundary加上“--”隔开,否则会导致文件上传失败!
补充:
对于URLConnection,获取响应体数据的方法包括getContent和getInputStream
getInputStream上面已经提到,对于getContent的用法如下:
1、重写ContentHandler
2、实现ContentHandlerFactory接口,在createContentHandler方法中将重写的ContentHandler实例作为返回值返回
3、在HttpURLConnection.setContentHandlerFactory中实例化ContentHandlerFactory实例
代码如下:
public class ContentHandlerFactoryImpl implements ContentHandlerFactory { @Override public ContentHandler createContentHandler(String mimetype) { if (mimetype==null){ return new ContentHandlerImpl(false); } return new ContentHandlerImpl(true); } class ContentHandlerImpl extends ContentHandler{ private boolean transform=false; public ContentHandlerImpl(boolean transform){ this.transform=transform; } @Override public Object getContent(URLConnection urlc) throws IOException { if (!transform){ return urlc.getInputStream(); }else { String encoding=getEncoding(urlc.getHeaderField("Content-Type")); if (encoding==null){ encoding="UTF-8"; } BufferedReader reader=new BufferedReader(new InputStreamReader(urlc.getInputStream(),encoding)); String tmp=null; StringBuffer content=new StringBuffer(); while ((tmp=reader.readLine())!=null){ content.append(tmp); } return content.toString(); } } } private String getEncoding(String contentType){ String [] headers=contentType.split(";"); for (String header:headers){ String [] params=header.split("="); if (params.length==2){ if (params[0].equals("charset")){ return params[1]; } } } return null; } }
public static String post(){ String message=""; URL url= null; try { url = new URL("http://127.0.0.1/test.php"); HttpURLConnection connection= (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setUseCaches(false); connection.setConnectTimeout(5*1000); HttpURLConnection.setContentHandlerFactory(new ContentHandlerFactoryImpl()); connection.setRequestProperty("ContentType","application/x-www-form-urlencoded"); OutputStream outputStream=connection.getOutputStream(); StringBuffer stringBuffer=new StringBuffer(); stringBuffer.append("user[name]="); stringBuffer.append("user"); stringBuffer.append("&user[pass]="); stringBuffer.append("123"); outputStream.write(stringBuffer.toString().getBytes()); outputStream.flush(); outputStream.close(); Log.d("HttpUtil","responseMessage"+connection.getResponseMessage()); Map> map=connection.getHeaderFields(); Set set=map.keySet(); for (String key:set){ List list=map.get(key); for (String value:list){ Log.d("HttpUtil","key="+key+" value="+value); } } message= (String) connection.getContent(); connection.disconnect(); } catch (Exception e) { e.printStackTrace(); } return message; }
参考自:https://my.oschina.net/zhanghc/blog/134591