微信小程序获取用户手机号存数据库,前后端都有《Java后台版 》

开发这个功能的时候走了很多弯路磨了很多时间,我发一下我自己用的来帮助大家

流程图
微信小程序获取用户手机号存数据库,前后端都有《Java后台版 》_第1张图片
前端
index.wxml

    我的首页内容
      
     

index.js

Page({
  data: {
      //判断小程序的API,回调,参数,组件等是否在当前版本可用。
      canIUse: wx.canIUse('button.open-type.getUserInfo'),
      
      isHide: false
  },



  onLoad: function() {
  
  },
  //获取用户code
  getcode: function(res){
    var that = this;
    // 查看是否授权
    wx.getSetting({
        success: function(res) {
            if (res.authSetting['scope.userInfo']) {
                wx.getUserInfo({
                    success: function(res) {
                        // 用户已经授权过,不需要显示授权页面,所以不需要改变 isHide 的值 根据自己的需求有其他操作再补充 我这里实现的是在用户授权成功后,调用微信的 wx.login 接口,从而获取code
                        wx.login({
                         //  success: res => {
                          // 获取到用户的 code 之后:res.code 可以传给后台,再经过解析获取用户的 openid 代码如下
                             //   wx.login({
                                  success: function (res) {
                                  console.log("用户的code:" + res.code);
                               //     if (res.code) { //使用小程序登录接口完成后端用户登录
                                      wx.request({
                                        url: "填写服务器接口一定要HTTPS的可以去natapp买一个" +"/getOpenid",
                                        data: {
                                          code: res.code,
                                          appid: "自己的APPID",
                                          secret: "自己的APPSECRET",        
                                        },
                                        method:'POST',
                                        header: {
                                        'content-type': 'application/json' // POST请求
                                        },
                                        success: function (res) {
                                          //把openid保存到缓存里
                                          wx.setStorageSync("openid", res.openid);
                                          wx.setStorageSync("session_key", res.session_key);
                                        }
                                      })
                                //     } else {
                                 //      console.log('获取用户登录态失败!' + res.errMsg)
                          
                                   //  }
                                  }
                                });
                         //   }
                       // });
                    }
                });
            } else {
                // 用户没有授权
                // 改变 isHide 的值,显示授权页面
                that.setData({
                  isHide: true
     });
            }
        }
    });
  },
  //获取用户开发信息
  bindGetUserInfo: function(e) {
      if (e.detail.userInfo) {
          //用户按了允许授权按钮
          var that = this;
          // 获取到用户的信息了,打印到控制台上看下
          console.log("用户的信息如下:");
          console.log(e.detail.openid);
          console.log(e.detail.userInfo);
          //授权成功后,通过改变 isHide 的值,让实现页面显示出来,把授权页面隐藏起来
          that.setData({
              isHide: false
          });
      } else {
          //用户按了拒绝按钮
          wx.showModal({
              title: '警告',
              content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
              showCancel: false,
              confirmText: '返回授权',
              success: function(res) {
                  // 用户没有授权成功,不需要改变 isHide 的值
                  if (res.confirm) {
                      console.log('用户点击了“返回授权”');
                  }
              }
          });
      }
  },
//获取用户手机号授权按钮
getPhoneNumber: function (e) {
    var app = getApp();
    wx.request({
      url: "填写服务器接口一定要是HTTPS的可以去natapp买一个" +"/postPhoneNumber",  //解密手机号码接口
      data: {
        encryptedData: e.detail.encryptedData,
        iv: e.detail.iv
      },
      method:'POST',
      header: {
      'content-type': 'application/json' // POST请求
      },

      success: function (res) {
        console.log(res.data.phoneNumber);
        wx.setStorageSync("phonenumber", res.data.phoneNumber);
        
      }
    })
   
  },

})

后端Java代码

Controller层代码

package com.pyx.wechatapplet2.conntroller.wechat;

import com.alibaba.fastjson.JSON;
import com.pyx.wechatapplet2.entity.user.Openid;
import com.pyx.wechatapplet2.util.AesCbcUtil;
import com.pyx.wechatapplet2.util.JDBCUtil;
import com.pyx.wechatapplet2.util.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@RestController
@Slf4j
public class WechatgetPhone {
    public  String Openid;
    public  String session_key;

    public String getOpenid() {
        return Openid;
    }

    public void setOpenid(String openid) {
        Openid = openid;
    }

    @PostMapping("/getOpenid")
    @Transactional(rollbackFor = Exception.class)
    public synchronized com.alibaba.fastjson.JSONObject getSessionKeyOropenid(@RequestBody Openid openid ) throws Exception {
        System.out.println("Openid code:" + openid.getCode());

        CloseableHttpClient httpclient = HttpClients.createDefault();
        //发送get请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        HttpGet httpget = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + "自己的APPID" + "&secret=" + "自己的appsecret" + "&js_code=" + openid.getCode() + "&grant_type=authorization_code");
        CloseableHttpResponse response = httpclient.execute(httpget);

        HttpEntity entity = response.getEntity();
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(entity));
        RedisUtil.setStringValue("session_key" , jsonObject.getString("session_key"));
        session_key=jsonObject.getString("session_key");
        Openid=jsonObject.getString("openid");
        System.out.println("Openid:" + Openid);
        RedisUtil.setStringValue("openid",jsonObject.getString("openid"));
        log.info(jsonObject.toJSONString());


        //----------------------------------解密用户信息-----------------------------------------
//        String userInfo = null;
//        JSONObject userInfoJSON = null;
//        Thread.sleep(500);
//        try {
//            byte[] resultByte = AES.decrypt(Base64.decodeBase64(openid.getEncryptedData()),
//                    Base64.decodeBase64(jsonObject.getString("session_key")),
//                    Base64.decodeBase64(openid.getIv()));
//
//            userInfo = new String(resultByte, "UTF-8");
//            System.out.println("userInfo:" + userInfo);
//            userInfoJSON = JSON.parseObject(userInfo);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        System.out.println("userInfo:" + userInfoJSON);
//----------------------------------解密用户信息-----------------------------------------

        return null;
    }

    //获取用户手机号信息
    @PostMapping(value ="/postPhoneNumber")
  //  @GetMapping(value = "/getPhoneNumber")
    public Object getPhoneNumber(@RequestBody Openid openid , @RequestParam(value = "param") String param) throws Exception {
        // 加密秘钥
        String sessionKey = RedisUtil.getStringValue("session_key");

        //手机号数据String类型
        String result = AesCbcUtil.decrypt(openid.getEncryptedData() , sessionKey , openid.getIv() , "UTF-8");
        System.out.println(result);
        //把String类型转变成JSONObject
        JSONObject resultObj = new JSONObject(result);//resultArray.optJSONObject(0);
        //用spring从JSONObject拿需要的数据
        String phoneNumber= resultObj.getString("phoneNumber");
        String watermark= resultObj.getString("watermark");
        JSONObject resultObj2 = new JSONObject(watermark);
        String appid=resultObj2.getString("appid");
        //数据库操作
        HttpServletRequest request = null;
        Connection connection=null;
        PreparedStatement ps=null;
        ResultSet rs;

        try{
            connection= JDBCUtil.getConnection();
            String selectSQL = "select * from user_information where phoneNumber = ?";
            ps=connection.prepareStatement(selectSQL);
            ps.setString(1,phoneNumber);
            ps.execute();
            String phone=null;
            rs=ps.executeQuery();
            while(rs.next()){
                phone = rs.getString("phoneNumber");//rs.getInt("UserName");
            }
            System.out.println(phone+"查询到的数据");
            if(phone==null){
            String sql="insert into user_information values(null,?,?,? ) ";
            ps=connection.prepareCall(sql);
            ps.setString(1,appid);
            ps.setString(2,phoneNumber);
            ps.setString(3,Openid);

            ps.execute();
            }else {
                System.out.println("已经有该数据");
            }
 //增加代码

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JDBCUtil.close(connection);
        }


        System.out.println("_____下面是拿到的数据_____");
        System.out.println(phoneNumber);
        System.out.println(watermark);
        System.out.println(appid);
        return result;

    }



}

手机号解密代码
AesCbcUtil

package com.yiqidaojia.wechatapplet2.util;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;

/**
 * Created by yfs on 2018/3/25.
 * 

* AES-128-CBC 加密方式 * 注: * AES-128-CBC可以自己定义“密钥”和“偏移量“。 * AES-128是jdk自动生成的“密钥”。 */ public class AesCbcUtil { static { //BouncyCastle是一个开源的加解密解决方案,主页在http://www.bouncycastle.org/ Security.addProvider(new BouncyCastleProvider()); } /** * AES解密 * * @param data //密文,被加密的数据 * @param key //秘钥 * @param iv //偏移量 * @param encodingFormat //解密后的结果需要进行的编码 * @return * @throws Exception */ public static String decrypt(String data, String key, String iv, String encodingFormat) throws Exception { // initialize(); //被加密的数据 byte[] dataByte = Base64.decodeBase64(data); //加密秘钥 byte[] keyByte = Base64.decodeBase64(key); //偏移量 byte[] ivByte = Base64.decodeBase64(iv); try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, encodingFormat); return result; } return null; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidParameterSpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } }

redis代码用于储存微信服务器发过来的session_key


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Redis工具类
 */
public class RedisUtil {
    private static Logger logger = LoggerFactory.getLogger(RedisUtil.class);
    /**
     * 默认过期时间,单位/秒, 60*60*2=2H, 两小时
     */
    private static final int DEFAULT_EXPIRE_TIME = 7200;
    private static List redisList;

    public static void init(List redisList) {
        RedisUtil.redisList = redisList;
    }

    // ------------------------ ShardedJedisPool ------------------------
    private static ShardedJedisPool shardedJedisPool;
    private static ReentrantLock INSTANCE_INIT_LOCL = new ReentrantLock(false);

    /**
     * 获取ShardedJedis实例
     *
     * @return
     */
    private static int timeout = 2;

    private static ShardedJedis getInstance() {
        if (shardedJedisPool == null) {
            try {
                if (INSTANCE_INIT_LOCL.tryLock(timeout, TimeUnit.SECONDS)) {
                    try {
                        if (shardedJedisPool == null) {
                            // JedisPoolConfig
                            JedisPoolConfig config = new JedisPoolConfig();
                            // 最大连接数, 默认8个
                            config.setMaxTotal(200);
                            // 最大空闲连接数, 默认8个
                            config.setMaxIdle(50);
                            // 设置最小空闲数
                            config.setMinIdle(8);
                            // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
                            config.setMaxWaitMillis(10000);
                            // 在获取连接的时候检查有效性, 默认false
                            config.setTestOnBorrow(true);
                            // 调用returnObject方法时,是否进行有效检查
                            config.setTestOnReturn(true);
                            // Idle时进行连接扫描
                            config.setTestWhileIdle(true);
                            //表示idle object evitor两次扫描之间要sleep的毫秒数
                            config.setTimeBetweenEvictionRunsMillis(30000);
                            //表示idle object evitor每次扫描的最多的对象数
                            config.setNumTestsPerEvictionRun(10);
                            //表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
                            config.setMinEvictableIdleTimeMillis(60000);

                            // JedisShardInfo List
                            List jedisShardInfos = new LinkedList();
                            for (Redis redis : redisList) {
                                String[] addressInfo = redis.getAddress().split(":");
                                String host = addressInfo[0];
                                int port = Integer.valueOf(addressInfo[1]);
                                JedisShardInfo jedisShardInfo = new JedisShardInfo(host, port, 10000);
                                if (redis.getPassword() != null && !"".equals(redis.getPassword())) {
                                    jedisShardInfo.setPassword(redis.getPassword());
                                }
                                jedisShardInfos.add(jedisShardInfo);
                            }
                            shardedJedisPool = new ShardedJedisPool(config, jedisShardInfos);
                            logger.info(">>>>>>>>>>> JedisUtil.ShardedJedisPool init success.");
                        }

                    } finally {
                        INSTANCE_INIT_LOCL.unlock();
                    }
                }

            } catch (InterruptedException e) {
                logger.error(e.getMessage(), e);
            }
        }

        if (shardedJedisPool == null) {
            throw new NullPointerException(">>>>>>>>>>> JedisUtil.ShardedJedisPool is null.");
        }

        ShardedJedis shardedJedis = shardedJedisPool.getResource();
        return shardedJedis;
    }

    // ------------------------ serialize and unserialize ------------------------

    /**
     * 将对象-->byte[] (由于jedis中不支持直接存储object所以转换成byte[]存入)
     *
     * @param object
     * @return
     */
    private static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            // 序列化
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
            logger.error("{}", e);
        } finally {
            try {
                oos.close();
                baos.close();
            } catch (IOException e) {
                logger.error("{}", e);
            }
        }
        return null;
    }

    /**
     * 将byte[] -->Object
     *
     * @param bytes
     * @return
     */
    private static Object unserialize(byte[] bytes) {
        ByteArrayInputStream bais = null;
        try {
            // 反序列化
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            logger.error("{}", e);
        } finally {
            try {
                bais.close();
            } catch (IOException e) {
                logger.error("{}", e);
            }
        }
        return null;
    }

    // ------------------------ jedis util ------------------------

    /**
     * Set String
     *
     * @param key
     * @param value
     * @param seconds 存活时间,单位/秒
     * @return
     */
    public static String setStringValue(String key, String value, int seconds) {
        String result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.setex(key, seconds, value);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * Set String (默认存活时间, 2H)
     *
     * @param key
     * @param value
     * @return
     */
    public static String setStringValue(String key, String value) {
        return setStringValue(key, value, DEFAULT_EXPIRE_TIME);
    }

    /**
     * Set Object
     *
     * @param key
     * @param obj
     * @param seconds 存活时间,单位/秒
     */
    public static String setObjectValue(String key, Object obj, int seconds) {
        String result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.setex(key.getBytes(), seconds, serialize(obj));
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * Set Object (默认存活时间, 2H)
     *
     * @param key
     * @param obj
     * @return
     */
    public static String setObjectValue(String key, Object obj) {
        return setObjectValue(key, obj, DEFAULT_EXPIRE_TIME);
    }

    /**
     * Get String
     *
     * @param key
     * @return
     */
    public static String getStringValue(String key) {
        String value = null;
        ShardedJedis client = getInstance();
        try {
            value = client.get(key);
        } catch (Exception e) {
            logger.info("", e);
        } finally {
            client.close();
        }
        return value;
    }

    /**
     * Get Object
     *
     * @param key
     * @return
     */
    public static Object getObjectValue(String key) {
        Object obj = null;
        ShardedJedis client = getInstance();
        int index = key.indexOf("forever-");
        try {
            byte[] bytes = client.get(key.getBytes());
            if (bytes != null && bytes.length > 0) {
                obj = unserialize(bytes);
            }
        } catch (Exception e) {
            logger.info("", e);
        } finally {
            client.close();
        }
        //重置过期时间
        if (index < 0) {
            expire(key, DEFAULT_EXPIRE_TIME);
        }
        return obj;
    }

    /**
     * Delete
     *
     * @param key
     * @return Integer reply, specifically:
     * an integer greater than 0 if one or more keys were removed
     * 0 if none of the specified key existed
     */
    public static Long del(String key) {
        Long result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.del(key);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * incrBy	value值加i
     *
     * @param key
     * @param i
     * @return new value after incr
     */
    public static Long incrBy(String key, int i) {
        Long result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.incrBy(key, i);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * exists
     *
     * @param key
     * @return Boolean reply, true if the key exists, otherwise false
     */
    public static Boolean exists(String key) {
        Boolean result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.exists(key);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * expire	重置存活时间
     *
     * @param key
     * @param seconds 存活时间,单位/秒
     * @return Integer reply, specifically:
     * 1: the timeout was set.
     * 0: the timeout was not set since the key already has an associated timeout (versions lt 2.1.3), or the key does not exist.
     */
    public static Long expire(String key, int seconds) {
        Long result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.expire(key, seconds);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }

    /**
     * expireAt		设置存活截止时间
     *
     * @param key
     * @param unixTime 存活截止时间戳
     * @return
     */
    public static Long expireAt(String key, long unixTime) {
        Long result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.expireAt(key, unixTime);
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }


    /**
     * Set Object(永久有效)
     *
     * @param key
     * @param obj
     */
    public static String setForeverObjectValue(String key, Object obj) {
        String result = null;
        ShardedJedis client = getInstance();
        try {
            result = client.set(key.getBytes(), serialize(obj));
        } catch (Exception e) {
            logger.info("{}", e);
        } finally {
            client.close();
        }
        return result;
    }
}

pom依赖

   

        
            org.projectlombok
            lombok
            true
        

        
            cn.hutool
            hutool-all
            4.1.21
        

        
            io.springfox
            springfox-swagger2
            2.9.2
        

        
            io.springfox
            springfox-swagger-ui
            2.9.2
        

        
            com.google.code.gson
            gson
            2.8.2
        

        
        
            com.alibaba
            druid
            1.1.10
        

        
        
            com.alibaba
            fastjson
            1.2.7
        



        
        
            com.squareup.okhttp3
            okhttp
            3.10.0
        

        
        
            redis.clients
            jedis
            2.9.0
        

        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.1.1
        


        
            org.springframework.boot
            spring-boot-configuration-processor
            true
        

        
        
            org.apache.ibatis
            ibatis-core
            3.0
        


        
        
            mysql
            mysql-connector-java
            8.0.15
        

        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        

        
        
            dom4j
            dom4j
            1.6.1
        




        
        
            org.apache.commons
            commons-lang3
            3.6
        
        
            commons-configuration
            commons-configuration
            1.10
        
        
            commons-io
            commons-io
            2.5
        
        
            org.apache.httpcomponents
            httpclient
        

        
            com.fasterxml
            classmate
            1.4.0
        

        
        
            cn.hutool
            hutool-all
            4.5.0
        
        
            org.bouncycastle
            bcprov-jdk15on
            1.55
        

        
            org.apache.httpcomponents
            httpclient
            4.3.5
        
        
            com.vaadin.external.google
            android-json
            0.0.20131108.vaadin1
        
        
            com.vaadin.external.google
            android-json
            0.0.20131108.vaadin1
        


    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


至此所有代码都完成了
在这里特别感谢一下帮助我的大佬 王子洋
这里是他的博客大家可以去看看
王子洋老师在B站有一个微信公众号的讲解视频大家感兴趣的可以去看一看名字是《Java开发之旅》

你可能感兴趣的:(微信小程序获取用户手机号存数据库,前后端都有《Java后台版 》)