文章目录
HttpClient
介绍
HttpClient是Apache的一个子项目,是高效的、功能丰富的支持HTTP协议的客户端编程工具包。
作用:发送HTTP请求;接收响应数据
应用场景:微信服务、地图服务、短信服务、天气预报服务
依赖包:
核心API:
HttpClient、HttpClients、CloseableHttpClient、HttpGet、HttpPost
发送请求步骤
- 创建HttpClient对象
- 创建Http请求对象
- 调用HttpClient的execute方法发送请求
通过浏览器请求服务的步骤
- 构造请求地址和参数
- 发送请求
- 接收数据
入门案例
Get
//http客户端对象,可以发送http请求
CloseableHttpClient httpClient = HttpClients.createDefault();
//构造Get方式请求
HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");
//发送请求
CloseableHttpResponse response = httpClient.execute(httpGet);
//http响应码
int statusCode = response.getStatusLine().getStatusCode();
//http响应体
HttpEntity entity = response.getEntity();
//将响应体转化为String字符串
String body = EntityUtils.toString(entity);
System.out.println(body);
//关闭资源
response.close();
httpClient.close();
Post
//http客户端对象
CloseableHttpClient httpClient = HttpClients.createDefault();
//Post请求方式
HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");
//构造json数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("username","admin");
jsonObject.put("password","123456");
//构造请求体
StringEntity stringEntity = new StringEntity(jsonObject.toString());
//设置请求编码
stringEntity.setContentEncoding("utf-8");
//设置数据类型
stringEntity.setContentType("application/json");
//设置当前Post请求的请求体
httpPost.setEntity(stringEntity);
//发送请求
CloseableHttpResponse response = httpClient.execute(httpPost);
//http响应码
int statusCode = response.getStatusLine().getStatusCode();
//http响应体
HttpEntity entity = response.getEntity();
//将响应体转化为String字符串
String body = EntityUtils.toString(entity);
System.out.println(body);
//关闭资源
response.close();
httpClient.close();
微信小程序开发
介绍
一种新的开放能力,可以在微信内被便捷地获取和传播,同时具有出色的使用体验
链接:https://mp.weixin.qq.com/cgi-bin/wx?token=&lang=zh_CN
准备工作
注册小程序
注册地址:https://mp.weixin.qq.com/wxopen/waregister?action=step1
完善小程序信息
登录小程序后台:https://mp.weixin.qq.com/
- 完善小程序信息,小程序类目
- 查看小程序的AppID
下载开发者工具
下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
- 扫描登录开发者工具
- 创建小程序项目
- 熟悉开发者工具布局
- 设置不校验合法域名
入门案例
了解小程序目录结构
小程序包含了一个描述整体程序的app和多个描述各自页面的page。
- 一个小程序主体部分由三个文件组成,必须放在项目的根目录
- 一个小程序页面由四个文件组成
编写小程序代码
编译小程序
微信登录
微信登录流程
微信登录:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
目标:获取用户在当前小程序的唯一身份信息openid,然后插入苍穹外卖数据库中,作为用户在苍穹外卖系统中的用户唯一标识
需求和分析
接口设计
数据库设计
代码开发
小程序登录:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
- 写controller代码
@ApiOperation("用户登录接口")
@PostMapping("/login")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO){
log.info("用户登录接口:{}",userLoginDTO);
//1.调用业务进行微信登录,返回登录User对象
User user = userService.login(userLoginDTO);
//2.下发令牌
Map<String,Object> cliams = new HashMap<>();
cliams.put(JwtClaimsConstant.USER_ID,user.getId());
String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), cliams);
//3.封装数据返回
UserLoginVO userLoginVO = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(token)
.build();
return Result.success(userLoginVO);
}
- 写sercice的实现类代码(service接口的代码省略)
@Override
public User login(UserLoginDTO userLoginDTO) {
//1.远程调用微信凭证校验接口获取openid
String url = "https://api.weixin.qq.com/sns/jscode2session";
Map<String,String> map = new HashMap<>();
map.put("appid",weChatProperties.getAppid());
map.put("secret",weChatProperties.getSecret());
map.put("js_code",userLoginDTO.getCode());
map.put("grant_type","authorization_code");
String json = HttpClientUtil.doGet(url,map);
JSONObject jsonObject = JSON.parseObject(json);
String openid = (String) jsonObject.get("openid");
if (openid == null) {
throw new BaseException("微信登录失败");
}
//2.根据openid查询用户数据
User user = userMapper.findByOpenId(openid);
//2.1用户数据不为null,直接返回
if (user != null){
return user;
}
//2.2用户数据为null,注册用户(将openid插入到user表中)
user = new User();
user.setOpenid(openid);
user.setCreateTime(LocalDateTime.now());
userMapper.insert(user); //不仅要插入数据,并且里面要获取到自增长主键值
//3. 返回登录的用户对象
return user;
}
- 写拦截器的代码(mapper层代码省略)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//获取登录数据员工id
// Long userId = (Long) request.getSession().getAttribute("employee");
//从请求头中获取令牌
String token = request.getHeader(jwtProperties.getUserTokenName());
Map<String, Object> claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
Long userId = Long.parseLong(String.valueOf(claims.get(JwtClaimsConstant.USER_ID)));
log.info("当前用户id:{}",userId);
// System.out.println("拦截器的线程名称为:"+Thread.currentThread().getName());
BaseContext.setCurrentId(userId);
if(userId!=null){
//如果有登录数据,代表一登录,放行
return true;
}else{
//否则,发送未认证错误信息
response.setStatus(401);
return false;
}
}
- 在MvcConfig中注册用户拦截器,并配置拦截路劲即可
registry.addInterceptor(jwtTokenUserInterceptor)
.addPathPatterns("/user/**")
.excludePathPatterns("/user/user/login")
.excludePathPatterns("/user/shop/status");