• Android(java)学习笔记152:采用get请求提交数据到服务器(qq登录案例)


    1.GET请求:

       组拼url的路径,把提交的数据拼装url的后面,提交给服务器。

    缺点:(1)安全性(Android下提交数据组拼隐藏在代码中,不存在安全问题)  (2)长度有限不能超过4K(http协议限制),IE浏览器限制至1K

    优点:代码方便编写

    2.我们首先在电脑模拟下GET请求访问服务器的场景

    (1)使用Eclipse 新建一个 " 动态web项目 ",如下:

    (2)然后编写一个servlet程序(运行在服务端),命名为" LoginServlet ",如下:

    代码内容如下:

     1 package com.himi.web;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.annotation.WebServlet;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 
    10 /**
    11  * Servlet implementation class LoginServlet
    12  */
    13 @WebServlet("/LoginServlet")
    14 public class LoginServlet extends HttpServlet {
    15     private static final long serialVersionUID = 1L;
    16 
    17     /**
    18      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    19      */
    20     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    21          String qq = request.getParameter("qq");
    22          String password = request.getParameter("password");
    23          System.out.println("qq:"+qq);
    24          System.out.println("password:"+password);
    25          
    26//模拟服务器操作,查询数据库,看qq和密码是否正确. response.getOutputStream()获得一个输出流,向浏览器写入数据(提示数据).这里是输出Output,服务器输出到浏览器
    27          if("10086".equals(qq) && "123456".equals(password)) {
    28              response.getOutputStream().write("Login Success".getBytes());
    29          }else {
    30              response.getOutputStream().write("Login Failed".getBytes());
    31          }
    32          
    33     }
    34 
    35 }

    刚刚我们说过GET请求方法,把提交的数据组拼到url路径上提交到服务器上,所以这里request.getParameter();

    (3)接下来编写一个jsp动态页面(区别于html静态页面),首先我们说一下jsp和html区别,如下:

    jsp和html区别:

          •HTML页面是静态页面,也就是事先由用户写好放在服务器上,由web服务器向客户端发送;JSP页面是动态页面,有JSP容器执行该页面的Java代码部分然后实时生成的页面.

          •定义上HTML页面是静态页面可以直接运行,JSP页面是动态页它运行时需要转换成servlet。 

          •HTML能直接打开,jsp只能发布到Tomact等服务器上才能打开

          •他们的表头不同,这个是JSP的头“ <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>”在表头中有编码格式和倒入包等。

          •很好区分的在jsp中用<%%>就可以写Java代码了,而html没有<%%>。

    编写一个login.jsp代码,在WebContent文件夹下

    login.jsp代码如下:

     1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     2 <html>
     3 <head>
     4 <%@ page language="java" contentType="text/html; charset=utf-8"
     5     pageEncoding="utf-8"%>
     6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     7 <title>???????</title>
     8 </head>
     9 <body>
    10     
    11     <form action="LoginServlet" method="get">
    12   请输入QQ账号: <input type="text" name="qq"> <br/>
    13   请输入QQ密码: <input type="password" name="password"> <br/>
    14     <input type="submit" value="登录">
    15     </form>
    16 </body>
    17 </html>

    右击login.jsp文件," 运行方式 "--> " 在服务器上运行 ";运行的结果如下:

    (4)打开360浏览器抓包分析http通信的详细过程:

    • 打开360浏览器,地址栏输入:http://localhost:8080/web/login.jsp,结果如下:

    •随便输入一个QQ账号和QQ密码,输入QQ账号10000,输入QQ密码123123如下:

    观察下面,我们可以观察到我们输入的QQ账号和QQ密码已经传输到Tomcat服务器上

    详细的抓取数据包如下:

    上面提到的Response的数据长度是12(字符数),如下Response数据内容

    • 输入正确的QQ账号和QQ密码,如下:

    由下面我们知道了我们输入的QQ账号和QQ密码已经传输到Tomcat服务器上面: 

    同样抓取的数据包为:

    上面提到的Response的数据长度是13(字符数),如下Response数据内容

    (5)小结:

    •首先我们让编写的Servlet的程序在LoginServlet在Tomcat运行,Tomcat则处于一直监听状态(监听外界Http--GET请求),当我们在login.jsp输入QQ账号和QQ密码时候,点击"登录"之后,浏览器会把QQ账号和QQ密码组拼到url路径上,把这些数据提交给Tomcat服务器;

    •此时处于监听状态的Tomcat服务器则根据接收到http的请求数据包中提取到QQ账号和QQ密码,比对正确的QQ账号和QQ密码(现实则是比对数据库的QQ账号和QQ密码);

    •根据QQ账号和QQ密码匹配状况,反馈不同的信息,匹配成功返回"Login Success" ,反之匹配失败返回"Login Failed";

    •返回的数据包被电脑浏览器获取,然后提取出返回数据,显示在浏览上,这样浏览器上就出现了"Login Success"或"Login Failed";

    3.Android下模拟出手机GET请求访问远端服务器场景:

    (1)新建一个Android工程,命名为”qq登录",下面首先是MainActivity.java

      1 package com.itheima.qqlogin;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.File;
      5 import java.io.FileInputStream;
      6 import java.io.FileOutputStream;
      7 import java.io.InputStream;
      8 import java.io.InputStreamReader;
      9 import java.net.HttpURLConnection;
     10 import java.net.MalformedURLException;
     11 import java.net.URL;
     12 
     13 import android.app.Activity;
     14 import android.os.Bundle;
     15 import android.text.TextUtils;
     16 import android.util.Log;
     17 import android.view.View;
     18 import android.widget.CheckBox;
     19 import android.widget.EditText;
     20 import android.widget.Toast;
     21 
     22 public class MainActivity extends Activity {
     23     private static final String Tag = "MainActivity";
     24     private EditText et_qq;
     25     private EditText et_pwd;
     26     private CheckBox cb_remember;
     27 
     28     @Override
     29     protected void onCreate(Bundle savedInstanceState) {
     30         super.onCreate(savedInstanceState);
     31         setContentView(R.layout.activity_main);
     32         //查询关心的控件
     33         et_qq = (EditText) findViewById(R.id.et_qq);
     34         et_pwd = (EditText) findViewById(R.id.et_pwd);
     35         cb_remember = (CheckBox) findViewById(R.id.cb_remember);
     36         Log.i(Tag,"oncreate 被调用");
     37         //完成数据的回显。
     38         readSavedData();
     39     }
     40     //读取保存的数据
     41     private void readSavedData() {
     42         // getFilesDir() == /data/data/包名/files/  获取文件的路径 一般系统是不会清理的。 用户手工清理,系统会有提示。
     43         // getCacheDir()==  /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存 用户手工清理系统没有提示
     44         File file = new File(getFilesDir(),"info.txt");
     45         if(file.exists()&&file.length()>0){
     46             try {
     47                 //FileInputStream fis = new FileInputStream(file);
     48                 FileInputStream fis =this.openFileInput("info.txt");
     49                 BufferedReader br = new BufferedReader(new InputStreamReader(fis));
     50                 //214342###abcdef
     51                 String info = br.readLine();
     52                 String qq = info.split("###")[0];
     53                 String pwd = info.split("###")[1];
     54                 et_qq.setText(qq);
     55                 et_pwd.setText(pwd);
     56                 fis.close();
     57             } catch (Exception e) {
     58                 e.printStackTrace();
     59             }
     60         }
     61     }
     62     /**
     63      * 登陆按钮的点击事件,在点击事件里面获取数据
     64      * @param view
     65      */
     66     public void login(View view){
     67         final String qq = et_qq.getText().toString().trim();
     68         final String pwd = et_pwd.getText().toString().trim();
     69         if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(pwd)){
     70             Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
     71             return;
     72         }
     73         //判断用户是否勾选记住密码。
     74         if(cb_remember.isChecked()){
     75             //保存密码
     76             Log.i(Tag,"保存密码");
     77             try {
     78 //                File file = new File(getFilesDir(),"info.txt");
     79 //                FileOutputStream fos = new FileOutputStream(file);
     80                 FileOutputStream fos = this.openFileOutput("info.txt", 0);
     81                 //214342###abcdef
     82                 fos.write((qq+"###"+pwd).getBytes());
     83                 fos.close();
     84                 Toast.makeText(this, "保存成功", 0).show();
     85             } catch (Exception e) {
     86                 e.printStackTrace();
     87                 Toast.makeText(this, "保存失败", 0).show();
     88             }
     89         }else{
     90             //无需保存密码
     91             Log.i(Tag,"无需保存密码");
     92         }
     93         
     94         //登录的操作,网络的请求
     95         new Thread() {
     96             public void run() {
     97                 //String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
     98                 try {
     99                     String path = getString(R.string.serverip);
    100                     URL url = new URL(path+"?qq="+qq+"&password="+pwd);
    101                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    102                     conn.setRequestMethod("GET");
    103                     int code = conn.getResponseCode();
    104                     if(code == 200) {
    105                         InputStream is = conn.getInputStream();
    106                         String result = StreamTools.readStream(is);
    107                         showToastInAnyThread(result);
    108                     }else {
    109                         showToastInAnyThread("请求失败");
    110                     }
    111                 } catch (Exception e) {
    112                     e.printStackTrace();
    113                     showToastInAnyThread("请求失败");
    114                 }
    115             };
    116         }.start();
    117         
    118     }
    119     
    120     /**
    121      * 显示土司 在主线程更新UI
    122      * @param text
    123      */
    124     public void showToastInAnyThread(final String text) {
    125         runOnUiThread(new Runnable() {
    126             
    127             @Override
    128             public void run() {
    129                 Toast.makeText(MainActivity.this, text, 0).show();
    130                 
    131             }
    132         });
    133     }
    134 }

    其中使用到的工具类StreamTools如下:

     1 package com.itheima.qqlogin;
     2 
     3 import java.io.ByteArrayOutputStream;
     4 import java.io.InputStream;
     5 
     6 /**
     7  * 流的工具类
     8  * @author Administrator
     9  *
    10  */
    11 public class StreamTools {
    12     /**
    13      * 把输入流的内容转换成字符串
    14      * @param is
    15      * @return null解析失败, string读取成功
    16      */
    17     public static String readStream(InputStream is) throws Exception {
    18             ByteArrayOutputStream baos = new ByteArrayOutputStream();
    19             byte[] buffer = new byte[1024];
    20             int len = 0;
    21             while((len = is.read(buffer)) != -1) {
    22                 baos.write(buffer, 0, len);
    23             }
    24             is.close();
    25             String result = baos.toString();
    26             baos.close();
    27             return result;
    28             
    29         
    30     }
    31 }

    ByteArrayOutputStream类:是在创建它的实例时,程序内部创建一个byte型别数组的缓冲区

    ByteArrayInputStream:的实例向数组中写入或读出byte型数据。

    具体用法:

             ByteArrayOutputStream:    可以捕获内存缓冲区的数据,转换成字节数组

             ByteArrayInputStream:     可以将字节数组转化为输入流

    (2)布局文件activity_main.xml

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:gravity="center_horizontal"
     5     android:paddingLeft="10dp"
     6     android:paddingRight="10dp"
     7     android:orientation="vertical" >
     8 
     9     <ImageView
    10         android:layout_width="200dip"
    11         android:layout_height="200dip"
    12         android:src="@drawable/ic_launcher" />
    13 
    14     <EditText
    15         android:id="@+id/et_qq"
    16         android:inputType="text"
    17         android:layout_width="match_parent"
    18         android:layout_height="wrap_content"
    19         android:hint="请输入qq号码" />
    20     
    21      <EditText
    22          android:id="@+id/et_pwd"
    23          android:layout_width="match_parent"
    24          android:layout_height="wrap_content"
    25          android:hint="请输入密码"
    26          android:inputType="textPassword" />
    27      
    28      <CheckBox 
    29          android:id="@+id/cb_remember"
    30            android:layout_width="match_parent"
    31          android:layout_height="wrap_content"
    32          android:text="记住密码"
    33          />
    34 
    35      <Button
    36          android:onClick="login" 
    37          android:layout_width="match_parent"
    38          android:layout_height="wrap_content"
    39          android:text="登陆"
    40          
    41          />
    42 </LinearLayout>

    布局效果图如下:

    (3) 布署程序到模拟器上,我们进行演示:

    当我们输入QQ账号:10000,QQ密码:123123,效果如下:

    点击登录,出现”Login Failed",如下:

    与此同时,我们的Tomcat服务器端也接收到了账号和密码

    (4)当我们输入正确的QQ账号和密码时候:

    同时我们看到了Tomcat服务器上面,也收到QQ账号和QQ密码的信息,如下:

    (5)小结:

    我们点击"登录",程序中提取到QQ账号 和 QQ密码,组拼成url网络访问路径,访问Tomcat服务器;

    Tomcat服务器得到账号和密码,会在LoginServlet程序中进行比对,如果匹配成功就返回"Login Success",匹配失败就是返回"Login Failed";

    返回的信息数据,手机端程序获取之后,以土司的形式打印出来,提示用户登录的情况。

  • 相关阅读:
    Kafka与RabbitMQ区别
    Illegal instruction 问题的解决方法
    Debian 6 , 十个串口为什么只识别到了 6个 剩下4 个被禁止了
    微信二次认证 C#
    修改XtraMessageBox的内容字体大小
    svn: E155017: Checksum mismatch while updating 校验错误的解决方法
    再生龙恢复分区后修复引导或debian linux修复引导 三部曲
    Clonezilla制作镜像时报错: errextfsclone.c:bitmap free count err
    我用windows live Writer 写个日志试试看
    Debian下签名无法验证
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4783000.html
Copyright © 2020-2023  润新知