guns框架新增对微信公众号一键登录的支持
一、概述
前段时间帮朋友写了个简单的H5页面用于记录房屋租赁的情况,方便提示哪些房子快到期了,最近把该应用挂到了微信公众号上面,为了使用方便计划做一键登录支持。
二、数据库调整
新增表用于记录用户ID与微信openid,unionid之间的对应关系。
CREATE TABLE `tbl_wx_user` (
`wx_user_id` bigint NOT NULL COMMENT 'id',
`user_id` bigint DEFAULT NULL COMMENT '用户id',
`union_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`open_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`create_user` bigint DEFAULT NULL COMMENT '创建人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`update_user` bigint DEFAULT NULL COMMENT '更新人',
PRIMARY KEY (`wx_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
三、新表相关支持类
1.entity
package cn.stylefeng.guns.modular.hourse.entity;
import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 微信用户表
*
* @author roger
* @date 2021/09/20 08:00
*/
@TableName("tbl_wx_user")
@Data
@EqualsAndHashCode(callSuper = true)
public class WXUser extends BaseEntity {
/**
* 微信用户ID
*/
@TableId(value = "wx_user_id", type = IdType.ASSIGN_ID)
private Long wxUserId;
/**
* 关联用户ID
*/
@TableField("user_id")
private Long userId;
/**
* 微信unionId
*/
@TableField("union_id")
private String unionId;
/**
* 微信用户openId
*/
@TableField("open_id")
private String openId;
}
2.mapper
package cn.stylefeng.guns.modular.hourse.mapper;
import cn.stylefeng.guns.modular.hourse.entity.Bill;
import cn.stylefeng.guns.modular.hourse.entity.WXUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* 账单管理 Mapper 接口
*
* @author roger
* @date 2021/09/20 08:00
*/
public interface WXUserMapper extends BaseMapper<WXUser> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.guns.modular.hourse.mapper.WXUserMapper">
</mapper>
3.enums
package cn.stylefeng.guns.modular.hourse.enums;
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum;
import lombok.Getter;
/**
* 账单管理异常相关枚举
*
* @author roger
* @date 2021/09/20 08:00
*/
@Getter
public enum WXUserExceptionEnum implements AbstractExceptionEnum {
/**
* 查询结果不存在
*/
WXUSER_NOT_EXISTED(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10001", "查询结果不存在");
/**
* 错误编码
*/
private final String errorCode;
/**
* 提示用户信息
*/
private final String userTip;
WXUserExceptionEnum(String errorCode, String userTip) {
this.errorCode = errorCode;
this.userTip = userTip;
}
}
4.pojo
package cn.stylefeng.guns.modular.hourse.pojo.request;
import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest;
import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 微信用户封装类
*
* @author roger
* @date 2021/09/20 08:00
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class WXUserRequest extends BaseRequest {
/**
* 微信用户ID
*/
@NotNull(message = "微信用户ID不能为空", groups = {edit.class, delete.class})
@ChineseDescription("微信用户ID")
private Long wxUserId;
/**
* 关联用户ID
*/
@ChineseDescription("关联用户ID")
private Long userId;
/**
* 微信unionId
*/
@ChineseDescription("微信unionId")
private String unionId;
/**
* 微信用户openId
*/
@ChineseDescription("微信用户openId")
private String openId;
}
5.service
package cn.stylefeng.guns.modular.hourse.service;
import cn.stylefeng.guns.modular.hourse.entity.Bill;
import cn.stylefeng.guns.modular.hourse.entity.WXUser;
import cn.stylefeng.guns.modular.hourse.pojo.request.WXUserRequest;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 账单管理 服务类
*
* @author roger
* @date 2021/09/20 08:00
*/
public interface WXUserService extends IService<WXUser> {
/**
* 新增
*
* @param wxUserRequest 请求参数
* @author roger
* @date 2021/09/20 08:00
*/
void add(WXUserRequest wxUserRequest);
/**
* 删除
*
* @param wxUserRequest 请求参数
* @author roger
* @date 2021/09/20 08:00
*/
void del(WXUserRequest wxUserRequest);
/**
* 编辑
*
* @param wxUserRequest 请求参数
* @author roger
* @date 2021/09/20 08:00
*/
void edit(WXUserRequest wxUserRequest);
/**
* 查询详情
*
* @param wxUserRequest 请求参数
* @author roger
* @date 2021/09/20 08:00
*/
WXUser detail(WXUserRequest wxUserRequest);
/**
* 获取列表
*
* @param wxUserRequest 请求参数
* @return List<Bill> 返回结果
* @author roger
* @date 2021/09/20 08:00
*/
List<WXUser> findList(WXUserRequest wxUserRequest);
/**
* 获取列表(带分页)
*
* @param wxUserRequest 请求参数
* @return PageResult<Bill> 返回结果
* @author roger
* @date 2021/09/20 08:00
*/
PageResult<WXUser> findPage(WXUserRequest wxUserRequest);
}
package cn.stylefeng.guns.modular.hourse.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.hourse.entity.Bill;
import cn.stylefeng.guns.modular.hourse.entity.WXUser;
import cn.stylefeng.guns.modular.hourse.enums.BillExceptionEnum;
import cn.stylefeng.guns.modular.hourse.enums.WXUserExceptionEnum;
import cn.stylefeng.guns.modular.hourse.mapper.WXUserMapper;
import cn.stylefeng.guns.modular.hourse.pojo.request.WXUserRequest;
import cn.stylefeng.guns.modular.hourse.service.WXUserService;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* 账单管理业务实现层
*
* @author roger
* @date 2021/09/20 08:00
*/
@Service
public class WXUserServiceImpl extends ServiceImpl<WXUserMapper, WXUser> implements WXUserService {
@Override
public void add(WXUserRequest wxUserRequest) {
WXUser wxUser = new WXUser();
BeanUtil.copyProperties(wxUserRequest, wxUser);
this.save(wxUser);
wxUserRequest.setWxUserId(wxUser.getWxUserId());
}
@Override
public void del(WXUserRequest wxUserRequest) {
WXUser wxUser = this.queryWxUser(wxUserRequest);
this.removeById(wxUser.getWxUserId());
}
@Override
public void edit(WXUserRequest wxUserRequest) {
WXUser wxUser = this.queryWxUser(wxUserRequest);
BeanUtil.copyProperties(wxUserRequest, wxUser);
this.updateById(wxUser);
}
@Override
public WXUser detail(WXUserRequest wxUserRequest) {
return this.queryWxUser(wxUserRequest);
}
@Override
public PageResult<WXUser> findPage(WXUserRequest wxUserRequest) {
LambdaQueryWrapper<WXUser> wrapper = createWrapper(wxUserRequest);
Page<WXUser> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
return PageResultFactory.createPageResult(sysRolePage);
}
@Override
public List<WXUser> findList(WXUserRequest wxUserRequest) {
LambdaQueryWrapper<WXUser> wrapper = this.createWrapper(wxUserRequest);
return this.list(wrapper);
}
/**
* 获取信息
*
* @author roger
* @date 2021/09/20 08:00
*/
private WXUser queryWxUser(WXUserRequest wxUserRequest) {
WXUser wxUser = this.getById(wxUserRequest.getWxUserId());
if (ObjectUtil.isEmpty(wxUser)) {
throw new ServiceException(WXUserExceptionEnum.WXUSER_NOT_EXISTED);
}
return wxUser;
}
/**
* 创建查询wrapper
*
* @author roger
* @date 2021/09/20 08:00
*/
private LambdaQueryWrapper<WXUser> createWrapper(WXUserRequest wxUserRequest) {
LambdaQueryWrapper<WXUser> queryWrapper = new LambdaQueryWrapper<>();
Long wxUserId = wxUserRequest.getWxUserId();
Long userId = wxUserRequest.getUserId();
String unionId = wxUserRequest.getUnionId();
String openId = wxUserRequest.getOpenId();
queryWrapper.eq(ObjectUtil.isNotNull(wxUserId), WXUser::getWxUserId, wxUserId);
queryWrapper.eq(ObjectUtil.isNotNull(userId), WXUser::getUserId, userId);
queryWrapper.eq(ObjectUtil.isNotNull(unionId), WXUser::getUnionId, unionId);
queryWrapper.eq(ObjectUtil.isNotNull(openId), WXUser::getOpenId, openId);
return queryWrapper;
}
}
四、微信登录支持
1.controller
package cn.stylefeng.guns.modular.hourse.controller;
import cn.stylefeng.guns.modular.hourse.pojo.request.WXLoginRequest;
import cn.stylefeng.guns.modular.hourse.service.WXLoginService;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@RestController
@ApiResource(name = "微信服务")
@Slf4j
public class WXLoginController {
@Resource
private WXLoginService wxLoginService;
@PostResource(name = "微信登录接口", path = "/loginWXApi",requiredLogin = false,requiredPermission = false)
public ResponseData loginWXApi(@RequestBody WXLoginRequest wxLoginRequest) {
log.info("loginWXApi:"+wxLoginRequest.getCode());
return new SuccessResponseData(wxLoginService.loginWX(wxLoginRequest.getCode()));
}
@PostResource(name = "微信登录接口", path = "/loginByOpenId",requiredLogin = false,requiredPermission = false)
public ResponseData loginByOpenId(@RequestBody WXLoginRequest wxLoginRequest) {
log.info("loginWXApi:"+wxLoginRequest.getCode());
return new SuccessResponseData(wxLoginService.loginByOpenId(wxLoginRequest.getCode()));
}
@GetResource(name = "微信服务器验证", path = "/getWxToken",requiredLogin = false,requiredPermission = false)
public String getWxToken(String signature,String timestamp,String nonce,String echostr) {
log.info("getWxGZHToken:"+signature+"_"+timestamp+"-"+nonce+"_"+echostr);
String[] array = {"hoursezjljcvip", timestamp, nonce};
Arrays.sort(array);
String s = encrypt(StringUtils.join(array));
if (s.equals(signature)) {
return echostr;
}
return "";
}
public String encrypt(String content) {
try {
// Create MD5 Hash
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(content.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++)
hexString.append(String.format("%02X", 0xFF & messageDigest[i]));
return hexString.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
2.service
package cn.stylefeng.guns.modular.hourse.service;
import cn.stylefeng.guns.modular.hourse.entity.Bill;
import cn.stylefeng.guns.modular.hourse.pojo.request.BillRequest;
import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 账单管理 服务类
*
* @author roger
* @date 2021/09/20 08:00
*/
public interface WXLoginService {
/**
* 新增
*
* @param code 请求参数
* @author roger
* @date 2021/09/20 08:00
*/
LoginResponse loginWX(String code);
}
package cn.stylefeng.guns.modular.hourse.service.impl;
import cn.stylefeng.guns.modular.hourse.entity.WXUser;
import cn.stylefeng.guns.modular.hourse.pojo.request.WXUserRequest;
import cn.stylefeng.guns.modular.hourse.service.WXLoginService;
import cn.stylefeng.guns.modular.hourse.service.WXUserService;
import cn.stylefeng.guns.modular.hourse.util.HttpRequest;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.jwt.api.context.JwtContext;
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
import cn.stylefeng.roses.kernel.message.api.expander.WebSocketConfigExpander;
import cn.stylefeng.roses.kernel.system.api.UserServiceApi;
import cn.stylefeng.roses.kernel.system.api.pojo.user.UserLoginInfoDTO;
import cn.stylefeng.roses.kernel.system.api.pojo.user.request.SysUserRequest;
import cn.stylefeng.roses.kernel.system.modular.user.entity.SysUser;
import cn.stylefeng.roses.kernel.system.modular.user.factory.SysUserCreateFactory;
import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserOrgService;
import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserRoleService;
import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
/**
* 账单管理业务实现层
*
* @author roger
* @date 2021/09/20 08:00
*/
@Service
@Slf4j
public class WXLoginServiceImpl implements WXLoginService {
private static final Object SESSION_OPERATE_LOCK = new Object();
@Resource
private WXUserService wxUserService;
@Resource
private SysUserService sysUserService;
@Resource
private SysUserOrgService sysUserOrgService;
@Resource
private SysUserRoleService sysUserRoleService;
@Resource
private SessionManagerApi sessionManagerApi;
@Resource
private UserServiceApi userServiceApi;
/**
* 微信登录。
* 查询是否已经存在,存在则进入登录流程,
* 不存在则向微信服务器获取用户信息,新建用户,
* 然后再进行登录流程
* @param code 请求参数
* @return
*/
@Override
public LoginResponse loginWX(String code) {
HashMap<String,String> map = getAccessToken(code);
if(map == null){
throw new AuthException(AuthExceptionEnum.SSO_LOGIN_CODE_GET_ERROR);
}else{
String openId =map.get("openid");
WXUserRequest wxUserRequest = new WXUserRequest();
wxUserRequest.setOpenId(openId);
List<WXUser> wxUsers = wxUserService.findList(wxUserRequest);
//已经存在该用户的信息,则执行登录,否则从微信获取id
log.info("wxUsers:"+wxUsers.size()+" "+code);
SysUser sysUser = null;
if(wxUsers.size() >0){
sysUser = this.sysUserService.getById(wxUsers.get(0).getUserId());
}
if(sysUser ==null){
//String token = getToken();
// System.out.println(token);
String url= "https://api.weixin.qq.com/sns/userinfo";
String params="access_token="+map.get("access_token")+"&openid="+openId+"&lang=zh_CN";
String result = HttpRequest.sendGet(url,params);
JSONObject json = JSONObject.parseObject(result);
log.info("推送结果sns:" + result);
//插入用户表
sysUser = new SysUser();
sysUser.setRealName(json.getString("nickname"));
sysUser.setAccount(openId);
sysUser.setNickName(json.getString("nickname"));
sysUser.setPassword("hourse123");
String sex = json.getString("sex");
if("1".equalsIgnoreCase(sex))
sysUser.setSex("M");
else if("2".equalsIgnoreCase(sex))
sysUser.setSex("F");
else{
sysUser.setSex("M");
}
SysUserCreateFactory.fillAddSysUser(sysUser);
this.sysUserService.save(sysUser);
sysUserOrgService.add(sysUser.getUserId(), 1339554696976781407l, 1339554696976781332l);
SysUserRequest sysUserRequest = new SysUserRequest();
sysUserRequest.setUserId(sysUser.getUserId());
List<Long> grantOrgIdList = new LinkedList<>();
grantOrgIdList.add(1339550467939639304l);
sysUserRequest.setGrantRoleIdList(grantOrgIdList);
sysUserRoleService.assignRoles(sysUserRequest);
WXUser wxUser = new WXUser();
wxUser.setOpenId(openId);
wxUser.setUserId(sysUser.getUserId());
this.wxUserService.save(wxUser);
}
if(sysUser ==null){
throw new AuthException(AuthExceptionEnum.SSO_LOGIN_CODE_GET_ERROR);
}
UserLoginInfoDTO userValidateInfo = userServiceApi.getUserLoginInfo(sysUser.getAccount());
LoginUser loginUser = userValidateInfo.getLoginUser();
// 9. 生成用户的token
DefaultJwtPayload defaultJwtPayload = new DefaultJwtPayload(loginUser.getUserId(), loginUser.getAccount(), false, null);
String jwtToken = JwtContext.me().generateTokenDefaultPayload(defaultJwtPayload);
loginUser.setToken(jwtToken);
// 如果包含租户编码,则放到loginUser中
loginUser.setTenantCode("");
synchronized (SESSION_OPERATE_LOCK) {
// 9.1 获取ws-url 保存到用户信息中
loginUser.setWsUrl(WebSocketConfigExpander.getWebSocketWsUrl());
// 10. 缓存用户信息,创建会话
sessionManagerApi.createSession(jwtToken, loginUser, false);
// 11. 如果开启了单账号单端在线,则踢掉已经上线的该用户
if (AuthConfigExpander.getSingleAccountLoginFlag()) {
sessionManagerApi.removeSessionExcludeToken(jwtToken);
}
}
return new LoginResponse(loginUser, jwtToken, defaultJwtPayload.getExpirationDate());
}
}
@Override
public LoginResponse loginByOpenId(String openId) {
WXUserRequest wxUserRequest = new WXUserRequest();
wxUserRequest.setOpenId(openId);
List<WXUser> wxUsers = wxUserService.findList(wxUserRequest);
SysUser sysUser = null;
if(wxUsers.size() >0){
sysUser = this.sysUserService.getById(wxUsers.get(0).getUserId());
}
if(sysUser ==null){
throw new AuthException(AuthExceptionEnum.SSO_LOGIN_CODE_GET_ERROR);
}
UserLoginInfoDTO userValidateInfo = userServiceApi.getUserLoginInfo(sysUser.getAccount());
LoginUser loginUser = userValidateInfo.getLoginUser();
// 9. 生成用户的token
DefaultJwtPayload defaultJwtPayload = new DefaultJwtPayload(loginUser.getUserId(), loginUser.getAccount(), false, null);
String jwtToken = JwtContext.me().generateTokenDefaultPayload(defaultJwtPayload);
loginUser.setToken(jwtToken);
// 如果包含租户编码,则放到loginUser中
loginUser.setTenantCode("");
synchronized (SESSION_OPERATE_LOCK) {
// 9.1 获取ws-url 保存到用户信息中loginUser.setWsUrl(WebSocketConfigExpander.getWebSocketWsUrl());
// 10. 缓存用户信息,创建会话
sessionManagerApi.createSession(jwtToken, loginUser, true);
// 11. 如果开启了单账号单端在线,则踢掉已经上线的该用户
if (AuthConfigExpander.getSingleAccountLoginFlag()) {
sessionManagerApi.removeSessionExcludeToken(jwtToken);
}
}
return new LoginResponse(loginUser, jwtToken, defaultJwtPayload.getExpirationDate());
}
private HashMap<String,String> getAccessToken(String code)
{
try {
HashMap<String,String> map = new HashMap<String,String>();
String url = " https://api.weixin.qq.com/sns/oauth2/access_token";
String params = "appid="+"appid"+"&secret="+"secret&code="+code+"&grant_type=authorization_code";
String result = HttpRequest.sendGet(url, params);
log.info("推送结果getAccessToken:" + result);
if (result != "") {
JSONObject json = JSONObject.parseObject(result);
if(json.get("access_token") != null && json.get("openid") != null){
map.put("access_token",json.getString("access_token"));
map.put("openid",json.getString("openid"));
return map;
}else{
return null;
}
}
return null;
}catch (Exception ex)
{
log.error("",ex);
return null;
}
}
}
3.辅助类
package cn.stylefeng.guns.modular.hourse.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HttpRequest {
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
/* for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}*/
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream(),"utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param, HashMap<String,String> headParams) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
/*conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");*/
conn.setRequestProperty("Content-Type","application/json");
if(headParams != null){
for(Map.Entry<String, String> entry : headParams.entrySet()) {
conn.setRequestProperty(entry.getKey(),entry.getValue());
}
}
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(),"utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
public static String sendPostJson(String url, String json, HashMap<String,String> headParams) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection)realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
//conn.setRequestProperty("Connection", "Keep-Alive");
//conn.setRequestProperty("Charset", "UTF-8");
// 设置文件类型:
conn.setRequestProperty("Content-Type","application/json");
if(headParams != null){
for(Map.Entry<String, String> entry : headParams.entrySet()) {
conn.setRequestProperty(entry.getKey(),entry.getValue());
}
}
// 往服务器里面发送数据
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(json);
// flush输出流的缓冲
out.flush();
/*if (json != null && !"".equals(json)) {
byte[] writebytes = json.getBytes();
// 设置文件长度
conn.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(writebytes);
// flush输出流的缓冲
out.flush();
}*/
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(),"utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
}
五、vue前端支持
1.增加按钮
<x-button
size="large"
class="mybutton"
action-type="button"
type="primary"
@click.native="doSubmitWX()">微信登录</x-button>
2.实现doSubmitWX
doSubmitWX() {
this.getWXMessage('snsapi_userinfo');
},
getWXMessage(scope) {
if (isWeChat()) {
let appId = 'appid';
let redirectUri = 'https://hourse.zjljc.vip/hourseApp/#/login';
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=` + scope + `&state=1#wechat_redirect`
}
},
3.跳转返回
mounted () {
// alert(window.location);
let code = this.getUrlParam('code');
// alert('mounted:' + code);
if (code !== undefined && code != null) {
this.loginSuccessWX(code);
}
},
methods: {
async loginSuccessWX1 (code) {
try {
// loading.value = true;
// alert('loginWX:' + code);
const data = await LoginApi.loginByOpenId({'code': code}).catch(() => {
// loading.value = false;
});
// alert('response:' + JSON.stringify(data));
if (data.success) {
// 如果没开启单点登录,则直接将token
// 清除回车事件
// message.success('登录成功');
this.$store
.dispatch('user/setToken', {
token: data.data.token,
remember: true
})
.then(() => {
this.goHome();
});
}
} catch (e) {
// TODO zhuoda sentry
console.error('error', e);
// alert(e);
// this.btnLoading = false;
// this.verificationCode();
}
}
}
4、请求API
static loginWX (params) {
return Request.post('/loginWXApi', params);
}