本篇主要介绍如何利用HttpURLConnection在手机端使用HTTP协议和服务器端进行交互,主要流程是首先向服务器发送请求,请求成功后再获取服务器返回的数据和结果等。


网络通讯需要声明联网权限,所以首先在AndroidManifest声明权限

< uses-permission android:name=“android.permission.INTERNET” />

而请求方式分为两种,一种是get,一种为post,get和post都可以向服务器传递参数发送请求。最大的区别在于get方式是将要传递的参数放到连接的url中,而post方式会用一个数据操作流入dataOutputStream来写入数据。我理解的是get方式要简单一些,安全性低一些,post方式复杂一些,安全性高一些,所以一般发送数据类型简单且不重要的数据时会使用get方式,反之则选择post方式。

注意网络请求HttpURLConnection要放在子线程中,处理完了之后要用disconnect方法关闭连接
1.使用get方式发送请求
int room_id=1;//传给服务器的参数
 int section=1;//传递服务器的参数
 final Thread thread=new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            URL url=new URL("http://39.**.***.***:8080/MeetingManager/MeetingAndRooms/topThreeDepartmentRatio?room_id="
        +URLEncoder.encode(String.valueOf(room_id))
        +"§ion="+URLEncoder.encode(String.valueOf(section)));//url为网络连接地址,:后面的为端口号,最后放入传到服务器的参数。比如我要传room_id和section两个变量

            HttpURLConnection connection= (HttpURLConnection) url.openConnection();//实例HttpURLConnection
            connection.setRequestMethod("GET");//设置请求方式为get
            connection.setConnectTimeout(5*1000);//设置连接时间
            connection.connect();//连接
            
            int code = connection.getResponseCode();//获取状态码
            Log.d("interfaces code ",String.valueOf(code));
            if(code==200){//code为200时表示请求正常
                InputStream inputStream=connection.getInputStream();//获得请求所返回的结果
                String result = stremToString(inputStream);
                JSONObject root_json = new JSONObject(result);//将一个字符串封装成一个json对象root_json
               
                /**然后把返回的数据分别拿出来,比如我的返回体为
 * {"code":0,"message":"请求成功", "data":{{"department_name":"后勤部","ratio":"0.5"},{"department_name":"公关部","ratio":"0.2"},{"department_name":"宣传部","ratio":"0.1"}},"meta":null}
 * **/
               JSONArray jsonArray = root_json.getJSONArray("data");//获取root_json中的data作为jsonArray对象
                int codes=root_json.getInt("code");
                proportions.clear();//清除beans
                Log.d("interfaces 0",String.valueOf(jsonArray.length()));
                for(int i=0;i<jsonArray.length();i++){
                    JSONObject proportion_json=jsonArray.getJSONObject(i);
                    proportion proportion=new proportion(proportion_json.getString("department_name"),proportion_json.getDouble("ratio"));
                    proportions.add(proportion);
                    Log.d("interfaces ",proportion.getName());
                }
                Log.d("interfaces 1",String.valueOf(jsonArray.length())+"+"+String.valueOf(proportions.size()));
                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[0] =sb.toString();
                inputStream.close();
                connection.disconnect();
                Log.d("interfaces 2",String.valueOf(jsonArray.length())+"+"+String.valueOf(proportions.size()));

            }
        } catch (Exception e) {
            Log.e("interfaces: ",e.toString());
        }
    }
});
thread.start();

这里用了URLEncoder.encode方法来拼接传给服务器的参数到url里。注意第一个参数先写?再接参数名字,接下来的参数以&开头。

2.使用post方式发送请求

流程和使用get方式差不多,都是先设置连接然后向服务器传递参数,连接成功后再获取服务器返回的参数,主要是传递参数的方式不同,这里举一个上传文件和一个下载文件的例子

//上传文件
public String uploadFile(final File file, int parent_room_id){
    final String[] message = {""};
    final String url="http://39.**.**.**:8080/Common/FileUpload/upload.do";//网络地址
    final String boundary="123456";//分割线
    final Map<String ,String> params=new HashMap<>();//以键值对的方式放传给服务器的参数
    params.put("id",String.valueOf(parent_room_id));
    params.put("type",",meeting_room_pic");
    final Thread thread=new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url1=new URL(url);
                HttpURLConnection connection= (HttpURLConnection) url1.openConnection();
                connection.setRequestMethod("POST");//设置请求方式为post
                connection.addRequestProperty("Connection","Keep-Alive");//设置与服务器保持连接
                connection.addRequestProperty("Charset","UTF-8");//设置字符编码类型
                connection.addRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);//post请求,上传数据时的编码类型,并且指定了分隔符
                // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
                // http正文内,因此需要设为true, 默认情况下是false;
                connection.setDoOutput(true);
                //设置是否从httpUrlConnection读入,默认情况下是true;
                connection.setDoInput(true);
                // Post 请求不能使用缓存
                connection.setUseCaches(false);
                connection.setConnectTimeout(20000);
                //getOutStream会隐含的进行connect,所以也可以不调用connect
                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){
                    Log.e("uploadFile ",e.toString());
                }

                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[0] =sb1.toString();
                inputStream.close();
                fileInputStream.close();
                dataOutputStream.close();
                connection.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    thread.start();
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return message[0];
}
//下载文件或图片到外部存储
    public void doSDCard(Context context, final int parent_room_id){
        if (isExternalStorageWritable()){
            final Thread thread=new Thread(){
                @Override
                public void run() {
                    try {
                        String boundary="123456";
                        File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
                        if (!file.exists()){
                            file.mkdirs();//创建路径
                        }
//                        Map<String ,String> params=new HashMap<>();
//                        params.put("id",String.valueOf(parent_room_id));
//                        params.put("type","meeting_room_pic");
                        File newFile=new File(file.getPath(),System.currentTimeMillis()+".jpg");
//                        newFile.createNewFile();
                        URL url = new URL("http://47.***.***.134/wechat/Public/uploads/huiyishi.jpg");//接口地址
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                        connection.setRequestMethod("POST");
                        connection.setConnectTimeout(5*1000);

                        DataOutputStream dataOutputStream=new DataOutputStream(connection.getOutputStream());


                        String content = "id=" + URLEncoder.encode(String.valueOf(parent_room_id))+"&type=meeting_room_pic";
                        dataOutputStream.writeBytes(content);
//                        try {
//                            Set<String > keySet=params.keySet();
//                            for (String param:keySet){
//                                dataOutputStream.writeBytes(encode(param)+"=");
//                                String value=params.get(param);
//                                dataOutputStream.writeBytes(encode(value));
//                                dataOutputStream.writeBytes(boundary);
//                            }
//                        }catch (Exception e){
//                            Log.e("下载 ",e.toString());
//                        }

                        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) {
                        Log.e("interfaces e:",e.toString());
                    }
                }

            };
            thread.start();
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            AlertDialog.Builder builder=new AlertDialog.Builder(context);
            builder.setMessage("外部存储不可用!");
            builder.create().show();
        }
    }