java springboot集成微信小程序【详细教程】

这篇具有很好参考价值的文章主要介绍了java springboot集成微信小程序【详细教程】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

申请小程序账号

注册小程序点我

引入依赖

<!-- 小程序依赖 -->
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-miniapp</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-common</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
</dependency>  

yml配置

wx:
  miniapp:
    configs:
      - appid: 12313#微信小程序的appid
        secret: 1231313#微信小程序的Secret
        token:  #微信小程序消息服务器配置的token
        aesKey:  #微信小程序消息服务器配置的EncodingAESKey
        msgDataFormat: JSON

读取配置文件类WxMaProperties

@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {

    private List<Config> configs;

    @Data
    public static class Config {
        /**
         * 设置微信小程序的appid
         */
        private String appid;

        /**
         * 设置微信小程序的Secret
         */
        private String secret;

        /**
         * 设置微信小程序消息服务器配置的token
         */
        private String token;

        /**
         * 设置微信小程序消息服务器配置的EncodingAESKey
         */
        private String aesKey;

        /**
         * 消息格式,XML或者JSON
         */
        private String msgDataFormat;
    }

}

配置文件加载

@Slf4j
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {
    private final WxMaProperties properties;

    private static final Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
    private static Map<String, WxMaService> maServices;

    @Autowired
    public WxMaConfiguration(WxMaProperties properties) {
        this.properties = properties;
    }

    public static WxMaService getMaService(String appid) {
        WxMaService wxService = maServices.get(appid);
        if (wxService == null) {
            throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
        }

        return wxService;
    }

    public static WxMaMessageRouter getRouter(String appid) {
        return routers.get(appid);
    }

    @PostConstruct
    public void init() {
        List<WxMaProperties.Config> configs = this.properties.getConfigs();
        if (configs == null) {
            throw new WxRuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
        }

        maServices = configs.stream()
            .map(a -> {
                WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
//                WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());
                // 使用上面的配置时,需要同时引入jedis-lock的依赖,否则会报类无法找到的异常
                config.setAppid(a.getAppid());
                config.setSecret(a.getSecret());
                config.setToken(a.getToken());
                config.setAesKey(a.getAesKey());
                config.setMsgDataFormat(a.getMsgDataFormat());

                WxMaService service = new WxMaServiceImpl();
                service.setWxMaConfig(config);
                routers.put(a.getAppid(), this.newRouter(service));
                return service;
            }).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
    }

    private WxMaMessageRouter newRouter(WxMaService service) {
        final WxMaMessageRouter router = new WxMaMessageRouter(service);
        router
            .rule().handler(logHandler).next()
            .rule().async(false).content("订阅消息").handler(subscribeMsgHandler).end()
            .rule().async(false).content("文本").handler(textHandler).end()
            .rule().async(false).content("图片").handler(picHandler).end()
            .rule().async(false).content("二维码").handler(qrcodeHandler).end();
        return router;
    }

    private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder()
            .templateId("此处更换为自己的模板id")
            .data(Lists.newArrayList(
                new WxMaSubscribeMessage.MsgData("keyword1", "339208499")))
            .toUser(wxMessage.getFromUser())
            .build());
        return null;
    };

    private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
        log.info("收到消息:" + wxMessage.toString());
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
            .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
        service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
            .toUser(wxMessage.getFromUser()).build());
        return null;
    };

    private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            WxMediaUploadResult uploadResult = service.getMediaService()
                .uploadMedia("image", "png",
                    ClassLoader.getSystemResourceAsStream("tmp.png"));
            service.getMsgService().sendKefuMsg(
                WxMaKefuMessage
                    .newImageBuilder()
                    .mediaId(uploadResult.getMediaId())
                    .toUser(wxMessage.getFromUser())
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

    private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
        try {
            final File file = service.getQrcodeService().createQrcode("123", 430);
            WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
            service.getMsgService().sendKefuMsg(
                WxMaKefuMessage
                    .newImageBuilder()
                    .mediaId(uploadResult.getMediaId())
                    .toUser(wxMessage.getFromUser())
                    .build());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }

        return null;
    };

}

json返回工具类

public class JsonUtils {
    private static final ObjectMapper JSON = new ObjectMapper();

    static {
        JSON.setSerializationInclusion(Include.NON_NULL);
        JSON.configure(SerializationFeature.INDENT_OUTPUT, Boolean.TRUE);
    }

    public static String toJson(Object obj) {
        try {
            return JSON.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return null;
    }
}

控制层

小程序临时素材接口

@RestController
@RequestMapping("/wx/media/{appid}")
public class WxMaMediaController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 上传临时素材
     *
     * @return 素材的media_id列表,实际上如果有的话,只会有一个
     */
    @PostMapping("/upload")
    public List<String> uploadMedia(@PathVariable String appid, HttpServletRequest request) throws WxErrorException {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());

        if (!resolver.isMultipart(request)) {
            return Lists.newArrayList();
        }

        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
        Iterator<String> it = multiRequest.getFileNames();
        List<String> result = Lists.newArrayList();
        while (it.hasNext()) {
            try {
                MultipartFile file = multiRequest.getFile(it.next());
                File newFile = new File(Files.createTempDir(), file.getOriginalFilename());
                this.logger.info("filePath is :" + newFile.toString());
                file.transferTo(newFile);
                WxMediaUploadResult uploadResult = wxService.getMediaService().uploadMedia(WxMaConstants.KefuMsgType.IMAGE, newFile);
                this.logger.info("media_id : " + uploadResult.getMediaId());
                result.add(uploadResult.getMediaId());
            } catch (IOException e) {
                this.logger.error(e.getMessage(), e);
            }
        }

        return result;
    }

    /**
     * 下载临时素材
     */
    @GetMapping("/download/{mediaId}")
    public File getMedia(@PathVariable String appid, @PathVariable String mediaId) throws WxErrorException {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        return wxService.getMediaService().getMedia(mediaId);
    }
}

微信小程序用户接口

@RestController
@RequestMapping("/wx/user/{appid}")
public class WxMaUserController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public String login(@PathVariable String appid, String code) {
        if (StringUtils.isBlank(code)) {
            return "empty jscode";
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            //TODO 可以增加自己的逻辑,关联业务相关数据
            return JsonUtils.toJson(session);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return e.toString();
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @PostMapping("/info")
    public String info(@PathVariable String appid, @RequestBody Map<String, String> map) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);
        String sessionKey = map.get("sessionKey");
        String signature = map.get("signature");
        String rawData = map.get("rawData");
        String encryptedData = map.get("encryptedData");
        String iv = map.get("iv");
        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);

        return JsonUtils.toJson(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @PostMapping("/phone")
    public String phone(@PathVariable String appid, @RequestBody Map<String, String> map) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);
        String sessionKey = map.get("sessionKey");
        String signature = map.get("signature");
        String rawData = map.get("rawData");
        String encryptedData = map.get("encryptedData");
        String iv = map.get("iv");

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return "user check failed";
        }

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);

        return JsonUtils.toJson(phoneNoInfo);
    }

}

前端代码-小程序项目哦,hubild直接创建

<template>
	<view class="content">
		<image class="logo" src="/static/logo.png"></image>
		<view class="text-area">
			<text class="title">{{title}}</text>
			
		</view>
		<view>
			
			<button @click="login">登录</button>


			<!-- 先点击 登录、获取头像昵称按钮才可以点击下面这两个按钮!!! -->
			<button @click="info">获取用户信息</button>
			<button @click="phone">获取手机号信息</button>
			
		</view>
		
		<view class="container">
		  <view class="userinfo">
		    <block>
		      <button @click="getUserProfile"> 获取头像昵称 </button>
		    </block>
		  </view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello2',
				openId: "",
				session: "",
				userInfo: {},
				hasUserInfo: false,
				canIUseGetUserProfile: false,
				signature:'',
				rawData:'',
				encryptedData:'',
				iv:''
			}
		},
		onLoad() {
		},
		methods: {
			login() {
				let that = this;
				wx.login({
				  success (res) {
					  console.log("res::",res)
				    if (res.code) {
				      //发起网络请求
				      wx.request({
				        url: 'http://localhost:8080/wx/user/wx35784428afa871df/login?code='+res.code,
						method: 'GET',
						success(res) {
							console.log("success res :" ,res)
							that.openId = res.data.openid;
							that.session = res.data.sessionKey;
						},
						fail(res) {
							console.log("fail res : ", res)
						}
				      })
				    } else {
				      console.log('登录失败!' + res.errMsg)
				    }
				  }
				})
			},
			info() {
				console.log("sessionKey::",this.session)
				wx.request({
					url: 'http://localhost:8080/wx/user/wx35784428afa871df/info',
					method: 'POST',
					data:{
						sessionKey: this.session,
						signature: this.signature,
						rawData: this.rawData,
						encryptedData: this.encryptedData,
						iv: this.iv
					},
					success(res) {
						console.log("后端获取:success res :" ,res)
					},
					fail(res) {
						console.log("后端获取:fail res : ", res)
					}
				})
			},
			phone() {
				wx.request({
					url: 'http://localhost:8080/wx/user/wx35784428afa871df/phone',
					method: 'POST',
					data:{
						sessionKey: this.session,
						signature: this.signature,
						rawData: this.rawData,
						encryptedData: this.encryptedData,
						iv: this.iv
					},
					success(res) {
						console.log("后端获取手机号:success res :" ,res)
					},
					fail(res) {
						console.log("后端获取手机号:fail res : ", res)
					}
				})
			},
			getUserProfile(e) {
				let that = this;
			    // 推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
			    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
			    wx.getUserProfile({
			      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
			      success: (res) => {
			        console.log("user info res :", res)
					that.signature = res.signature;
					that.rawData = res.rawData;
					that.encryptedData = res.encryptedData;
					that.iv = res.iv;
			      }
			    })
			  },
			  getUserInfo(e) {
			    // 不推荐使用 getUserInfo 获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
			    this.setData({
			      userInfo: e.detail.userInfo,
			      hasUserInfo: true
			    })
			  },
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

界面效果图

效果

java springboot集成微信小程序【详细教程】

点击登录
返回code码,我们拿code码进行获取openid

java springboot集成微信小程序【详细教程】

获取头像昵称
拿到返回的信息进行获取用户信息

java springboot集成微信小程序【详细教程】

获取用户信息

java springboot集成微信小程序【详细教程】

java springboot集成微信小程序【详细教程】文章来源地址https://www.toymoban.com/news/detail-507994.html

以上就完成了哦,简单教程

到了这里,关于java springboot集成微信小程序【详细教程】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端uniapp+后端springboot 详细教程《实现微信小程序授权登录》(附完整前后端项目demo)

    微信小程序官方登录流程图: 参考微信小程序登录官网文档 1、前端技术栈 1.1、uniapp 使用uniapp构建一套代码多端使用的前端框架项目 1.2、前端封装工具 dateUtil.js: 功能: 1. 时间日期格式化 2. 传入日期是否和当前日期的比较 完整代码: requestUtil.js: 功能: 1. 定义公共的

    2024年02月14日
    浏览(59)
  • Java集成支付宝沙箱支付,详细教程(SpringBoot完整版)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 easy支付官方文档:https://opendocs.alipay.com/open/009ys9 通用版文档:https://opendocs.alipay.com/open/02np94 支付宝沙箱的配置: 注册支付宝开发者账户,进入开发者控制台 沙箱快捷入口: https://open.alipay.com/develop/

    2024年02月20日
    浏览(52)
  • 微信小程序控制台 报错 对应的服务器证书无效 控制台输入 showRequestInfo() 可以获取更详细信息 原因是ssl证书过期 重新申请即可

    微信小程序控制台 报错 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息 报错原因:域名下的SSL证书过期 我这边报错的原因是ssl证书过期 重新申请后就好了,但也有本身域名申请的就有问题的,重新根据规范去申请域名 解决方式:重新申请SSL证书 如

    2024年02月12日
    浏览(53)
  • 微信小程序API(详细 教程)

    小程序中的 API 是由宿主环境提供的,通过这些丰富的小程序 API,开发者可以方便的调用微信提供的能力,例如:获取用户信息、本地存储、支付功能等。 小程序提供了很多实用的方法供开发者使用 小程序全局对象是: wx 所有的 API 都保存在 wx 对象中 显示消息提示框: wx.sh

    2023年04月15日
    浏览(47)
  • 微信小程序详细教程(建议收藏)

    1. 小程序的安装与创建 第一步 打开小程序官网 第二步 找到开发管理,找到开发设置,下面有一个 AppID ,复制即可,后面开发小程序需要用 新建项目 ,需要先下载微信开发工具下载网址,安装完成之后进入如下的界面。复制刚才的AppID,选择 不使用云开发 , javascript基础模

    2024年02月03日
    浏览(46)
  • 基于SpringBoot+Vue+uniapp微信小程序的微信小程序书店的详细设计和实现

    💗 博主介绍 :✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅 👇🏻 2023-2024年最值得选的微信小程序毕业设

    2024年03月17日
    浏览(79)
  • 微信小程序对接微信支付详细教程

    小程序 微信支付官方文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_11index=2 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_0.shtml 前提 在进行对接微信支付之前,我们首先需要将以下几点准备好: 申请APPID 申请商户号 小程序开通微信支付,绑定已经申请好的商户号。

    2024年02月09日
    浏览(49)
  • 微信小程序云开发入门详细教程

    本篇是《从零开始Python+微信小程序开发》专栏第九篇,主要介绍最新最全的云开发入门教程,微信小程序云开发,云函数,云数据库学习,微信小程序云开发扩展功能学习,希望大家能够一起学习,互相交流。 小程序云开发是微信团队联合腾讯云推出的专业的小程序开发服

    2024年02月11日
    浏览(44)
  • SpringBoot+微信小程序在线订餐小程序系统 附带详细运行指导视频

    项目演示地址: 视频地址 项目描述:这是一个 基于SpringBoot+微信小程序框架 开发的在线订餐小程序系统。首先,这是一个 前后端分离 的项目,代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个在线订餐小程序系统该有的所有功能。 项目功

    2024年02月12日
    浏览(47)
  • 基于SpringBoot+Vue+uniapp微信小程序的校园反诈骗微信小程序的详细设计和实现

    💗 博主介绍 :✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻 精彩专栏 推荐订阅 👇🏻 2023-2024年最值得选的微信小程序毕业设

    2024年03月22日
    浏览(98)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包