关于Android或Java的Http get,post请求的例子和做法还是很多的,本人在项目中没有使用第三方的类库,利用了Android原生类库HttpURLConnection做了一次文件上传,代码逻辑不复杂,就是要理解Http协议的过程和耐心+细心的调试:下面是一个实战例子,测试成功:

如需了解Http文件上传中Http 协议的原理:请参考本人的另外一篇文章:

从HTTP的multipart/form-data分析看C#后台 HttpWebRequest文件上传

https://blog.csdn.net/elie_yang/article/details/80710059

这里再写一个Java版本的文件上传:

public static String upload(String uploadUrl,String fileName, Map map, byte[] bytesData) {        try {            final String newLine = "\r\n"; // 换行符            final String boundaryPrefix = "--"; //边界前缀            // 定义数据分隔线            final String boundary = String.format("=========%s",System.currentTimeMillis());            URL url = new URL(uploadUrl);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setRequestMethod("POST");            // 发送POST请求必须设置如下两行            conn.setDoOutput(true);            conn.setDoInput(true);            conn.setUseCaches(false);            // 设置请求头参数            conn.setRequestProperty("connection", "Keep-Alive");            conn.setRequestProperty("Charsert", "UTF-8");            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);            OutputStream out = new DataOutputStream(conn.getOutputStream());            String keyValue = "Content-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n";            byte[] parameterLine= (boundaryPrefix+boundary+newLine).getBytes();            //构建请求参数            if(map!=null&&map.size()>0){                for (Entry e : map.entrySet()) {                   byte[] keyValueBytes = String.format(keyValue,e.getKey(),e.getValue()).getBytes();                   out.write(parameterLine);                   out.write(keyValueBytes);                }            }            StringBuilder sb = new StringBuilder();            sb.append(boundaryPrefix);            sb.append(boundary);            sb.append(newLine);            // 文件参数            sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + fileName + "\"" + newLine);            sb.append("Content-Type:application/octet-stream");            // 参数头设置完以后需要两个换行,然后才是参数内容            sb.append(newLine);            sb.append(newLine);            // 将参数头的数据写入到输出流中            out.write(sb.toString().getBytes());//            InputStream inputStream = FormatTools.getInstance().Byte2InputStream(bytesData);//            // 数据输入流,用于读取文件数据//            DataInputStream in = new DataInputStream(inputStream);//            byte[] bufferOut = new byte[1024];//            int bytes = 0;//            // 每次读1KB数据,并且将文件数据写入到输出流中//            while ((bytes = in.read(bufferOut)) != -1) {//                out.write(bufferOut, 0, bytes);//            }            out.write(bytesData);            // 最后添加换行            out.write(newLine.getBytes());//            in.close();            // 定义最后数据分隔线,即--加上boundary再加上--。            byte[] end_data = (newLine + boundaryPrefix + boundary + boundaryPrefix + newLine).getBytes();            // 写上结尾标识            out.write(end_data);            out.flush();            out.close();            // 定义BufferedReader输入流来读取URL的响应            StringBuffer sbOutPut=new StringBuffer();            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));            String line = null;            while ((line = reader.readLine()) != null) {                sbOutPut.append(line);            }            return sbOutPut.toString();        } catch (Exception e) {            System.out.println("发送POST请求出现异常!" + e);            e.printStackTrace();            return null;        }    }

接下来的问题是:Android UI主线程直接发起网络请求时会报错:

有段英文描述说的很明白:The exception that is thrown when an application attempts to perform a networking operation on its main thread.

意思是:当应用程序在主线程里尝试执行一个网络操作时会得到这个错误:解决办法很多,例如Handler post Message或AysncTask等;例如下面的代码:

private class UploadImageTask extends AsyncTask  {        @Override        protected Object doInBackground(Object[] objects) {            String requestHost = mcontext.getString(R.string.host_url);            ShareFileHelper fh = new ShareFileHelper();            Bitmap bmp = ScreenShot.takeScreenShot(view);            return fh.uploadImage(requestHost,"abc_456.jpg", bmp);        }        @Override        protected void onPostExecute(Object obj) {            String urlResult = obj.toString();            txtUrl.setText(urlResult);            Bitmap bitmap = QRCodeUtil.createQRCodeBitmap(urlResult,300,300);            imageView.setImageBitmap(bitmap);            super.onPostExecute(obj);        }    }

上面是一段上传图片,并生产二维码的过程。写到这里有一个思考:如果程序中有大量的网络请求需要也要这样定义大量AsyncTask子类吗?是否有HttpUrlConnection的异步执行方式,例如 asyncExecute(). 这样可以简化UI线程的代码量。调用也十分方便。可是SDK库没有这样的接口,百度得来可以对HttpURLConnection进行异步封装,也是把Thread的调用封装到请求中,实际执行没有测试过:

贴代码参考:

参考源:对android HttpUrlConnection的轻量级封装(仿xutils3) 

https://blog.csdn.net/qq_35596407/article/details/52528412

private static Handler handler = new Handler();    public static void get(final Map strMap, final String strUrl, final HttpCallBack callBack) {        Thread thread = new Thread() {            @Override            public void run() {                HttpURLConnection connection = null;                InputStream is = null;                try {                    StringBuilder stringBuffer = new StringBuilder(strUrl);                    stringBuffer.append("?");                    for (Object key : strMap.keySet()) {                        stringBuffer.append(key + "=" + strMap.get(key) + "&");                    }                    stringBuffer.deleteCharAt(stringBuffer.length() - 1);                    URL url = new URL(stringBuffer.toString());                    connection = (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("GET");                    connection.setConnectTimeout(10 * 1000);                    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {                        is = connection.getInputStream();                        final String result = InputStreamToString(is);                        handler.post(new Runnable() {                            @Override                            public void run() {                                callBack.onSuccess(result);                            }                        });                    } else {                        throw new Exception("ResponseCode:" + connection.getResponseCode());                    }                } catch (final Exception e) {                    e.printStackTrace();                    handler.post(new Runnable() {                        @Override                        public void run() {                            callBack.onError(e);                        }                    });                } finally {                    if (connection != null) connection.disconnect();                    if (is != null) try {                        is.close();                    } catch (IOException e) {                        e.printStackTrace();                    }                    handler.post(new Runnable() {                        @Override                        public void run() {                            callBack.onFinish();                        }                    });                }            }        };        thread.start();    }    public static void post(final Map strMap, final String strUrl, final HttpCallBack callBack) {        Thread thread = new Thread() {            @Override            public void run() {                HttpURLConnection connection = null;                OutputStream os = null;                InputStream is = null;                try {                    StringBuilder stringBuilder = new StringBuilder();                    for (Object key : strMap.keySet()) {                        stringBuilder.append(key + "=" + strMap.get(key) + "&");                    }                    stringBuilder.deleteCharAt(stringBuilder.length() - 1);                    URL url = new URL(strUrl);                    connection = (HttpURLConnection) url.openConnection();                    connection.setRequestMethod("POST");                    connection.setConnectTimeout(10 * 1000);                    connection.setDoOutput(true);                    connection.setDoInput(true);                    connection.setUseCaches(false);                    connection.setRequestProperty("Charset", "utf-8");                    connection.connect();                    os = connection.getOutputStream();                    os.write(stringBuilder.toString().getBytes());                    os.flush();                    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {                        is = connection.getInputStream();                        final String result = InputStreamToString(is);                        handler.post(new Runnable() {                            @Override                            public void run() {                                callBack.onSuccess(result);                            }                        });                    } else {                        throw new Exception("ResponseCode:" + connection.getResponseCode());                    }                } catch (final Exception e) {                    handler.post(new Runnable() {                        @Override                        public void run() {                            callBack.onError(e);                        }                    });                } finally {                    if (connection != null) connection.disconnect();                    try {                        if (is != null) is.close();                        if (os != null) os.close();                    } catch (IOException e) {                        e.printStackTrace();                    }                    handler.post(new Runnable() {                        @Override                        public void run() {                            callBack.onFinish();                        }                    });                }            }        };        thread.start();    }    public static String InputStreamToString(InputStream is) throws IOException {        ByteArrayOutputStream os = new ByteArrayOutputStream();        byte[] data = new byte[1024];        int len = -1;        while ((len = is.read(data)) != -1) {            os.write(data, 0, len);        }        os.flush();        os.close();        String result = new String(data, "UTF-8");        return result;    }    public interface HttpCallBack {        public void onSuccess(String result);        public void onError(Exception e);        public void onFinish();    }

附加一个利用URLConnection的Post和Get请求:

public static String sendPost(String url, String param) {        String charset = "utf-8";        PrintWriter out = null;        BufferedReader in = null;        String result = "";        String line;        StringBuffer sb=new StringBuffer();        try {            URL realUrl = new URL(url);            // 打开和URL之间的连接            URLConnection conn = realUrl.openConnection();            // 设置通用的请求属性 设置请求格式            conn.setRequestProperty("contentType", charset);            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");            //设置超时时间            conn.setConnectTimeout(30000);            conn.setReadTimeout(30000);            // 发送POST请求必须设置如下两行            conn.setDoOutput(true);            conn.setDoInput(true);            // 获取URLConnection对象对应的输出流            out = new PrintWriter(conn.getOutputStream());            // 发送请求参数            out.print(param);            // flush输出流的缓冲            out.flush();            // 定义BufferedReader输入流来读取URL的响应    设置接收格式            in = new BufferedReader(                    new InputStreamReader(conn.getInputStream(),charset));            while ((line = in.readLine()) != null) {                sb.append(line);            }            result=sb.toString();        } catch (Exception e) {            System.out.println("发送 POST请求出现异常!"+e);            e.printStackTrace();        }        //使用finally块来关闭输出流、输入流        finally{            try{                if(out!=null){                    out.close();                }                if(in!=null){                    in.close();                }            }            catch(IOException ex){                ex.printStackTrace();            }        }        return result;    }public static String sendGet(String url, String param) {        String result = "";        String charset = "utf-8";        String line;        StringBuffer sb=new StringBuffer();        BufferedReader in = null;        try {            String urlNameString = url + "?" + param;            URL realUrl = new URL(urlNameString);            // 打开和URL之间的连接            URLConnection conn = realUrl.openConnection();            // 设置通用的请求属性 设置请求格式            conn.setRequestProperty("contentType", charset);            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");            //设置超时时间            conn.setConnectTimeout(30000);            conn.setReadTimeout(30000);            // 建立实际的连接            conn.connect();            // 定义 BufferedReader输入流来读取URL的响应,设置接收格式            in = new BufferedReader(new InputStreamReader(                    conn.getInputStream(),charset));            while ((line = in.readLine()) != null) {                sb.append(line);            }            result=sb.toString();        } catch (Exception e) {            System.out.println("发送GET请求出现异常!" + e);            e.printStackTrace();        }        // 使用finally块来关闭输入流        finally {            try {                if (in != null) {                    in.close();                }            } catch (Exception e2) {                e2.printStackTrace();            }        }        return result;    }

 

更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. Python技巧匿名函数、回调函数和高阶函数
  3. python list.sort()根据多个关键字排序的方法实现
  4. android EditText设置不可写
  5. android“设置”里的版本号
  6. 在Fragment中设置控件点击方法,执行失败。
  7. android中文api(89)——ViewManager
  8. Android(安卓)闹钟管理类的使用
  9. Android设置通知栏/状态栏透明改变通知栏颜色和app最上部分颜色

随机推荐

  1. 如何让Android横竖屏切换时不销毁当前act
  2. 【30篇突击 android】源码统计 十三
  3. 【Android】安卓中常用的图片加载方法
  4. Android(安卓)获取当前日期 时间
  5. Android(安卓)格式化内部存储
  6. Android获取设备状态栏status bar高度的
  7. android文件缓存,并SD卡创建目录未能解决
  8. android布局属性详解
  9. 阻止android软键盘自动弹出
  10. android 中 系统日期时间的获取