最近做了一个关于商城的项目,B端选用若依的开源框架,C端还是vue前后端分离。其中C端主要是小程序的形式,所以想着来总结一下对接微信小程序登录中Java部分遇到的坑即代码分享!
废话不多说,直接上代码!
1、controller 层代码
入参我这边是直接使用request来接收,大家可以改成自己的DTO来接收入参
@GetMapping("/letsLogin")
@ApiOperation("微信授权登录")
public R letsLogin(HttpServletRequest request){
return remoteMallUserService.letsLogin(request);
}
2、service 层代码
其中涉及到几个基本配置参数,我这边单独列出,大家可以放入配置文件进行引用,也可以直接作为常量引用;
同时可以参考微信公众平台提供的开发文档(服务端):接口调用凭证 | 微信开放文档
// APP_ID 小程序注册时由微信提供
private final static String APP_ID = "....";
// APP_SERCRET 小程序注册时由微信提供
private final static String APP_SERCRET = ".....";
// 请求地址这边用了多个所以我们按照调用的顺序来说明
// 首先是这个TOKENURL 用于获取微信用户的授权认证 来拿到“accessToken”
private final static String TOKENURL = "https://api.weixin.qq.com/cgi-bin/token";
// 第二是用于请求获取用户手机号的地址(结尾的“access_token”需要拼接上TOKENURL返回的参数)
private final static String PHONENURL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
// 最后才是登录url了
private final static String URL = "https://api.weixin.qq.com/sns/jscode2session";
由于我自身的业务中存在通过手机号验证登录这个功能模块,所以我在入参的时候会做一个是否存在手机号的判断,不存在时才通过微信去请求;存在时直接调用登录URL即可;
这边还需要简单解释一下入参(红色为必传参数):
1、userPhone 用户手机号;
2、code:前端通过getPhoneNum() 获得的code;
3、loginCode:前端通过wx.login() 获得的code;
@Autowired
private RestTemplate restTemplate;
@Override
public R letsLogin(HttpServletRequest request){
// 先拿到前端通过wx.login()拿到的code -- 5分钟过期哦
String loginCode = request.getParameter("loginCode");
if(StringUtils.isBlank(loginCode)){
return R.fail(101,"loginCode不可以为空!");
}
String userPhone = request.getParameter("userPhone");
// 如果手机号为空则判断是否有code(该code是前端通过获取手机号方法拿到的)
if (StringUtils.isBlank(userPhone)){
String code = request.getParameter("code");
if(StringUtils.isBlank(code)){
return R.fail(101,"code为空,无法获取手机号!");
}
// 获取手机号 -- 这边需要定义一个传参的map
Map<String, String> params1 = new HashMap<>();
// 此处为固定值不需要修改
params1.put("grant_type", "client_credential");
// APP_ID和APP_SERCRET需要根据实际情况进行传参
params1.put("appid", APP_ID);
params1.put("secret", APP_SERCRET);
// 调用TOKENURL获取授权凭证access_token
// 我这边用的是Hultool的HTTP请求工具 -- 之后会附上maven依赖
String resultToken = HttpUtil.sendGet(TOKENURL, params1);
// fastjson 框架自带 大家可以选择自己的JSON转换工具
JSONObject tokenJson = JSONObject.parseObject(resultToken);
String accessToken = (String)tokenJson.get("access_token");
// 使用前端code获取手机号码(accessToken一定要以get的方式请求)其他参数为json格式
String url1 = PHONEURL + accessToken;
Map<String, String> paramMap = new HashMap<>();
paramMap.put("code", code);
HttpHeaders headers = new HttpHeaders();
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap, headers);
ResponseEntity<Object> response = restTemplate.postForEntity(url1, httpEntity, Object.class);
Object body = response.getBody();
Map<String, Object> map = new ObjectMapper().convertValue(body, Map.class);
Object phoneInfo = map.get("phone_info");
Map<String, Object> map1 = new ObjectMapper().convertValue(phoneInfo, Map.class);
// 以上都是response参数的处理 最终拿到userPhone 可以进行下一步 微信登陆了
userPhone = (String)map1.get("phoneNumber");
}
// 构建 一个map传登录的参数
Map<String, String> params = new HashMap<>();
params.put("appid", APP_ID);
params.put("secret", APP_SERCRET);
// 这里的code是前端通过wx.login()获取到的
params.put("js_code", loginCode);
// 固定参数
params.put("grant_type", "authorization_code");
String resultJson = HttpUtil.sendGet(URL, params);
JSONObject json = JSONObject.parseObject(resultJson);
if (!json.containsKey("errcode")) {
// 拿到openid(用户在该小程序的唯一用户标识)
String openId = (String)json.get("openid");
// 之后的可以根据自己的业务进行处理 比如:新增用户...
return R.ok("","登录成功");
} else {
return R.fail(101,"登录失败!");
}
}
3、util 层代码。添加一个RestTemplateConfig配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//ms
factory.setConnectTimeout(15000);//ms
return factory;
}
}
4、Hultool的依赖
<!-- hutool 工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.4</version>
</dependency>
最后说一下在开发中踩到的坑,就是获取手机号返回的response这边进行了两次的map转换才拿到最终的手机号,但是官方文档中的返回格式是一个JSON对象,如果是一个JSON串的话就不需要这么麻烦了,所以各位大神可以在开发的时候优化一下这部分!
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现