1.GET请求:

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

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

优点:代码方便编写

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

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

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

代码内容如下:

 package com.himi.web;

 import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String qq = request.getParameter("qq");
String password = request.getParameter("password");
System.out.println("qq:"+qq);
System.out.println("password:"+password); //模拟服务器操作,查询数据库,看qq和密码是否正确. response.getOutputStream()获得一个输出流,向浏览器写入数据(提示数据).这里是输出Output,服务器输出到浏览器
if("10086".equals(qq) && "123456".equals(password)) {
response.getOutputStream().write("Login Success".getBytes());
}else {
response.getOutputStream().write("Login Failed".getBytes());
} } }

刚刚我们说过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代码如下:

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>???????</title>
</head>
<body> <form action="LoginServlet" method="get">
请输入QQ账号: <input type="text" name="qq"> <br/>
请输入QQ密码: <input type="password" name="password"> <br/>
<input type="submit" value="登录">
</form>
</body>
</html>

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

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

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

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

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

详细的抓取数据包如下:

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

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

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

同样抓取的数据包为:

上面提到的Response的数据长度是(字符数),如下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:

 package com.itheima.qqlogin;

 import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity {
private static final String Tag = "MainActivity";
private EditText et_qq;
private EditText et_pwd;
private CheckBox cb_remember; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查询关心的控件
et_qq = (EditText) findViewById(R.id.et_qq);
et_pwd = (EditText) findViewById(R.id.et_pwd);
cb_remember = (CheckBox) findViewById(R.id.cb_remember);
Log.i(Tag,"oncreate 被调用");
//完成数据的回显。
readSavedData();
}
//读取保存的数据
private void readSavedData() {
// getFilesDir() == /data/data/包名/files/ 获取文件的路径 一般系统是不会清理的。 用户手工清理,系统会有提示。
// getCacheDir()== /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存 用户手工清理系统没有提示
File file = new File(getFilesDir(),"info.txt");
if(file.exists()&&file.length()>0){
try {
//FileInputStream fis = new FileInputStream(file);
FileInputStream fis =this.openFileInput("info.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
//214342###abcdef
String info = br.readLine();
String qq = info.split("###")[0];
String pwd = info.split("###")[1];
et_qq.setText(qq);
et_pwd.setText(pwd);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 登陆按钮的点击事件,在点击事件里面获取数据
* @param view
*/
public void login(View view){
final String qq = et_qq.getText().toString().trim();
final String pwd = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(pwd)){
Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
return;
}
//判断用户是否勾选记住密码。
if(cb_remember.isChecked()){
//保存密码
Log.i(Tag,"保存密码");
try {
// File file = new File(getFilesDir(),"info.txt");
// FileOutputStream fos = new FileOutputStream(file);
FileOutputStream fos = this.openFileOutput("info.txt", 0);
//214342###abcdef
fos.write((qq+"###"+pwd).getBytes());
fos.close();
Toast.makeText(this, "保存成功", 0).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "保存失败", 0).show();
}
}else{
//无需保存密码
Log.i(Tag,"无需保存密码");
} //登录的操作,网络的请求
new Thread() {
public void run() {
//String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
try {
String path = getString(R.string.serverip);
URL url = new URL(path+"?qq="+qq+"&password="+pwd);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code == 200) {
InputStream is = conn.getInputStream();
String result = StreamTools.readStream(is);
showToastInAnyThread(result);
}else {
showToastInAnyThread("请求失败");
}
} catch (Exception e) {
e.printStackTrace();
showToastInAnyThread("请求失败");
}
};
}.start(); } /**
* 显示土司 在主线程更新UI
* @param text
*/
public void showToastInAnyThread(final String text) {
runOnUiThread(new Runnable() { @Override
public void run() {
Toast.makeText(MainActivity.this, text, 0).show(); }
});
}
}

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

 package com.itheima.qqlogin;

 import java.io.ByteArrayOutputStream;
import java.io.InputStream; /**
* 流的工具类
* @author Administrator
*
*/
public class StreamTools {
/**
* 把输入流的内容转换成字符串
* @param is
* @return null解析失败, string读取成功
*/
public static String readStream(InputStream is) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
String result = baos.toString();
baos.close();
return result; }
}

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

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

具体用法:

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

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

(2)布局文件activity_main.xml:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical" > <ImageView
android:layout_width="200dip"
android:layout_height="200dip"
android:src="@drawable/ic_launcher" /> <EditText
android:id="@+id/et_qq"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入qq号码" /> <EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword" /> <CheckBox
android:id="@+id/cb_remember"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="记住密码"
/> <Button
android:onClick="login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登陆" />
</LinearLayout>

布局效果图如下:

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

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

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

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

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

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

(5)小结:

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

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

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

Android(java)学习笔记209:采用get请求提交数据到服务器(qq登录案例)的更多相关文章

  1. Android(java)学习笔记210:采用post请求提交数据到服务器(qq登录案例)

    1.POST请求:  数据是以流的方式写给服务器 优点:(1)比较安全 (2)长度不限制 缺点:编写代码比较麻烦   2.我们首先在电脑模拟下POST请求访问服务器的场景: 我们修改之前编写的logi ...

  2. Android(java)学习笔记153:采用post请求提交数据到服务器(qq登录案例)

    1.POST请求:  数据是以流的方式写给服务器 优点:(1)比较安全 (2)长度不限制 缺点:编写代码比较麻烦   2.我们首先在电脑模拟下POST请求访问服务器的场景: 我们修改之前编写的logi ...

  3. Android(java)学习笔记212:中文乱码的问题处理(qq登录案例)

    1.我们在之前的笔记中LoginServlet.java中,我们Tomcat服务器回复给客户端的数据是英文的"Login Success","Login Failed&q ...

  4. Android(java)学习笔记155:中文乱码的问题处理(qq登录案例)

    1. 我们在之前的笔记中LoginServlet.java中,我们Tomcat服务器回复给客户端的数据是英文的"Login Success","Login Failed& ...

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

    1.GET请求:    组拼url的路径,把提交的数据拼装url的后面,提交给服务器. 缺点:(1)安全性(Android下提交数据组拼隐藏在代码中,不存在安全问题)  (2)长度有限不能超过4K(h ...

  6. Java学习笔记:基本输入、输出数据操作实例分析

    Java学习笔记:基本输入.输出数据操作.分享给大家供大家参考,具体如下: 相关内容: 输出数据: print println printf 输入数据: Scanner 输出数据: JAVA中在屏幕中 ...

  7. Android 采用post方式提交数据到服务器

    接着上篇<Android 采用get方式提交数据到服务器>,本文来实现采用post方式提交数据到服务器 首先对比一下get方式和post方式: 修改布局: <LinearLayout ...

  8. Android 采用get方式提交数据到服务器

    首先搭建模拟web 服务器,新建动态web项目,servlet代码如下: package com.wuyudong.web; import java.io.IOException; import ja ...

  9. Java学习笔记之[ 利用扫描仪Scanner进行数据输入 ]

    /*********数据的输入********//**利用扫描仪Scanner进行数据输入 怎么使用扫描仪Scanner *1.放在类声明之前,引入扫描仪 import java.util.Scann ...

随机推荐

  1. trash目录: ~/.local/share/Trash

    trash目录:~/.local/share/Trash

  2. hdu1054Strategic Game(树形DP)

    链接 归属简单树形DP 挺简单的 跟第一道一样 就是我跑偏了题意..以为要覆盖点 纠结啊 推了N久 推不出啊 然后就郁闷了 打了局游戏 边想边打 实在想不出 看下题解 跑偏了 分两种情况D 方程见代码 ...

  3. USACO4.13Fence Loops(无向图最小环)

    最近脑子有点乱 老是不想清楚就啪啪的敲 敲完之后一看 咦..样例都过不去 仔细一想 这样不对啊 刚开始就写了一SPFA 最后发现边跟点的关系没处理好 删了..写dfs..还是没转化好 开始搜解题方法 ...

  4. apache点NET环境

    1.首先 下载一个mod_aspdotnet-2.2.0.2006-setup-r2.msi 2.安装好后在apache的moudles目录会生成一个mod_aspdotnet.so文件 3.修改ht ...

  5. [HDU 1011] Starship Troopers

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. RESTLET开发实例(三)基于spring的REST服务

    http://www.lifeba.org/arch/restlet_spring_3.html 前面两篇文章,我们介绍了基于JAX-RS的REST服务以及Application的Rest服务.这里将 ...

  7. HDU5647 DZY Loves Connecting 树形DP

    (先奉上jcvb大神的官方题解)BC 76 div 1 1002 对于每个结点i,统计出f[i]表示包含i的连通集有多少个,那么容易看出答案就是所有f[i]的和. 要计算f[i]是经典的树形DP问题. ...

  8. JDK源码重新编译——支持eclipse调试JDK源码--转载

    最近在研究jdk源码,发现debug时无法查看源码里的变量值. 因为sun提供的jdk并不能查看运行中的局部变量,需要重新编译一下rt.jar. 下面这六步是编译jdk的具体步骤: Step 1:   ...

  9. lru cache java

    http://www.acmerblog.com/leetcode-lru-cache-lru-5745.html acm之家的讲解是在是好,丰富 import java.util.LinkedHas ...

  10. POJ-1981 Circle and Points 单位圆覆盖

    题目链接:http://poj.org/problem?id=1981 容易想到直接枚举两个点,然后确定一个圆来枚举,算法复杂度O(n^3). 这题还有O(n^2*lg n)的算法.将每个点扩展为单位 ...