安卓网络编程学习——java原生网络编程

Posted 武神酱丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓网络编程学习——java原生网络编程相关的知识,希望对你有一定的参考价值。

写在前面

该博客紧接上篇博客:https://www.cnblogs.com/wushenjiang/p/12937531.html,继续学习post请求,带参数的post和get请求以及文件上传与下载

post请求

其实post请求的方式与get请求差不太多,我们还是先上代码:

    public void postRequest(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                InputStream inputStream = null;
                try {
                    URL url = new URL(BASE_URL + "/post/comment");
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setRequestMethod("POST");
                    httpURLConnection.setConnectTimeout(10000);
                    httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
                    httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
                    httpURLConnection.setRequestProperty("Accept", "application/json,text/plain,*/*");

                    CommentItem commentItem = new CommentItem("234134123", "我是评论内容...哈哈");
                    Gson gson = new Gson();
                    String jsonStr = gson.toJson(commentItem);
                    byte[] bytes = jsonStr.getBytes("UTF-8");
                    Log.d(TAG, "bytes==>" + bytes.length);
                    httpURLConnection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
                    //连接
                    httpURLConnection.connect();
                    //把数据给到服务器
                    outputStream = httpURLConnection.getOutputStream();
                    outputStream.write(bytes);
                    outputStream.flush();
                    //拿到结果
                    int responseCode = httpURLConnection.getResponseCode();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        inputStream = httpURLConnection.getInputStream();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                        Log.d(TAG, "result ==>" + bufferedReader.readLine());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

可以看到,与get请求不同的一点就是我们需要添加一个内容,然后把数据写入到服务端,最后关闭所有的流。整体的流程和get基本一致。

带参数的post和get请求

这里其实很类似,我们直接写一个方法统一起来:

 private void startRequest(final Map<String, String> params, final String method, final String api) {
        new Thread(new Runnable() {
            BufferedReader bufferedReader = null;

            @Override
            public void run() {
                StringBuilder sb = new StringBuilder("?");
                try {
                    //组装参数
                    if (params != null && params.size() > 0) {
                        Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, String> next = iterator.next();
                            sb.append(next.getKey());
                            sb.append("=");
                            sb.append(next.getValue());
                            if (iterator.hasNext()) {
                                sb.append("&");
                            }
                        }
                        Log.d(TAG, "sb result -->" + sb.toString());
                    }
                    URL url;
                    String paramsStr = sb.toString();
                    if (paramsStr != null && paramsStr.length() > 0) {
                        url = new URL(BASE_URL + api + paramsStr);
                    } else {
                        url = new URL(BASE_URL + api);
                    }
                    Log.d(TAG, "url ==>" + url.toString());
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setRequestMethod(method);
                    httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
                    httpURLConnection.setRequestProperty("Accept", "*/*");
                    httpURLConnection.connect();
                    int responseCode;
                    responseCode = httpURLConnection.getResponseCode();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        InputStream inputStream = httpURLConnection.getInputStream();
                        bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                        String json = bufferedReader.readLine();
                        Log.d(TAG, "result ==>" + json);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bufferedReader != null) {
                        try {
                            bufferedReader.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

可以看到,我们主要就是需要将url进行一个字符串拼接,我们使用StringBuilder来进行字符串拼接,要更为安全。具体的操作流程请见代码,不用多说了。

文件上传

我们要做文件上传,其实很简单。先来上代码:

  public void postFiles(View v) {
        new Thread(new Runnable() {
            OutputStream outputStream = null;
            InputStream inputStream = null;

            @Override
            public void run() {
                try {
                    File fileOne = new File("/storage/emulated/0/Download/shop-ad.png");
                    File fileTwo = new File("/storage/emulated/0/Download/rBsADV64HDWAI6i_AAhJfxL8eXE287.png");
                    File fileThree = new File("/storage/emulated/0/Download/rBsADV64ILeAfwQMAAdBpy-0H04021.png");
                    String fileKey = "files";
                    String fileType = "image/png";
                    String BOUNDARY = "--------------------------246140106706876087289187";
//                    String BOUNDARY = "----------------------------246140106706876087289187";
                    URL url = new URL(BASE_URL + "/files/upload");
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setRequestMethod("POST");
                    httpURLConnection.setConnectTimeout(10000);
                    httpURLConnection.setRequestProperty("User-Agent", "android/" + Build.VERSION.SDK_INT);
                    httpURLConnection.setRequestProperty("Accept", "*/*");
                    httpURLConnection.setRequestProperty("Cache-Control", "no-cache");
                    httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
                    httpURLConnection.setRequestProperty("Connection", "keep-alive");
                    httpURLConnection.setDoOutput(true);
                    httpURLConnection.setDoInput(true);
                    //连接
                    httpURLConnection.connect();
                    outputStream = httpURLConnection.getOutputStream();
                    uploadFile(fileOne, fileKey, fileOne.getName(), fileType, BOUNDARY, outputStream, false);
                    uploadFile(fileTwo, fileKey, fileTwo.getName(), fileType, BOUNDARY, outputStream, false);
                    uploadFile(fileThree, fileKey, fileThree.getName(), fileType, BOUNDARY, outputStream, true);
                    outputStream.flush();
                    //获取返回结果
                    int responseCode = httpURLConnection.getResponseCode();
                    Log.d(TAG, "responseCode ==>" + responseCode);
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        inputStream = httpURLConnection.getInputStream();
                        BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream));
                        String result = bf.readLine();
                        Log.d(TAG, "result ==>" + result);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //                    if (bfi != null) {
                    //                        try {
                    //                            bfi.close();
                    //                        } catch (IOException e) {
                    //                            e.printStackTrace();
                    //                        }
                    //                    }
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            private void uploadFile(File file,
                                    String fileKey,
                                    String fileName,
                                    String fileType,
                                    String BOUNDARY,
                                    OutputStream outputStream,
                                    boolean isLast) throws IOException {
                //准备数据
                StringBuilder headerSbInfo = new StringBuilder();
                headerSbInfo.append("--");
                headerSbInfo.append(BOUNDARY);
                headerSbInfo.append("\\r\\n");
                headerSbInfo.append("Content-Disposition: form-data; name=\\"" + fileKey + "\\"; filename=\\"" + fileName + "\\"");
                headerSbInfo.append("\\r\\n");
                headerSbInfo.append("Content-Type:" + fileType);
                headerSbInfo.append("\\r\\n");
                headerSbInfo.append("\\r\\n");
                byte[] headerInfoBytes = headerSbInfo.toString().getBytes("UTF-8");
                outputStream.write(headerInfoBytes);
                //文件内容
                FileInputStream fos = new FileInputStream(file);
                BufferedInputStream bfi = new BufferedInputStream(fos);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = bfi.read(buffer, 0, buffer.length)) != -1) {
                    outputStream.write(buffer, 0, len);
                }
                //写尾部信息
                StringBuilder footerSbInfo = new StringBuilder();
                footerSbInfo.append("\\r\\n");
                footerSbInfo.append("--");
                footerSbInfo.append(BOUNDARY);
                if (isLast) {
                    footerSbInfo.append("--");
                    footerSbInfo.append("\\r\\n");
                }
                footerSbInfo.append("\\r\\n");
                outputStream.write(footerSbInfo.toString().getBytes("UTF-8"));
            }
        }).start();
    }

仔细看,其实有点复杂。这里解释一下:
首先我们要先设置把本地的一张图设置为File类,而后设置连接的参数。之后是上传的方法 可以看到,我们上传文件的方法也是一个字符串拼接,不过拼接的是一种固定格式,我们需要按照规定的格式拼接好才能让我们的服务器识别并上传。之后将图片转换成二进制文件进行读取,之后再拼接尾部格式。之后便是返回结果了。我们通过返回结果来看看是否上传成功,之后在自己的文件夹下看看是否有文件即可。

文件下载

和上传文件相比,下载文件就没有那么复杂了,如下代码:

   public void downloadFile(View v) {
        new Thread(new Runnable() {
            FileOutputStream fileOutputStream = null;
            InputStream inputStream = null;
            @Override
            public void run() {
                try {
                    URL url = new URL(BASE_URL + "/download/10");
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setConnectTimeout(10000);
                    httpURLConnection.setRequestMethod("GET");
                    httpURLConnection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
                    httpURLConnection.setRequestProperty("Accept", "*/*");
                    httpURLConnection.connect();
                    int responseCode = httpURLConnection.getResponseCode();
                    Log.d(TAG,"responseCode ==>"+responseCode);
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        Map<String, List<String>> headerFields = httpURLConnection.getHeaderFields();
                        for (Map.Entry<String, List<String>> stringListEntry : headerFields.entrySet()) {
                            Log.d(TAG,stringListEntry.getKey() +"==="+stringListEntry.getValue());
                        }
                        String headerField = httpURLConnection.getHeaderField("Content-disposition");
                        Log.d(TAG,"headerField -->"+headerField);
//                        int index = headerField.indexOf("filename=");
//                        String fileName = headerField.substring(index + "filename=".length());
//                        Log.d(TAG,"fileName ==>"+fileName);
                        String fileName = headerField.replace("attachment; filename=", "");
                        Log.d(TAG,"fileName ==>"+fileName);
                        File picFile = RequestTestActivity.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                        if (!picFile.exists()) {
                            picFile.mkdirs();
                        }
                        File file = new File(picFile+fileName);
                        if(!file.exists()){
                            file.createNewFile();
                        }

                        fileOutputStream = new FileOutputStream(file);
                        inputStream = httpURLConnection.getInputStream();
                        byte[] buffer = new byte[1024];
                        int len;
                        while((len = inputStream.read(buffer,0,buffer.length)) != -1){
                            fileOutputStream.write(buffer,0,len);
                        }
                        fileOutputStream.flush();

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    if (inputStream != null) {
                        IOUtils.ioClose(inputStream);
                    }
                    if (fileOutputStream != null) {
                        IOUtils.ioClose(fileOutputStream);
                    }
                }
            }
        }).start();
    }

我们从服务器请求回文件,然后获取路径,新建文件和路径,然后存储进去即可。

总结

使用java API的编程操作到这里就先告一段落了,可以看到通过原生API编程的不易啊,后面我们马上学习框架使用和线程管理,就更能体会到框架的好处了。

以上是关于安卓网络编程学习——java原生网络编程的主要内容,如果未能解决你的问题,请参考以下文章

原生安卓去除网络叉号

手机刷原生安卓系统不同步网络时间,怎么修改来着?

安卓 原生okhttp使用get与post获取网络数据

零基础,怎么学习Android安卓APP的开发,需要学习哪些知识

译文:18个实用的JavaScript代码片段,助你快速处理日常编程任务

安卓编程 如何在Java代码里设置button的margin(外边距)?