springboot公众号微信授权获取用户信息(采用wxJava包)

写在前面的话

H5授权获取用户信息,这次采用了比较流行的wxJava包 /binary/weixin-java-tools
需要一些配置
1、config 里需要两个文件

package com.xxx.common.configuration;

import lombok.AllArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.List;
import java.util.stream.Collectors;


/**
 * 类名称:WxMpConfiguration
 *
 * 描述:wechat mp configuration
 * 创建时间: 2022-09-17 13:20:37
 */
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {

    private final WxMpProperties properties;

    /**
     * 微信服务类
     *
     * @return {@link WxMpService }
     * @date 2022-09-17 13:20:38
     */
    @Bean
    public WxMpService wxMpService() {
        // 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
        final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
        if (configs == null) {
            throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
        }

        WxMpService service = new WxMpServiceImpl();
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    WxMpDefaultConfigImpl configStorage;

                    configStorage = new WxMpDefaultConfigImpl();

                    configStorage.setAppId(a.getAppId());
                    configStorage.setSecret(a.getSecret());
                    configStorage.setToken(a.getToken());
                    configStorage.setAesKey(a.getAesKey());
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return service;
    }

}

package com.xxx.common.configuration;

import cn.hutool.json.JSONUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * 类名称:WxMpProperties
 *
 * 描述:wechat mp properties
 * 创建时间: 2022-09-17 13:21:19
 */
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
    /**
     * 是否使用redis存储access token
     */
    private boolean useRedis;

    /**
     * redis 配置
     */
    private RedisConfig redisConfig;

    @Data
    public static class RedisConfig {
        /**
         * redis服务器 主机地址
         */
        private String host;

        /**
         * redis服务器 端口号
         */
        private Integer port;

        /**
         * redis服务器 密码
         */
        private String password;

        /**
         * redis 服务连接超时时间
         */
        private Integer timeout;
    }

    /**
     * 多个公众号配置信息
     */
    private List<MpConfig> configs;

    @Data
    public static class MpConfig {
        /**
         * 设置微信公众号的appid
         */
        private String appId;

        /**
         * 设置微信公众号的app secret
         */
        private String secret;

        /**
         * 设置微信公众号的token
         */
        private String token;

        /**
         * 设置微信公众号的EncodingAESKey
         */
        private String aesKey;
    }

    /**
     * 重写toString
     *
     * @return {@link String }
     * @date 2022-09-17 13:21:19
     */
    @Override
    public String toString() {
        return JSONUtil.toJsonStr(this);
    }
}

2、配置文件内容

#wxjava(appid,appsecret,接口配置里的Token值,接口配置里的EncodingAESKey值)
wx.mp.useRedis=false
wx.mp.configs[0].appId=11111
wx.mp.configs[0].secret=222222
wx.mp.configs[0].token=
wx.mp.configs[0].aesKey=

一、跳转

原理,没有session就构建一个要回跳的地址并存起来,生成一个新的跳转地址

if (httpServletRequest.getSession().getAttribute("wechat_user") == null) {
                // 定义要跳回的地址
                String scheme = httpServletRequest.getScheme(); // 协议 如:https
                //String remoteHost = httpServletRequest.getRemoteHost(); // 网址 如:127.0.0.1
                String remoteHost = "javaxq.xxx.cc"; // 这里先写死,上边获取的为本地ip
                String referer = scheme + "://" + remoteHost + "/#/answer?sn=" + id;

                // 追加部分参数
                Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
                if (parameterMap.size() > 0) {
                    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                        String key = entry.getKey();
                        String[] value = entry.getValue();
                        if (value.length > 0) {
                            if (StringUtils.isNotBlank(value[0])) {
                                referer += "&" + key + "=" + value[0];
                            }
                        }
                    }
                }

                // 写入session 
                httpServletRequest.getSession().setAttribute("target_url", referer);

                // 构建要跳转的地址
                String jumpUrl = scheme + "://" + remoteHost + "/api/answer/oauth_callback";

                // 构建微信授权的跳转地址
                referer = wxMpService.getOAuth2Service().buildAuthorizationUrl(jumpUrl, "snsapi_userinfo", null);
				// 返回要跳转的信息,这里你可以自行修改为返回上边的地址
                this.setAction(answerVo, RStatus.REDIRECT.getCode(), referer);
                return answerVo;
            }

回调

原理,接收code,获取用户信息,写入session,读取session里的跳转地址进行跳转

/**
     * 微信授权回调
     *
     * @param code
     * @param response 响应
     * @return {@link String }
     * @date 2022-09-17 13:31:26
     */
    @GetMapping(value = "/oauth_callback")
    public String oauth(String code, HttpServletResponse response) throws WxErrorException, IOException {
        // 用code获取accessToken,这里的accessToken指的是单个用户授权的accessToken
        WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
        // 用accessToken获取用户信息
        WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(accessToken, "zh_CN");

        if (userInfo != null) {
            // 写入 session->wechat_user
            Map<String, String> userInfoMap = new HashMap<>();
            userInfoMap.put("open_id", userInfo.getOpenid());
            userInfoMap.put("nick_name", userInfo.getNickname());
            httpServletRequest.getSession().setAttribute("wechat_user", userInfoMap);

            // 跳转
            String targetUrl = (String) httpServletRequest.getSession().getAttribute("target_url");
            if (StringUtils.isNotBlank(targetUrl)) {
                response.sendRedirect(targetUrl);
            }
            //response.sendRedirect(userInfo.get);
        }

        // 获取 target_url 并进行跳转
        return userInfo.toString();
    }
### 使用 Spring Boot 开发微信公众号教程 #### 1. 前置准备工作 为了能够顺利地集成微信公众号Spring Boot应用程序中,需完成以下前置工作: - 注册微信公众平台账号并创建相应的公众号。 - 获取`appId`和`appSecret`这两个核心参数用于后续的身份验证与授权操作[^1]。 #### 2. 引入必要的依赖项 在项目的`pom.xml`文件内加入如下Maven依赖来支持微信功能模块的开发: ```xml <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp-spring-boot-starter</artifactId> <version>${wx.java.version}</version> </dependency> ``` 此部分配置使得开发者可以更便捷地调用微信开放平台所提供的API接口[^2]。 #### 3. 应用程序配置 (`application.yml`) 接下来,在`src/main/resources/application.yml`中添加关于微信公众号的相关设置信息: ```yaml wechat: mp: appId: wxxxxxxxxxxxxxxx # 替换成自己的AppID secret: xxxxxxxxxxxxxxxx # 替换成自己的AppSecret token: yourTokenHere aesKey: yourAesKeyIfNeed ``` 这些属性对于初始化SDK以及实现消息加密解密等功能至关重要。 #### 4. 编写 Java 类 ##### Properties 配置类 定义一个名为WeChatConfig.properties的Bean对象用来加载上述YAML中的配置值: ```java @ConfigurationProperties(prefix = "wechat.mp") public class WeChatMpProperties { private String appId; private String secret; private String token; private String aesKey; // Getters and Setters... } ``` ##### Service 实现类 通过继承自WxMpService并重载相应的方法来自定义业务逻辑处理流程。这里提供了一个简单的例子展示如何获取已发布图文素材列表: ```java @Service @Slf4j @RequiredArgsConstructor(onConstructor_ = {@Autowired}) public class WxMpServiceImpl implements InitializingBean { private final WxMpDefaultConfigImpl configStorage; private final WxMpMaterialService materialService; @Override public void afterPropertiesSet() throws Exception { this.configStorage.setAppid(appId); this.configStorage.setSecret(secret); this.materialService = new WxMpMaterialServiceImpl(); } /** * 查询永久素材总数及各类型数量. */ public Integer getMaterialCount(){ try{ return materialService.getMaterialCount(); }catch (Exception e){ log.error("查询失败",e); throw new RuntimeException(e.getMessage()); } } } ``` 以上代码片段展示了如何利用WxJava库提供的工具和服务来进行具体的交互操作。 #### 5. 创建菜单结构 可以通过编写专门的服务端点或命令行工具来动态构建导航栏目。下面是一个简单示例——创建名为InitMenu的类负责向服务器发送请求以建立基础菜单布局[^3]: ```java @RestController @RequestMapping("/menu") public class MenuController { @PostMapping("/init") public ResponseEntity<String> initMenu(@RequestBody Map<String, Object> body) { // 构建菜单数据体... boolean result = menuService.createMenu(menuData); if(result){ return ResponseEntity.ok().body("成功"); }else{ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若水印象

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值