• Android(java)学习笔记176: 远程服务的应用场景(移动支付案例)


    一. 移动支付:

          用户需要在移动终端提交账号、密码以及金额等数据 到 远端服务器。然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端。用户提交账号、密码以及金额等数据都是比较敏感的数据,这些数据不能让外界获取

          阿里等等支付宝平台把支付的逻辑封装起来,只给我们提供一个方法去调用,这样提高了安全性。当我们用户提交账号、密码以及金额等数据,点击"支付"的时候,支付宝平台已经调用方法加密数据这个支付逻辑是远程服务,为了安全,防止信息泄露),提交给远端服务器(解密数据,逻辑判断)。

    二. 通过一个移动支付的框架案例说明远程服务的应用:

    1.这是支付宝公司内部开发的框架,内部进行很多加密,别人反编译也是无法获得什么有用的信息的,支付宝公司开发出这个"远程安全支付服务",可以供用户调用,但是无法获取内部实现逻辑,数据怎么加密,怎么解密,这些都是不清楚,这样安全才能得到保障,这样用户才能放心使用移动支付服务。

    如下,这里我们新建的"Alipay"工程,模拟的就是阿里云服务终端提供了支付逻辑。

    (1)新建一个Android工程,命名为"Alipay",如下:

    (2)我们知道,这个用户提交的数据加密过程是不能暴露给其他人的,这是很敏感的,所以这里我们要使用的远程服务service使用远程服务service的目的是因为只暴露给用户可调用的方法,不提供具体实现的逻辑,提高信息安全性。用户点击"支付",实际上是调用阿里云支付的远程服务的支付逻辑方法

    这里我们定义一个服务Service,为AlipayService,如下:

     1 package com.himi.alipay;
     2 
     3 import android.app.Service;
     4 import android.content.Intent;
     5 import android.os.Binder;
     6 import android.os.IBinder;
     7 
     8 /**
     9  * 
    10  * 阿里云安全支付的服务
    11  *
    12  */
    13 public class AlipayService extends Service {
    14     //获取远程服务的秘书
    15     private class MyBinder extends Binder implements IService {
    16 
    17         public int callSafePay(String username, String password, float money,
    18                 long timestamp) {
    19             // TODO 自动生成的方法存根
    20             return safePay(username, password, money, timestamp);
    21         }
    22         
    23     }
    24 
    25     @Override
    26     public IBinder onBind(Intent intent) {
    27         // TODO 自动生成的方法存根
    28         return null;
    29     }
    30     
    31     /**
    32      * 
    33      * @param username 用户名
    34      * @param password  密码
    35      * @param money    金额
    36      * @param timestamp  时间戳  (用户提交支付的时间)
    37      * @return 404用户名密码错误   200支付成功   503支付超过限额   (现实开发中,这种逻辑状态码估计很多)
    38      */
    39     public int safePay(String username, String password, float money, long timestamp) {
    40         System.out.println("加密username");
    41         System.out.println("加密password");
    42         System.out.println("连接支付宝的服务器,检查用户名和密码是否正确");
    43         if("123".equals(password)&&"abc".equals(username)) {
    44 
    45         }else {
    46             return 404;
    47         }
    48         
    49         System.out.println("连接银行网关,检查账户余额是否充足");
    50         
    51         //银行的消费限额
    52         if(money < 5000) {
    53             return 200;
    54         }else {
    55             System.out.println("超过银行限额支付失败");
    56             return 503;
    57         }
    58     }
    59 
    60 }

    为了调用远程服务的safePay,必须提供一个接口IService供外界使用,如下:

    1 package com.himi.alipay;
    2 
    3 public interface IService {
    4     public int callSafePay(String key, String username, String password, float money, long timestamp);
    5 
    6 }

    这个时候工程如下图:

    (3)接下来,就是找到工程目录下的IService.java文件,改扩展名".java" 为 ".aidl ",同时修改AlipayService服务代码,这个参考:Android(java)学习笔记232:Android进程间通讯(IPC)之AIDL (面试常问),修改结果如下:

    AlipayService如下:

     1 package com.himi.alipay;
     2 
     3 import android.app.IntentService;
     4 import android.app.Service;
     5 import android.content.Intent;
     6 import android.os.Binder;
     7 import android.os.IBinder;
     8 
     9 /**
    10  * 
    11  * 阿里云安全支付的服务
    12  *
    13  */
    14 public class AlipayService extends Service {
    15     
    16     private class MyBinder extends IService.Stub{
    17 
    18         public int callSafePay(String key, String username, String password, float money,
    19                 long timestamp) {
    20             // TODO 自动生成的方法存根
    21             return safePay(key,username, password, money, timestamp);
    22         }
    23         
    24     }
    25 
    26     @Override
    27     public IBinder onBind(Intent intent) {
    28         // TODO 自动生成的方法存根
    29         return new MyBinder();
    30     }
    31     
    32     /**
    33      * @param key   支付宝公司提供给(其他公司)需要支付业务服务的密钥
    34      * @param username 用户名
    35      * @param password  密码
    36      * @param money    金额
    37      * @param timestamp  时间戳  (用户提交支付的时间)
    38      * @return 404用户名密码错误   200支付成功   503支付超过限额   (现实开发中,这种逻辑状态码估计很多)
    39      */
    40     public int safePay(String key,String username, String password, float money, long timestamp) {
    41         System.out.println("加密username");
    42         System.out.println("加密password");
    43         System.out.println("连接支付宝的服务器,检查用户名和密码是否正确");
    44         if("123".equals(password)&&"abc".equals(username)) {
    45 
    46         }else {
    47             return 404;
    48         }
    49         
    50         System.out.println("连接银行网关,检查账户余额是否充足");
    51         
    52         //银行的消费限额
    53         if(money < 5000) {
    54             return 200;
    55         }else {
    56             System.out.println("超过银行限额支付失败");
    57             return 503;
    58         }
    59     }
    60 
    61 }

    此时工程变成如下:

    (4)就这样远程的服务平台,我们就是搭建好了。

    3. 以后别的公司,要使用支付的操作,那就使用上面支付宝定义的支付服务即可。

        下面我们模拟出一家公司开发出一种游戏APP需要使用支付服务,这个游戏为"捕鱼达人"

    (1)新建一个Android工程,命名为" Alipay_捕鱼达人 ",如下:

          如果我们的公司想要接入支付宝的服务,我们必须向支付宝服务的公司进行申请(提供我们公司的营业执照、公司的类型;以及告诉他们,我们是哪一个应用哪一个包名要接入这个支付应用),提交完申请,如果没有问题,这个时候支付宝公司,才会提供给你SDK的接口,让你调用支付的逻辑服务。上面提到的参数Key,就是支付宝公司提供给申请公司的密钥,从而使得申请的公司可以使用到这个支付逻辑业务。如果没有这个key,支付宝服务会认为这是一个非法的业务请求,不会提供支付业务(支付宝公司赚钱的业务)。

    (2)首先来到布局文件activity_main.xml文件,如下:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context="com.himi.fish.MainActivity" >
    10 
    11     <Button
    12         android:layout_width="wrap_content"
    13         android:layout_height="wrap_content"
    14         android:layout_centerHorizontal="true"
    15         android:layout_centerVertical="true"
    16         android:onClick="pay"
    17         android:text="花费2元买炮弹" />
    18 
    19 </RelativeLayout>

    布局效果如下:

    (3)在Alipay_捕鱼达人 "的src目录下,新建一个包"com.himi.alipay",这个包名和前面远程支付包名一样。

    (现实开发中,支付宝公司会提供给申请公司----支付业务包名方法接口

    效果如下图:

    (4)进行MainActivity.java代码编写,如下:

     1 package com.himi.fish;
     2 
     3 import com.himi.alipay.IService;
     4 
     5 import android.app.Activity;
     6 import android.content.ComponentName;
     7 import android.content.Intent;
     8 import android.content.ServiceConnection;
     9 import android.os.Bundle;
    10 import android.os.IBinder;
    11 import android.os.RemoteException;
    12 import android.view.View;
    13 import android.widget.Toast;
    14 
    15 public class MainActivity extends Activity {
    16     
    17     private MyConn conn;
    18     private IService iService;
    19 
    20     @Override
    21     protected void onCreate(Bundle savedInstanceState) {
    22         super.onCreate(savedInstanceState);
    23         setContentView(R.layout.activity_main);
    24         Intent service = new Intent();
    25         service.setAction("com.himi.alipay");
    26         conn = new MyConn();
    27         bindService(service, conn, BIND_AUTO_CREATE);
    28     }
    29     
    30     private class MyConn implements ServiceConnection {
    31 
    32         @Override
    33         public void onServiceConnected(ComponentName name, IBinder service) {
    34             iService = IService.Stub.asInterface(service);            
    35         }
    36 
    37         @Override
    38         public void onServiceDisconnected(ComponentName name) {
    39             // TODO 自动生成的方法存根
    40             
    41         }
    42         
    43     }
    44 
    45 
    46     public void pay(View view) {
    47         try {
    48             int result = iService.callSafePay("123456", "abc", "123", 505.02f,
    49                     System.currentTimeMillis());
    50             switch (result) {
    51             case 404:
    52                 Toast.makeText(this, "用户名密码错误", 0).show();
    53                 break;
    54 
    55             case 200:
    56                 Toast.makeText(this, "支付成功", 0).show();
    57                 break;
    58             case 503:
    59                 Toast.makeText(this, "支付超过限额", 0).show();
    60                 break;
    61             default:
    62                 break;
    63             }
    64 
    65         } catch (RemoteException e) {
    66             // TODO 自动生成的 catch 块
    67             e.printStackTrace();
    68         }
    69     }
    70 }

    (5)布署程序到模拟器上,如下:

    点击按钮 " 花费2元买炮弹 " ,如下打印土司提示,同时观察logcat打印的日志,如下:

     

    与此同时,logcat打印的日志为:

    倘若我们输入的密码 或者 账号不正确,如下:

    与此同时,logcat打印的日志为:

    倘若我们输入的现金超过了限制的金额,如下:

    与此同时,logcat打印的日志为:

    三、远程服务的应用场景总结

    1. 超级大公司,写出来逻辑供别的程序员使用。

    2. 手机企业,手机定制厂商,提供一些方便的逻辑供程序员使用。

    比如snoy手机,人脸识别。

    3. 系统的源码,内置很多的服务。电话的服务TelephoneManager, 布局填充器的服务LayoutInflaterService等等

  • 相关阅读:
    js基础整理总结
    pyinstaller打包django项目成exe以及遇到的一些问题
    Django对接SQL Server服务
    死锁
    python 之路
    Python注释
    Django2.1迁移数据库出错
    一行 Python 代码实现并行
    【转载】Python 类定义与对象
    关于盒模型布局在UC上的兼容处理
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4802841.html
Copyright © 2020-2023  润新知