回调实现获取扫描人信息

1、扫码后微信回调本地方法,在本地方法获取扫描人信息步骤

2、准备工作

(1)在父service模块的pom文件导入依赖(已引入)。

(2)在service_wxlogin模块中com/atguigu/wxservice/util目录下中编写httpclient工具类HttpClientUtils.java。

java 复制代码
package com.atguigu.wxservice.util;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *  依赖的jar包有:commons-lang-2.6.jar、httpclient-4.3.2.jar、httpcore-4.3.1.jar、commons-io-2.4.jar
 * @author zhaoyb
 *
 */
public class HttpClientUtils {

   public static final int connTimeout=10000;
   public static final int readTimeout=10000;
   public static final String charset="UTF-8";
   private static HttpClient client = null;

   static {
      PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
      cm.setMaxTotal(128);
      cm.setDefaultMaxPerRoute(128);
      client = HttpClients.custom().setConnectionManager(cm).build();
   }

   public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception{
      return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
   }

   public static String postParameters(String url, String parameterStr,String charset, Integer connTimeout, Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception{
      return post(url,parameterStr,"application/x-www-form-urlencoded",charset,connTimeout,readTimeout);
   }

   public static String postParameters(String url, Map<String, String> params) throws ConnectTimeoutException,
         SocketTimeoutException, Exception {
      return postForm(url, params, null, connTimeout, readTimeout);
   }

   public static String postParameters(String url, Map<String, String> params, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
         SocketTimeoutException, Exception {
      return postForm(url, params, null, connTimeout, readTimeout);
   }

   public static String get(String url) throws Exception {
      return get(url, charset, null, null);
   }

   public static String get(String url, String charset) throws Exception {
      return get(url, charset, connTimeout, readTimeout);
   }

   /**
    * 发送一个 Post 请求, 使用指定的字符集编码.
    *
    * @param url
    * @param body RequestBody
    * @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
    * @param charset 编码
    * @param connTimeout 建立链接超时时间,毫秒.
    * @param readTimeout 响应超时时间,毫秒.
    * @return ResponseBody, 使用指定的字符集编码.
    * @throws ConnectTimeoutException 建立链接超时异常
    * @throws SocketTimeoutException  响应超时
    * @throws Exception
    */
   public static String post(String url, String body, String mimeType,String charset, Integer connTimeout, Integer readTimeout)
         throws ConnectTimeoutException, SocketTimeoutException, Exception {
      HttpClient client = null;
      HttpPost post = new HttpPost(url);
      String result = "";
      try {
         if (StringUtils.isNotBlank(body)) {
            HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
            post.setEntity(entity);
         }
         // 设置参数
         Builder customReqConf = RequestConfig.custom();
         if (connTimeout != null) {
            customReqConf.setConnectTimeout(connTimeout);
         }
         if (readTimeout != null) {
            customReqConf.setSocketTimeout(readTimeout);
         }
         post.setConfig(customReqConf.build());

         HttpResponse res;
         if (url.startsWith("https")) {
            // 执行 Https 请求.
            client = createSSLInsecureClient();
            res = client.execute(post);
         } else {
            // 执行 Http 请求.
            client = HttpClientUtils.client;
            res = client.execute(post);
         }
         result = IOUtils.toString(res.getEntity().getContent(), charset);
      } finally {
         post.releaseConnection();
         if (url.startsWith("https") && client != null&& client instanceof CloseableHttpClient) {
            ((CloseableHttpClient) client).close();
         }
      }
      return result;
   }


   /**
    * 提交form表单
    *
    * @param url
    * @param params
    * @param connTimeout
    * @param readTimeout
    * @return
    * @throws ConnectTimeoutException
    * @throws SocketTimeoutException
    * @throws Exception
    */
   public static String postForm(String url, Map<String, String> params, Map<String, String> headers, Integer connTimeout,Integer readTimeout) throws ConnectTimeoutException,
         SocketTimeoutException, Exception {

      HttpClient client = null;
      HttpPost post = new HttpPost(url);
      try {
         if (params != null && !params.isEmpty()) {
            List<NameValuePair> formParams = new ArrayList<NameValuePair>();
            Set<Entry<String, String>> entrySet = params.entrySet();
            for (Entry<String, String> entry : entrySet) {
               formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
            post.setEntity(entity);
         }

         if (headers != null && !headers.isEmpty()) {
            for (Entry<String, String> entry : headers.entrySet()) {
               post.addHeader(entry.getKey(), entry.getValue());
            }
         }
         // 设置参数
         Builder customReqConf = RequestConfig.custom();
         if (connTimeout != null) {
            customReqConf.setConnectTimeout(connTimeout);
         }
         if (readTimeout != null) {
            customReqConf.setSocketTimeout(readTimeout);
         }
         post.setConfig(customReqConf.build());
         HttpResponse res = null;
         if (url.startsWith("https")) {
            // 执行 Https 请求.
            client = createSSLInsecureClient();
            res = client.execute(post);
         } else {
            // 执行 Http 请求.
            client = HttpClientUtils.client;
            res = client.execute(post);
         }
         return IOUtils.toString(res.getEntity().getContent(), "UTF-8");
      } finally {
         post.releaseConnection();
         if (url.startsWith("https") && client != null
               && client instanceof CloseableHttpClient) {
            ((CloseableHttpClient) client).close();
         }
      }
   }

   /**
    * 发送一个 GET 请求
    *
    * @param url
    * @param charset
    * @param connTimeout  建立链接超时时间,毫秒.
    * @param readTimeout  响应超时时间,毫秒.
    * @return
    * @throws ConnectTimeoutException   建立链接超时
    * @throws SocketTimeoutException   响应超时
    * @throws Exception
    */
   public static String get(String url, String charset, Integer connTimeout,Integer readTimeout)
         throws ConnectTimeoutException,SocketTimeoutException, Exception {

      HttpClient client = null;
      HttpGet get = new HttpGet(url);
      String result = "";
      try {
         // 设置参数
         Builder customReqConf = RequestConfig.custom();
         if (connTimeout != null) {
            customReqConf.setConnectTimeout(connTimeout);
         }
         if (readTimeout != null) {
            customReqConf.setSocketTimeout(readTimeout);
         }
         get.setConfig(customReqConf.build());

         HttpResponse res = null;

         if (url.startsWith("https")) {
            // 执行 Https 请求.
            client = createSSLInsecureClient();
            res = client.execute(get);
         } else {
            // 执行 Http 请求.
            client = HttpClientUtils.client;
            res = client.execute(get);
         }

         result = IOUtils.toString(res.getEntity().getContent(), charset);
      } finally {
         get.releaseConnection();
         if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
            ((CloseableHttpClient) client).close();
         }
      }
      return result;
   }


   /**
    * 从 response 里获取 charset
    *
    * @param ressponse
    * @return
    */
   @SuppressWarnings("unused")
   private static String getCharsetFromResponse(HttpResponse ressponse) {
      // Content-Type:text/html; charset=GBK
      if (ressponse.getEntity() != null  && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
         String contentType = ressponse.getEntity().getContentType().getValue();
         if (contentType.contains("charset=")) {
            return contentType.substring(contentType.indexOf("charset=") + 8);
         }
      }
      return null;
   }



   /**
    * 创建 SSL连接
    * @return
    * @throws GeneralSecurityException
    */
   private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
      try {
         SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] chain,String authType) throws CertificateException {
               return true;
            }
         }).build();

         SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {

            @Override
            public boolean verify(String arg0, SSLSession arg1) {
               return true;
            }

            @Override
            public void verify(String host, SSLSocket ssl)
                  throws IOException {
            }

            @Override
            public void verify(String host, X509Certificate cert)
                  throws SSLException {
            }

            @Override
            public void verify(String host, String[] cns,
                           String[] subjectAlts) throws SSLException {
            }

         });

         return HttpClients.custom().setSSLSocketFactory(sslsf).build();

      } catch (GeneralSecurityException e) {
         throw e;
      }
   }

   public static void main(String[] args) {
      try {
         String str= post("https://localhost:443/ssl/test.shtml","name=12&page=34","application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
         //String str= get("https://localhost:443/ssl/test.shtml?name=12&page=34","GBK");
            /*Map<String,String> map = new HashMap<String,String>();
            map.put("name", "111");
            map.put("page", "222");
            String str= postForm("https://localhost:443/ssl/test.shtml",map,null, 10000, 10000);*/
         System.out.println(str);
      } catch (ConnectTimeoutException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (SocketTimeoutException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }

}

3、在UcenterMemberController里添加callback方法

java 复制代码
@Autowired
UcenterMemberService memberService;

@ApiOperation(value = "微信扫描后的回调方法")
@GetMapping("callback")
public String callback(String code,String state){
    System.out.println("code:"+code);
    System.out.println("state:"+state);
    //1拿到参数code,请求微信固定地址,获得参数openid、access_token
    String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
            "?appid=%s" +
            "&secret=%s" +
            "&code=%s" +
            "&grant_type=authorization_code";
    baseAccessTokenUrl= String.format(
            baseAccessTokenUrl,
            ConstantPropertiesUtil.WX_OPEN_APP_ID,
            ConstantPropertiesUtil.WX_OPEN_APP_SECRET,
            code
    );

    try {
        String accessTokenInfo = HttpClientUtils.get(baseAccessTokenUrl);
        System.out.println("accessTokenInfo = "+accessTokenInfo);
        Gson gson = new Gson();
        HashMap<String,Object> accessTokenMap =  gson.fromJson(accessTokenInfo, HashMap.class);
        //从map获取相关参数
        String openid = (String)accessTokenMap.get("openid");
        String access_token = (String)accessTokenMap.get("access_token");
        //拿两个参数请求微信固定地址,获取微信用户信息
        String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=%s" +
                "&openid=%s";
        baseUserInfoUrl= String.format(
                baseUserInfoUrl,
                access_token,
                openid
        );
        //httpclient请求
        String userInfo = HttpClientUtils.get(baseUserInfoUrl);
        System.out.println("userInfo ="+userInfo);
        HashMap<String,Object> userInfoMap = gson.fromJson(userInfo,HashMap.class);
        String nickname = (String)userInfoMap.get("nickname");
        String headimgurl = (String)userInfoMap.get("headimgurl");

        //根据openid查询用户
        UcenterMember member = memberService.getWxInfoByOpenid(openid);
        if(member==null){
            member = new UcenterMember();
            member.setOpenid(openid);
            member.setNickname(nickname);
            member.setAvatar(headimgurl);
            memberService.save(member);
        }
        //生成token,并返回
        String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());
        //返回首页
        return "redirect:http://localhost:3000?token="+jwtToken;


    } catch (Exception e) {
        throw new GuliException(20001,"扫描失败");
    }

}

4、在UcenterMemberService添加通过openid获取信息的接口

java 复制代码
UcenterMember getWxInfoByOpenid(String openid);

5、在UcenterMemberServiceImpl实现通过openid获取信息的接口方法

java 复制代码
//根据微信openid查询用户信息
@Override
public UcenterMember getWxInfoByOpenid(String openid) {
    QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();
    wrapper.eq("openid",openid);
    UcenterMember ucenterMember = baseMapper.selectOne(wrapper);
    return ucenterMember;
}

6、测试

java 复制代码
http://localhost:3000/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJndWxpLXVzZXIiLCJpYXQiOjE1OTM4MjcyNzksImV4cCI6MTU5MzkxMzY3OSwiaWQiOiIxMjc5MjMwNDQyMjY4MDU3NjAyIiwibmlja25hbWUiOiLlpI_no4oifQ.ElPnyOJ02chkA8_N15iGLLhvEG5LsyVGacWe_-hIW7U

7、总结信息

相关推荐
【D'accumulation】11 分钟前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
试行26 分钟前
Android实现自定义下拉列表绑定数据
android·java
茜茜西西CeCe31 分钟前
移动技术开发:简单计算器界面
java·gitee·安卓·android-studio·移动技术开发·原生安卓开发
救救孩子把36 分钟前
Java基础之IO流
java·开发语言
小菜yh38 分钟前
关于Redis
java·数据库·spring boot·redis·spring·缓存
宇卿.44 分钟前
Java键盘输入语句
java·开发语言
浅念同学44 分钟前
算法.图论-并查集上
java·算法·图论
立志成为coding大牛的菜鸟.1 小时前
力扣1143-最长公共子序列(Java详细题解)
java·算法·leetcode
鱼跃鹰飞1 小时前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring