美文网首页
[Java]开发安卓,你得掌握的Java知识14——网络数据传输

[Java]开发安卓,你得掌握的Java知识14——网络数据传输

作者: 入梦瞌睡 | 来源:发表于2019-08-24 00:45 被阅读0次

0.前言

  • 上面两篇文章,
    讲解了网络中,底层的数据传输的原理(Socket)

  • 本文则着重讲解实际情况中,我们如何使用Java进行数据的传输(上传、下载等)

  • 若想要了解“类”等其他主要知识,可以去看前面的文章

  • 由于最终目的是要开发安卓app,
    因此这里使用的IDE是AS(Android Studio)
    (不会使用的可以参考下面这篇文章中的例子)
    [Java]开发安卓,你得掌握的Java知识2

1.准备工作

在读本文前,你需要做好以下准备:

  • (1)要配置好apache服务器
  • (2)电脑中配置了php,可以写php代码
  • (3)大致了解前后端交互
  • (4)可以的话,最好去了解一下html的表单<form>
  • 推荐新手使用wampserver 64,
    它集成了php、apache、MYSQL数据库
  • 直接安装、运行wampserver 64,就可以免去配置php、apache的复杂操作。

2.基础知识讲解


URL的一些奥秘

  • url就是我们在地址栏输入的网址
    一般我们可能只会注意到www.xxx.com这部分,
    后面的内容,外行人可能以为是乱码
  • 其实,url的每一个部分都有它对应的意思,只是我们未必能知道而已
  • www.xxx.com这部分叫域名,其实是与ip地址有映射关系的字符串,我们>访问的所有网页,其实都是接入网络中的某台计算机中的内容(这些计算机一般叫做服务器)

  • 域名后面的那些用斜杠隔开的,其实是对应的文件夹,我们访问的网页,就是ip地址所指向的计算机中,某个指定文件夹下面的某个html文件(当然可能是jsp什么的)

  • 如果看到有?name=jack&age=12之类的格式,其实就是向对应的文件传参数,实际上就是在说:
    name = jack , age = 12
    把这两个参数传过去

  • 比如这一点可以在微博中有一定作用


  • is_hot=1表示按照微博的火热程度来排序
    如果改成is_all=1,那么就会按照时间排序,这一点十分有用

Get与Post

  • get与post是两种传递数据的方式,他们最主要的区别在于:
get:

①传递的数据会出现在地址栏中(就是上面所说的?name=jack&age=12)
②传递的数据不能太多
③由于数据会出现在地址栏,因此不安全
④虽然不安全,但是我们可以通过修改地址栏的参数传递,来改变一些东西(比如上面微博的那个例子is_all与is_hot)

post:

①传递的数据会出现在地址栏中
②由于数据会出现在地址栏,因此安全
③可以一次传递大量数据
④代码编写比get方法略微复杂一点

PHP简单语法:

  • 变量的定义:
    $name = "jack"

  • 输出/返回内容:
    echo $name;或者echo "jack"

  • 变量的获取:
    $age = $_GET["age"];
    注意:

  • 这里的GET表示是用GET方法传递数据,因此要用$_GET来获取穿过来的数据

  • "age"是传递数据的时候指定的名字,如果是用html传递的话,就是写在标签中的name(这个name是标签的一个参数)
    <input type="text" name="age">

3.具体实现方法

本文会wampserver64来使用php、apache服务器

第一步

先写一个php文件,来作为接受、返回数据

<?php 
    $name = $_POST["fname"];
    $age = $_POST["age"];
    echo $name." ".$age."岁"; 
?> 
  • 简单来说就是定义了两个变量name和age
    然后返回
    $name $age岁

第二步

把这个php文件放在wamp64\www下面
www是wampserver这个集成软件的根目录
默认的apache服务器的根目录在htdocs

第三步

在java程序中书写传递数据的函数
(我知道代码很长很吓人,代码后面会有逐句分析)

public static void post() throws IOException {
        //1.创建URL对象
        URL url = new URL("http://127.0.0.1/AndroidTest/test1.5.php");
        //2.创建HttpURLConnection对象
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        //3.设置请求方式为post
        connection.setRequestMethod("POST");
        //设置有输出流(说明需要上传,默认值为false)
        connection.setDoOutput(true);
        //设置输入流,默认为true(服务器肯定会返回数据
        connection.setDoInput(true);
        //4.准备上传的数据
        String data = "fname=jack&age=12";

        //5.开始上传 要得到输出流对象(不断向服务器输出)
        OutputStream os = connection.getOutputStream();
        //data是字符串,要转换为字节
        os.write(data.getBytes());
        os.flush();//写完了

        //6,接收服务器端返回的数据
        InputStream is = connection.getInputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            System.out.println(new String(buf,0,len));
        }
    }

POST请求方式

  • 首先,我们实际用java在网络中传递数据,不会像之前那样直接用Socket,原因是:
    Socket有局限性,我们只能在Socket中放ip地址和端口,但是
    无法让socket知道访问该ip地址中的哪个文件

  • 所以我们用的是封装了Socket的URL类来实现数据传递,
    URL的构造参数中放的是欲访问的网址

  • 使用HTTPURLConnection的原因是要设置请求方式和输出流
    因为请求方式默认为GET,所以post才需要设置请求方式

  • String data就是想要发送给指定文件的内容,虽然是post方式,但是也是要按照类似get方式来写(只是开头没有?)

  • 输出流用的是字节流OutputStream,
    getBytes()可以将字符串变为字节数组

  • 读取返回的内容用的是InputStream,InputStream后面几行都是常规操作,如果不熟悉的可以去看之前的文章:
    [Java]开发安卓,你得掌握的Java知识9

执行结果:(要找一个main函数调用post())


GET请求方式

java代码差不多(要简单一些):

public static void getParams() throws IOException {
        String path = "http://127.0.0.1/AndroidTest/test.php?fname=jack&age=12";
        URL url = new URL(path);

        //1.5.指明请求方式,默认为get

        //2.获取连接的对象(URLConnection封装了socket,socket可以做的,URLConnection都可以做)
        URLConnection connection = url.openConnection();

        //接受服务器端的数据
        InputStream is = connection.getInputStream();
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            System.out.println(new String(buf,0,len));
        }
    }

主要区别在于:

  • 将要传递的数据放到了path中,不需要额外传数据

  • 不需要去设置请求方式

  • php文件中的 _POST要改为_GET

传递文件

public static void getImage() throws IOException {
        //URL
        URL url = new URL("http://localhost/1.jpg");

        //获取与服务器连接的对象
        URLConnection connection = url.openConnection();

        //读取下载的内容 - 获取输入流
        InputStream is = connection.getInputStream();

        //创建文件保存的位置,路径自己定义
        String desPath ="D:\\AndroidStudioProjects\\AndroidCourse\\JavaCourse1Day1\\course1day1\\src\\main\\java\\course1day14\\1.jpg";
        FileOutputStream fos = new FileOutputStream(desPath);

        //具体的下载操作
        byte[] buf = new byte[1024];
        int len;
        while ((len = is.read(buf)) != -1) {
            fos.write(buf,0,len);
        }
    }
  • URL、URLConnection的操作和上面的POST、GET一样

-下面的InputStream到最后的while那部分代码,
就是经典的文件的拷贝,先用InputStream读取文件到缓存,再用FileOutputStream将文件从缓存中读出
只不过这次是从服务器中把文件拷贝到本地

  • byte[]是字节数组,新手可能没见过,它的目的就是在读取文件时,找一个地方放你要读取到的东西的一部分,然后将这次读到的内容写到硬盘中,要反复多次这样的操作,直至将整个文件拷贝完
    (当然,每次读写的单位还是一个字节,只是字节数组能一次性放下1024个字节而已)

4.总结

(1)本文讲解了实际情况中,如何实现网络中的数据传递,比起使用底层的socket进行交互,封装好的URL更加方便
(2)虽然访问服务器可以使用URL这种封装好的类,但是数据的读写依然要使用InputStream和OutputStream这些类,因此即使看起来很复杂,也有必要多多熟悉字节、字符输入输出流的使用方法

相关文章

网友评论

      本文标题:[Java]开发安卓,你得掌握的Java知识14——网络数据传输

      本文链接:https://www.haomeiwen.com/subject/iwqxectx.html