Android通过HttpURLConnection连接服务器并进行数据传输

demo包含GET及POST数据传输方法,将数据以键值对的形式存储到JSONobject里面,与服务器进行数据交互。

1.申请网络权限,在AndroidManifest.xml加入

2.编写服务器连接与交互代码

WebAPI.java

public class WebAPI {
    //是否工作正常?
    public boolean isOK=true;

    //调用HttpURLConnectUtils对象完成API操作
    private HttpURLConnectUtils httpURLConnectUtils;
    //返回结果
    private String rlt;
    public String GetResult(){
        return rlt;
    }

    //操作是否完成
    private boolean IsCompleted = false;
    synchronized  boolean getIsCompleted(){
        return IsCompleted;
    }
    synchronized void setIsCompleted(boolean isCompleted){
        IsCompleted=isCompleted;
    }

    public WebAPI(){
        setIsCompleted(false);
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    httpURLConnectUtils = new HttpURLConnectUtils();
                }catch (IOException ioe){
                    isOK=false;
                }catch (JSONException je){
                    isOK=false;
                }
                setIsCompleted(true);
            }
        }.start();

        while (!getIsCompleted());
    }

    //执行Post
    public String DoHttpPost(final String mUrl, final Map parameter){
        if (!httpURLConnectUtils.isWebAPIok())
            return "";

        setIsCompleted(false);
        rlt="";
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    rlt = httpURLConnectUtils.DoHttpPost(mUrl, parameter);
                }catch (IOException ioe){
                }
                setIsCompleted(true);
            }
        }.start();

        while (!getIsCompleted());
        return rlt;
    }

    //执行Get
    public String DoHttpGet(final String mUrl){
        if (!httpURLConnectUtils.isWebAPIok())
            return "";

        rlt="";
        setIsCompleted(false);
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    rlt = httpURLConnectUtils.DoHttpGet(mUrl);
                }catch (IOException ioe){
                }
                setIsCompleted(true);
            }
        }.start();

        while (!getIsCompleted());
        return rlt;
    }

    //从指定网址利用Get方法获取一个指定文件id的文件,存储到SD卡指定位置filePath--文件夹已经存在
    //利用handler传送文件下载完成通知
    public void getFileFromWeb(final String mUrl, final String fileID, final String filePath, final Handler handler){
        if (!httpURLConnectUtils.isWebAPIok())
            return;

        new Thread(){
            @Override
            public void run() {
                super.run();
                boolean r=httpURLConnectUtils.getFileFromWeb(mUrl,fileID,filePath);
                Message msg=null;
                if (handler!=null) {
                    msg = handler.obtainMessage();
                    if (r)
                        msg.what = 0; //下载成功
                    else
                        msg.what = 1; //下载失败
                    msg.sendToTarget();
                }

            }
        }.start();
    }

    //从指定网址利用Get方法获取一个id对应的二维码文件,存储到SD卡指定位置filePath--文件夹已经存在
    public boolean getQRcodeFileFromWeb(final String mUrl, final String id, final String filePath){
        //下载Bitmap的Base64编码字符串
        String base64Pic=DoHttpGet(mUrl+"?id="+id);
        if (base64Pic == null || base64Pic.length()==0)
            return false;

        Bitmap bitmap = null;
        try {
            byte[] bitmapArray = Base64.decode(base64Pic.split(",")[1], Base64.DEFAULT);
            bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        //写入文件
        File sd_file=new File(Environment.getExternalStorageDirectory() + "/"+filePath);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(sd_file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
            bos.flush();
            bos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

HttpURLConnectUtils.java

public class HttpURLConnectUtils {
    //Web API使用的Token,在构造函数中获取,以后每次Get/Post时使用
    private static String token="";
    //Web API登录信息
    private String account = "System";
    private String passward = "123456";
    private String appKey = "openauth";

    //判断Web API操作是否正常?
    public boolean isWebAPIok(){
        if (token.trim().length()>0)
            return true;
        else
            return false;
    }

    public HttpURLConnectUtils() throws IOException, JSONException {
        //首次运行,需要获取Token
        final Map map = new HashMap<>();
        map.put("Account",account);
        map.put("Password",passward);
        map.put("AppKey", appKey);
        String rlt = DoHttpPost("", map);
        JSONObject demoJson = new JSONObject(rlt);
        token = demoJson.getString("token");
        System.out.println(token);
    }

    //执行post方法
    //mUrl--Post地址,parameter--参数信息(参数名,参数值)
    //返回值:JSON字符串
    public String DoHttpPost(String mUrl, Map parameter) throws IOException {
        URL url = new URL(mUrl);
        //初始化创建HttpURLConnection实例
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        //设置当前连接的参数
        httpURLConnection.setConnectTimeout(5000); //推荐设置网络延时,如果不设置此项,获取响应状态码时可能引起阻塞
        httpURLConnection.setDoOutput(true);    //可写
        httpURLConnection.setDoInput(true);    //可读
        httpURLConnection.setUseCaches(false); //不用缓存

        //设置HttpURLConnection请求头里面的属性
        //设定传送的内容类型是可序列化的java对象
        //(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
        httpURLConnection.setRequestProperty("Content-type", "application/json");
        httpURLConnection.setRequestProperty("accept", "application/json");
        if(token.length()>0) //非首次运行需要添加Token
            httpURLConnection.setRequestProperty("X-Token", token);
        //设置请求的方法
        httpURLConnection.setRequestMethod("POST");//Post请求

        //创建输出流,此时会隐含的进行connect
        OutputStream outputStream = httpURLConnection.getOutputStream();
        //创建字符流对象并用高效缓冲流包装它,便获得最高的效率,发送的是字符串推荐用字符流,其它数据就用字节流
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));

        String params = new String();
        JSONObject json = new JSONObject();
        try {
            Iterator> it = parameter.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = it.next();
                json.put(entry.getKey(), entry.getValue());
            }
            params = json.toString();
        }catch (Exception e){
        }
        //把json字符串写入缓冲区中
        bw.write(params);
        //提交参数
        bw.flush();
        outputStream.close();
        bw.close();

        //获取响应的状态码,判断是否请求成功
        int rltCode = httpURLConnection.getResponseCode();
        //获取响应状态码的描述,   正常返回"OK"
        String msg = httpURLConnection.getResponseMessage();
        if (rltCode != 200) //判断响应状态是否成功
        {
            return "Error Code--" + rltCode + ", Error Message--" + msg;
        }
        //接收返回值
        //创建文件流对象, InputStream-->InputStreamReader-->BufferedReader
        InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        //获取响应数据
        StringBuilder builder = new StringBuilder();
        //循环读取所有数据
        for (String s = bufferedReader.readLine(); s != null; s = bufferedReader.readLine()) {
            builder.append(s+"\n");
        }

        return builder.toString();
    }

    //执行get方法
    //mUrl--Get地址
    //返回值:JSON字符串
    public String DoHttpGet(String mUrl) throws IOException {

        URL url = new URL(mUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setConnectTimeout(5000);//推荐设置网络延时
        httpURLConnection.setReadTimeout(5000);//设置从主机读取数据超时(单位:毫秒)
        httpURLConnection.setRequestMethod("GET");

        httpURLConnection.setRequestProperty("accept", "application/json");
        httpURLConnection.setRequestProperty("X-Token", token); //添加Token

        httpURLConnection.connect(); //此处必须显式进行连接

        //以下同Post
        //获取响应的状态码,判断是否请求成功
        int rltCode = httpURLConnection.getResponseCode();
        String msg = httpURLConnection.getResponseMessage(); //获取响应状态码的描述, "OK"
        if (rltCode != 200) //判断响应状态是否成功
        {
            return "Error Code--" + rltCode + ", Error Message--" + msg;
        }

        //获取响应内容--读输入流
        InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuilder builder = new StringBuilder();
        for (String s = bufferedReader.readLine(); s != null; s = bufferedReader.readLine()) {
            builder.append(s);
        }

        return builder.toString();
    }

    //从指定网址利用Get方法获取一个指定文件id的文件,存储到SD卡指定位置filePath--文件夹已经存在
    public boolean getFileFromWeb(String mUrl, String fileID, String filePath){
        try {
            URL url = new URL(mUrl+"?id="+fileID);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(5000);//推荐设置网络延时
            httpURLConnection.setReadTimeout(5000);//设置从主机读取数据超时(单位:毫秒)
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestProperty("accept", "application/json");
            httpURLConnection.connect(); //此处必须显式进行连接

            //获取响应的状态码,判断是否请求成功
            if(httpURLConnection.getResponseCode()==HttpURLConnection.HTTP_OK){
                //获得网络字节输入流对象
                InputStream is=httpURLConnection.getInputStream();// 不是操作文件的吗
                //建立内存到SD卡的连接
                FileOutputStream fos=new FileOutputStream(
                        new File(Environment.getExternalStorageDirectory() + "/"+filePath));
                //写文件
                byte[] b=new byte[4 * 1024];
                int len=0;
                while((len=is.read(b))!=-1){  //先读到内存
                    fos.write(b, 0, len); //写入目标文件
                }
                fos.flush();
                fos.close();
            }
        }catch (IOException ioe){
            return false;
        }

        return true;
    }
}

3.补充一下,上述为用json传输数据,所以用字符串。但如果是图片之类的数据,需要用字节流,直接调用函数将图像之类的数据转化成Byte数据流,然后bw.write("比特流数据")即可。

你可能感兴趣的:(Android开发技术)