回调实现获取扫描人信息

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、总结信息

相关推荐
吾日三省吾码3 小时前
JVM 性能调优
java
弗拉唐4 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi775 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
少说多做3435 小时前
Android 不同情况下使用 runOnUiThread
android·java
知兀5 小时前
Java的方法、基本和引用数据类型
java·笔记·黑马程序员
蓝黑20205 小时前
IntelliJ IDEA常用快捷键
java·ide·intellij-idea
Ysjt | 深5 小时前
C++多线程编程入门教程(优质版)
java·开发语言·jvm·c++
shuangrenlong6 小时前
slice介绍slice查看器
java·ubuntu
牧竹子6 小时前
对原jar包解压后修改原class文件后重新打包为jar
java·jar