HttpUrlConnection 基础使用

一个支持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://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";
    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;
    }

复制代码

猜你喜欢

转载自blog.csdn.net/margin_0px/article/details/85246429
今日推荐