zoukankan      html  css  js  c++  java
  • Android(java)学习笔记153:采用post请求提交数据到服务器(qq登录案例)

    1.POST请求:

     数据是以流的方式写给服务器

    优点:(1)比较安全 (2)长度不限制

    缺点:编写代码比较麻烦

     

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

    我们修改之前编写的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>
        <h3>GET方式提交数据</h3>
        <form action="LoginServlet" method="get">
      请输入QQ账号: <input type="text" name="qq"> <br/>
      请输入QQ密码: <input type="password" name="password"> <br/>
        <input type="submit" value="登录">
        </form>
        
        <br>
        <hr>
        <h3>POST方式提交数据</h3>
          <form action="LoginServlet" method="post">
      请输入QQ账号: <input type="text" name="qq"> <br/>
      请输入QQ密码: <input type="password" name="password"> <br/>
        <input type="submit" value="登录">
        </form>
    </body>
    </html>

    将修改过的jsp代码在Tomcat服务器上运行,如下:

    我们在"POST方式提交数据"一栏,输入正确的QQ 账号和QQ密码,如下的然后提交出现如下错误:

    这是因为在LoginServlet中只有doGet()方法,对于POST请求,服务器自然是接收不到POST请求的数据包,自然会出现上面的错误,添加doPost()方法即可:

    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和密码是否正确
             if("10086".equals(qq) && "123456".equals(password)) {
                 response.getOutputStream().write("Login Success".getBytes());
             }else {
                 response.getOutputStream().write("Login Failed".getBytes());
             }
             
        }
        
        /**
         * 添加的doPost()方法,响应post数据请求
         */
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            System.out.println("post过来的数据");
            doGet(req, resp);
        }
    
    }

    这个时候我们再次刷新之前的错误页面,就会出现如下效果:

    类似这里如果我们没有输入正确的数据信息,就会显示" Login Failed"

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

    POST请求如何写代码,我们还是先在360浏览器抓包数据分析一下,再去考虑

    在Android下编写代码实现POST请求,如下:

    步骤:

    •//重要,记得设置请求方式post
      conn.setRequestMethod("POST");
    •//重要,记得设置数据的类型
      conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
     String data = "qq="+qq+"&password="+pwd;
    •//重要,记得设置数据的长度
     conn.setRequestProperty("Content-Length", String.valueOf(data.length()));

    •//重要,记得给服务器写数据
     conn.setDoOutput(true);//声明要给服务器写数据
    •//重要,把数据写给服务器
     conn.getOutputStream().write(data.getBytes());

    (1)MainActivity.java:

      1 package com.himi.post;
      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                 //post请求提交数据
     98                 //String path = "http://localhost:8080/web/LoginServlet";这里不能写成localhost
     99                 try {
    100                     String path = getString(R.string.serverip);
    101                     URL url = new URL(path);
    102                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    103                     //重要,记得设置请求方式post
    104                     conn.setRequestMethod("POST");
    105                     //重要,记得设置数据的类型
    106                     conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    107                     String data = "qq="+qq+"&password="+pwd;
    108                     //重要,记得设置数据的长度
    109                     conn.setRequestProperty("Content-Length", String.valueOf(data.length()));
    110                     
    111                     //重要,记得给服务器写数据
    112                     conn.setDoOutput(true);//声明要给服务器写数据
    113                     //重要,把数据写给服务器
    114                     conn.getOutputStream().write(data.getBytes());
    115                     
    116                     int code = conn.getResponseCode();
    117                     if(code == 200) {
    118                         InputStream is = conn.getInputStream();
    119                         String result = StreamTools.readStream(is);
    120                         showToastInAnyThread(result);
    121                     }else {
    122                         showToastInAnyThread("请求失败");
    123                     }
    124                 } catch (Exception e) {
    125                     e.printStackTrace();
    126                     showToastInAnyThread("请求失败");
    127                 }
    128             };
    129         }.start();
    130         
    131     }
    132     
    133     /**
    134      * 显示土司 在主线程更新UI
    135      * @param text
    136      */
    137     public void showToastInAnyThread(final String text) {
    138         runOnUiThread(new Runnable() {
    139             
    140             public void run() {
    141                 Toast.makeText(MainActivity.this, text, 0).show();
    142                 
    143             }
    144         });
    145     }
    146 }

    工具类还是StreamTools,如下:

     1 package com.himi.post;
     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 }

     

    (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账号或密码时候,如下:

    输入QQ账号:10000,QQ密码:123123,结果如下;

    当我们输入QQ账号或者密码是正确的时候:

    比如,我们输入QQ账号:10086,输入密码:123456,结果如下:

    同时服务器端也出现了数据接收的记录,如下:

  • 相关阅读:
    qt install (1)
    learning rewind func
    learning strrchr func
    learning memchr func
    git lfs setpu(4)
    大端与小端
    git branch/meger step(3)
    git log/show/HEAD step(2)
    调用外部EXE文件
    获取计算机上的所有进程
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4783469.html
Copyright © 2011-2022 走看看