• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

HttpUrlConnection 应用

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0528/515.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:

  1. Obtain a new HttpURLConnection by calling URL.openConnection() and casting the result to HttpURLConnection.
  2. Prepare the request. The primary property of a request is its URI. Request headers may also include metadata such as credentials, preferred content types, and session cookies.
  3. Optionally upload a request body. Instances must be configured with setDoOutput(true) if they include a request body. Transmit data by writing to the stream returned by getOutputStream().
  4. Read the response. Response headers typically include metadata such as the response body's content type and length, modified dates and session cookies. The response body may be read from the stream returned by getInputStream(). If the response has no body, that method returns an empty stream.
  5. Disconnect. Once the response body has been read, the 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实例,翻开URLConnection

URL url=new URL("http://www.baidu.com");
HttpURLConnection connection= (HttpURLConnection) url.openConnection();

  设置持续参数

 常用要领:

  setDoInput

  setDoOutput

  setIfModifiedSince:设置缓存页面的末了点窜光阴(参考自:http://www.homeqin.cn/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.homeqin.cn/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("409947972@qq.com&");
            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";
    Map<String ,String> params=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<String > 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<String ,List<String >> map=connection.getHeaderFields();
            Set<String> set=map.keySet();            for (String  key:set){
                List<String > 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;
    }
复制代码
 


上篇:上一篇:办理Fragment切换过快程序崩溃
下篇:下一篇:SimpleDateFormat的少许常用用法