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

1.GET请求:html

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

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

优势:代码方便编写web

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";

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

相关文章
相关标签/搜索