From 12edd5dc0b53eaa21eb365e2dc8e6d37ff360119 Mon Sep 17 00:00:00 2001
From: "DESKTOP-G8BCEP0\\HP" <2037158277@qq.com>
Date: Thu, 9 Sep 2021 12:01:03 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=BE=AE=E4=BF=A1?=
=?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=8E=88=E6=9D=83=E7=99=BB=E5=BD=95?=
=?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97=EF=BC=88=E5=8D=95?=
=?UTF-8?q?=E7=8B=AC=E8=BF=90=E8=A1=8C=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 5 +
.../java/com/xkrs/common/tool/JwtUtil.java | 94 +++++++++++
.../controller/AppletsUserController.java | 46 +++++
.../java/com/xkrs/dao/AppletsUserDao.java | 39 +++++
src/main/java/com/xkrs/dao/SysUserDao.java | 7 +
.../com/xkrs/model/entity/AppletsUser.java | 153 +++++++++++++++++
.../com/xkrs/model/entity/SysUserEntity.java | 12 ++
.../com/xkrs/service/AppletsUserService.java | 26 +++
.../service/impl/AppletsUserServiceImpl.java | 157 ++++++++++++++++++
src/main/java/com/xkrs/utils/DecodeUtils.java | 82 +++++++++
.../java/com/xkrs/utils/HttpClientUtil.java | 136 +++++++++++++++
11 files changed, 757 insertions(+)
create mode 100644 src/main/java/com/xkrs/common/tool/JwtUtil.java
create mode 100644 src/main/java/com/xkrs/controller/AppletsUserController.java
create mode 100644 src/main/java/com/xkrs/dao/AppletsUserDao.java
create mode 100644 src/main/java/com/xkrs/model/entity/AppletsUser.java
create mode 100644 src/main/java/com/xkrs/service/AppletsUserService.java
create mode 100644 src/main/java/com/xkrs/service/impl/AppletsUserServiceImpl.java
create mode 100644 src/main/java/com/xkrs/utils/DecodeUtils.java
create mode 100644 src/main/java/com/xkrs/utils/HttpClientUtil.java
diff --git a/pom.xml b/pom.xml
index db86383..10eb0e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,6 +149,11 @@
poi-ooxml
${poi-ooxml.version}
+
+ com.auth0
+ java-jwt
+ 3.7.0
+
diff --git a/src/main/java/com/xkrs/common/tool/JwtUtil.java b/src/main/java/com/xkrs/common/tool/JwtUtil.java
new file mode 100644
index 0000000..04f4cd2
--- /dev/null
+++ b/src/main/java/com/xkrs/common/tool/JwtUtil.java
@@ -0,0 +1,94 @@
+package com.xkrs.common.tool;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTDecodeException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
+
+/**
+ * @Author Scott
+ * @Date 2018-07-12 14:23
+ * @Desc JWT工具类
+ **/
+public class JwtUtil {
+
+ /**
+ * Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
+ */
+ public static final long EXPIRE_TIME = 30 * 60 * 1000;
+
+ /**
+ * 校验token是否正确
+ *
+ * @param token 密钥
+ * @param secret 用户的密码
+ * @return 是否正确
+ */
+ public static boolean verify(String token, String username, String secret) {
+ try {
+ // 根据密码生成JWT效验器
+ Algorithm algorithm = Algorithm.HMAC256(secret);
+ JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
+ // 效验TOKEN
+ DecodedJWT jwt = verifier.verify(token);
+ return true;
+ } catch (Exception exception) {
+ return false;
+ }
+ }
+
+ /**
+ * 获得token中的信息无需secret解密也能获得
+ *
+ * @return token中包含的用户名
+ */
+ public static String getUsername(String token) {
+ try {
+ DecodedJWT jwt = JWT.decode(token);
+ return jwt.getClaim("username").asString();
+ } catch (JWTDecodeException e) {
+ return null;
+ }
+ }
+
+ /**
+ * 生成签名,5min后过期
+ *
+ * @param username 用户名
+ * @param secret 用户的密码
+ * @return 加密的token
+ */
+ public static String sign(String username, String secret) {
+ Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
+ Algorithm algorithm = Algorithm.HMAC256(secret);
+ // 附带username信息
+ return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
+
+ }
+
+ /**
+ * 根据request中的token获取用户账号
+ *
+ * @param request
+ * @return
+ * @throws
+ */
+ public static String getUserNameByToken(HttpServletRequest request){
+ String accessToken = request.getHeader("Authorization");
+ if(accessToken ==null){
+ return null;
+ }
+ String username = getUsername(accessToken);
+ return username;
+ }
+
+ public static void main(String[] args) {
+ String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0";
+ System.out.println(JwtUtil.getUsername(token));
+
+ }
+}
diff --git a/src/main/java/com/xkrs/controller/AppletsUserController.java b/src/main/java/com/xkrs/controller/AppletsUserController.java
new file mode 100644
index 0000000..f03b8d3
--- /dev/null
+++ b/src/main/java/com/xkrs/controller/AppletsUserController.java
@@ -0,0 +1,46 @@
+package com.xkrs.controller;
+
+import com.xkrs.service.AppletsUserService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * @author HP
+ */
+@RestController
+public class AppletsUserController {
+
+ @Resource
+ private AppletsUserService appletsUserService;
+
+ /**
+ * 微信小程序登录
+ * @param map
+ * @return
+ */
+ @PostMapping("/userLogin")
+ public String userLogin(@RequestBody Map map){
+ String avatarUrl = (String) map.get("avatarUrl");
+ String nickName = (String) map.get("nickName");
+ Integer sex = (Integer) map.get("sex");
+ String code = (String) map.get("code");
+ return appletsUserService.userLogin(avatarUrl,nickName,sex,code);
+ }
+
+ /**
+ * 解析手机号
+ * @param map
+ * @return
+ */
+ @PostMapping("/decodePhone")
+ public String decodePhone(@RequestBody Map map){
+ String encryptedData = (String) map.get("encryptedData");
+ String iv = (String) map.get("iv");
+ String openId = (String) map.get("openId");
+ return appletsUserService.decodePhone(encryptedData,iv,openId);
+ }
+}
diff --git a/src/main/java/com/xkrs/dao/AppletsUserDao.java b/src/main/java/com/xkrs/dao/AppletsUserDao.java
new file mode 100644
index 0000000..83070c9
--- /dev/null
+++ b/src/main/java/com/xkrs/dao/AppletsUserDao.java
@@ -0,0 +1,39 @@
+package com.xkrs.dao;
+
+import com.xkrs.model.entity.AppletsUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author XinYi Song
+ */
+@Component
+public interface AppletsUserDao extends JpaRepository {
+
+ /**
+ * 根据openid查询用户信息
+ * @param openId
+ * @return
+ */
+ AppletsUser findByOpenId(String openId);
+
+ /**
+ * 根据用户id修改SessionKey
+ * @param userId
+ * @param SessionKey
+ */
+ @Query(value = "update applets_user set session_key = ?2 where id = ?1",nativeQuery = true)
+ @Modifying(clearAutomatically=true)
+ void updateSessionKey(Integer userId,String SessionKey);
+
+ /**
+ * 根据openId修改手机号
+ * @param openId
+ * @param phone
+ */
+ @Query(value = "update applets_user set user_phone = ?2 where open_id = ?1",nativeQuery = true)
+ @Modifying(clearAutomatically=true)
+ void updatePhone(String openId,String phone);
+}
diff --git a/src/main/java/com/xkrs/dao/SysUserDao.java b/src/main/java/com/xkrs/dao/SysUserDao.java
index 8f91591..673b6d1 100644
--- a/src/main/java/com/xkrs/dao/SysUserDao.java
+++ b/src/main/java/com/xkrs/dao/SysUserDao.java
@@ -127,4 +127,11 @@ public interface SysUserDao extends JpaRepository {
*/
@Query(value = "select * from sys_user where id = ?",nativeQuery = true)
SysUserEntity selectByUserId(Integer userId);
+
+ /**
+ * 根据openId查询用户的信息
+ * @param openId
+ * @return
+ */
+ SysUserEntity findByOpenId(String openId);
}
diff --git a/src/main/java/com/xkrs/model/entity/AppletsUser.java b/src/main/java/com/xkrs/model/entity/AppletsUser.java
new file mode 100644
index 0000000..b27aa75
--- /dev/null
+++ b/src/main/java/com/xkrs/model/entity/AppletsUser.java
@@ -0,0 +1,153 @@
+package com.xkrs.model.entity;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * 小程序用户表
+ * @author XinYi Song
+ */
+@Entity
+@Table(name="applets_user")
+public class AppletsUser {
+
+ /**
+ * 指定主键,建立自增序列,主键值取自序列
+ */
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "applets_user_seq_gen")
+ @SequenceGenerator(name = "applets_user_seq_gen", sequenceName = "applets_user_id_seq",allocationSize = 1)
+ private Integer id;
+
+ /** 昵称 */
+ @Column(length = 65,columnDefinition = "varchar(65)")
+ private String nickName;
+
+ /** 手机号 */
+ @Column(length = 65,columnDefinition = "varchar(65)")
+ private String userPhone;
+
+ /** 用户头像 */
+ private String userPhoto;
+
+ /** 性别 */
+ @Column(length = 55,columnDefinition = "varchar(55)")
+ private String userSex;
+
+ /** openid */
+ private String openId;
+
+ /** sessionKey */
+ private String sessionKey;
+
+ private Integer code;
+
+ private String token;
+
+ private LocalDateTime lastEntryTime;
+
+ @Column(columnDefinition = "varchar(64)")
+ private String lastEntryIp;
+
+ public AppletsUser() {
+ }
+
+ public AppletsUser(Integer id, String nickName, String userPhone, String userPhoto, String userSex, String openId, String sessionKey, Integer code, String token) {
+ this.id = id;
+ this.nickName = nickName;
+ this.userPhone = userPhone;
+ this.userPhoto = userPhoto;
+ this.userSex = userSex;
+ this.openId = openId;
+ this.sessionKey = sessionKey;
+ this.code = code;
+ this.token = token;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getUserPhone() {
+ return userPhone;
+ }
+
+ public void setUserPhone(String userPhone) {
+ this.userPhone = userPhone;
+ }
+
+ public String getUserPhoto() {
+ return userPhoto;
+ }
+
+ public void setUserPhoto(String userPhoto) {
+ this.userPhoto = userPhoto;
+ }
+
+ public String getUserSex() {
+ return userSex;
+ }
+
+ public void setUserSex(String userSex) {
+ this.userSex = userSex;
+ }
+
+ public String getOpenId() {
+ return openId;
+ }
+
+ public void setOpenId(String openId) {
+ this.openId = openId;
+ }
+
+ public String getSessionKey() {
+ return sessionKey;
+ }
+
+ public void setSessionKey(String sessionKey) {
+ this.sessionKey = sessionKey;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ @Override
+ public String toString() {
+ return "AppletsUser{" +
+ "id=" + id +
+ ", nickName='" + nickName + '\'' +
+ ", userPhone='" + userPhone + '\'' +
+ ", userPhoto='" + userPhoto + '\'' +
+ ", userSex='" + userSex + '\'' +
+ ", openId='" + openId + '\'' +
+ ", sessionKey='" + sessionKey + '\'' +
+ ", code=" + code +
+ ", token='" + token + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/com/xkrs/model/entity/SysUserEntity.java b/src/main/java/com/xkrs/model/entity/SysUserEntity.java
index fd02d3c..dd3a2c4 100644
--- a/src/main/java/com/xkrs/model/entity/SysUserEntity.java
+++ b/src/main/java/com/xkrs/model/entity/SysUserEntity.java
@@ -71,6 +71,9 @@ public class SysUserEntity implements Serializable {
@Column(columnDefinition = "varchar(64)")
private String lastEntryIp;
+ @Column(columnDefinition = "varchar(88)")
+ private String openId;
+
public Integer getId() {
return id;
}
@@ -183,6 +186,14 @@ public class SysUserEntity implements Serializable {
this.lastEntryIp = lastEntryIp;
}
+ public String getOpenId() {
+ return openId;
+ }
+
+ public void setOpenId(String openId) {
+ this.openId = openId;
+ }
+
@Override
public String toString() {
return "SysUserEntity{" +
@@ -200,6 +211,7 @@ public class SysUserEntity implements Serializable {
", lastEntryTime=" + lastEntryTime +
", deleteFlag=" + deleteFlag +
", lastEntryIp='" + lastEntryIp + '\'' +
+ ", openId='" + openId + '\'' +
'}';
}
}
diff --git a/src/main/java/com/xkrs/service/AppletsUserService.java b/src/main/java/com/xkrs/service/AppletsUserService.java
new file mode 100644
index 0000000..a0c8368
--- /dev/null
+++ b/src/main/java/com/xkrs/service/AppletsUserService.java
@@ -0,0 +1,26 @@
+package com.xkrs.service;
+
+/**
+ * @author XinYi Song
+ */
+public interface AppletsUserService {
+
+ /**
+ * 用户小程序登录
+ * @param avatarUrl 头像
+ * @param nickName 昵称
+ * @param sex 性别
+ * @param code
+ * @return
+ */
+ String userLogin(String avatarUrl,String nickName,Integer sex,String code);
+
+ /**
+ * 解析手机号
+ * @param encryptedData
+ * @param iv
+ * @param openId
+ * @return
+ */
+ String decodePhone(String encryptedData,String iv,String openId);
+}
diff --git a/src/main/java/com/xkrs/service/impl/AppletsUserServiceImpl.java b/src/main/java/com/xkrs/service/impl/AppletsUserServiceImpl.java
new file mode 100644
index 0000000..f43371f
--- /dev/null
+++ b/src/main/java/com/xkrs/service/impl/AppletsUserServiceImpl.java
@@ -0,0 +1,157 @@
+package com.xkrs.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.xkrs.common.encapsulation.PromptMessageEnum;
+import com.xkrs.common.tool.JwtUtil;
+import com.xkrs.dao.AppletsUserDao;
+import com.xkrs.model.entity.AppletsUser;
+import com.xkrs.service.AppletsUserService;
+import com.xkrs.utils.DecodeUtils;
+import com.xkrs.utils.HttpClientUtil;
+import io.micrometer.core.instrument.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.transaction.Transactional;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static com.xkrs.common.encapsulation.OutputEncapsulation.outputEncapsulationObject;
+
+/**
+ * @author HP
+ */
+@Service
+public class AppletsUserServiceImpl implements AppletsUserService {
+ public static Logger log = LoggerFactory.getLogger(AppletsUserServiceImpl.class);
+
+ @Resource
+ private AppletsUserDao appletsUserDao;
+
+ @Resource
+ private DecodeUtils decodeUtils;
+
+ /**
+ * 用户登录
+ * @param avatarUrl 头像
+ * @param nickName 昵称
+ * @param sex 性别
+ * @param code wx.login()获取的
+ * @return
+ */
+ @Transactional(rollbackOn = Exception.class)
+ @Override
+ public String userLogin(String avatarUrl, String nickName, Integer sex, String code) {
+ Locale locale = LocaleContextHolder.getLocale();
+ try {
+ log.info("进入微信登录实现方法----------------->");
+ String sexs = sex + "";
+ // 创建Httpclient对象
+ String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
+ Map requestUrlParam = new HashMap<>();
+ //小程序appId
+ requestUrlParam.put("appid","wxcdd789a27dd7dace");
+ //小程序secret
+ requestUrlParam.put("secret","78436fda2488c08d4a3744bfd1613265");
+ //小程序端返回的code
+ requestUrlParam.put("js_code",code);
+ //默认参数
+ requestUrlParam.put("grant_type","authorization_code");
+ JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));
+ // 解析json
+ //JSONObject jsonObject = (JSONObject) JSONObject.parse(resultString);
+ String sessionKeys = jsonObject.get("session_key").toString();
+ log.info("sessionKey-------"+sessionKeys);
+ String openId = jsonObject.get("openid").toString();
+ //校验openId是否有效
+ if (StringUtils.isBlank(openId) || StringUtils.isBlank(sessionKeys)) {
+ return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"用户登陆失败",locale);
+ }
+ //以unionId去查是否存在用户,如果存在修改用户信息并返回
+ AppletsUser appletsUser = appletsUserDao.findByOpenId(openId);
+ if (appletsUser != null) {
+ appletsUser.setSessionKey(sessionKeys);
+ appletsUserDao.updateSessionKey(appletsUser.getId(),sessionKeys);
+ //设置token
+ log.info("====="+appletsUser.getId());
+ String token = JwtUtil.sign(appletsUser.getNickName(), sessionKeys);
+ Map map = new HashMap(3);
+ map.put("token",token);
+ map.put("openId",appletsUser.getOpenId());
+ map.put("session_key",sessionKeys);
+ return outputEncapsulationObject(PromptMessageEnum.SUCCESS,map,locale);
+ }else{
+ AppletsUser appletsUser1 = new AppletsUser();
+ appletsUser1.setNickName(nickName);
+ appletsUser1.setUserPhoto(avatarUrl);
+ appletsUser1.setUserSex(sexs);
+ appletsUser1.setOpenId(openId);
+ appletsUser1.setSessionKey(sessionKeys);
+ //新增用户信息
+ if (appletsUserDao.save(appletsUser1) != null) {
+ log.info("插入用户成功------------>");
+ System.out.println("拿到userId----------------------->"+appletsUser1.getId());
+ //设置token
+ String token = JwtUtil.sign(appletsUser1.getNickName(), appletsUser1.getSessionKey());
+ Map map = new HashMap(3);
+ map.put("token",token);
+ map.put("openId",appletsUser1.getOpenId());
+ map.put("session_key",appletsUser1.getSessionKey());
+ return outputEncapsulationObject(PromptMessageEnum.SUCCESS,map,locale);
+ } else {
+ return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"微信登录失败,请稍后重试",locale);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"微信登录失败,请稍后重试",locale);
+ }
+
+ /**
+ * 解析手机号
+ * @param encryptedData
+ * @param iv
+ * @param openId
+ * @return
+ */
+ @Transactional(rollbackOn = Exception.class)
+ @Override
+ public String decodePhone(String encryptedData, String iv, String openId) {
+ Locale locale = LocaleContextHolder.getLocale();
+ log.info("进入解密手机号实现方法------------->");
+ try {
+ //通过userId获取用户信息用于解密手机号
+ AppletsUser appletsUser = appletsUserDao.findByOpenId(openId);
+ if (null == appletsUser) {
+ return outputEncapsulationObject(PromptMessageEnum.DATA_WRONG,"用户信息错误,请稍后重试",locale);
+ }
+ if (StringUtils.isNotBlank(appletsUser.getUserPhone())) {
+ //以userId作为redisKey存入redis并设置有效时间为半小时
+ //redisClient.set(tourismUser.getTourismId(), tourismUser.getUserPhone(), 1800);
+ return outputEncapsulationObject(PromptMessageEnum.SUCCESS,"获取用户手机号成功",locale);
+ }
+ // 用于解密手机号的sessionKey
+ String sessionKey = appletsUser.getSessionKey();
+ //解密获得手机号
+ JSONObject jsonObject = decodeUtils.wxDecrypt(encryptedData, sessionKey, iv);
+ String phone = jsonObject.getString("phoneNumber");
+ if (StringUtils.isNotEmpty(phone)) {
+ log.info("用户手机号为--------->" + phone);
+ //插入用户手机号
+ appletsUserDao.updatePhone(openId,phone);
+ log.info("插入用户手机号成功----------->");
+ //redisClient.set(tourismUser.getTourismId(), phone, 1800);
+ return outputEncapsulationObject(PromptMessageEnum.SUCCESS,"获取用户手机号成功",locale);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"获取手机号失败",locale);
+ }
+}
diff --git a/src/main/java/com/xkrs/utils/DecodeUtils.java b/src/main/java/com/xkrs/utils/DecodeUtils.java
new file mode 100644
index 0000000..cf4f24b
--- /dev/null
+++ b/src/main/java/com/xkrs/utils/DecodeUtils.java
@@ -0,0 +1,82 @@
+package com.xkrs.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.tomcat.util.codec.binary.Base64;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.Security;
+
+/**
+ * 解密工具类
+ *
+ * @Author duyongmeng
+ * @Time 2020/11/10
+ */
+@Component
+public class DecodeUtils {
+ // 算法名
+ public static final String KEY_NAME = "AES";
+ // 加解密算法/模式/填充方式
+ // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
+ public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
+
+ /**
+ * @param encrypted 目标密文
+ * @param session_key 会话ID
+ * @param iv 加密算法的初始向量
+ */
+ public JSONObject wxDecrypt(String encrypted, String session_key, String iv) {
+ String json;
+ JSONObject jsonObject = null;
+ byte[] encrypted64 = Base64.decodeBase64(encrypted);
+ byte[] key64 = Base64.decodeBase64(session_key);
+ byte[] iv64 = Base64.decodeBase64(iv);
+ byte[] data;
+ try {
+ init();
+ json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
+ jsonObject = JSONObject.parseObject(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return jsonObject;
+ }
+
+ /**
+ * 初始化密钥
+ */
+ public static void init() throws Exception {
+ Security.addProvider(new BouncyCastleProvider());
+ KeyGenerator.getInstance(KEY_NAME).init(128);
+ }
+
+ /**
+ * 生成iv
+ */
+ public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
+ // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
+ // Arrays.fill(iv, (byte) 0x00);
+ AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
+ params.init(new IvParameterSpec(iv));
+ return params;
+ }
+
+ /**
+ * 生成解密
+ */
+ public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
+ throws Exception {
+ Key key = new SecretKeySpec(keyBytes, KEY_NAME);
+ Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
+ // 设置为解密模式
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+ return cipher.doFinal(encryptedData);
+ }
+}
diff --git a/src/main/java/com/xkrs/utils/HttpClientUtil.java b/src/main/java/com/xkrs/utils/HttpClientUtil.java
new file mode 100644
index 0000000..36473a9
--- /dev/null
+++ b/src/main/java/com/xkrs/utils/HttpClientUtil.java
@@ -0,0 +1,136 @@
+package com.xkrs.utils;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author HP
+ */
+public class HttpClientUtil {
+
+ public static String doGet(String url, Map param) {
+
+ // 创建Httpclient对象
+ CloseableHttpClient httpclient = HttpClients.createDefault();
+
+ String resultString = "";
+ CloseableHttpResponse response = null;
+ try {
+ // 创建uri
+ URIBuilder builder = new URIBuilder(url);
+ if (param != null) {
+ for (String key : param.keySet()) {
+ builder.addParameter(key, param.get(key));
+ }
+ }
+ URI uri = builder.build();
+
+ // 创建http GET请求
+ HttpGet httpGet = new HttpGet(uri);
+
+ // 执行请求
+ response = httpclient.execute(httpGet);
+ // 判断返回状态是否为200
+ if (response.getStatusLine().getStatusCode() == 200) {
+ resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (response != null) {
+ response.close();
+ }
+ httpclient.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return resultString;
+ }
+
+ public static String doGet(String url) {
+ return doGet(url, null);
+ }
+
+ public static String doPost(String url, Map param) {
+ // 创建Httpclient对象
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ String resultString = "";
+ try {
+ // 创建Http Post请求
+ HttpPost httpPost = new HttpPost(url);
+ // 创建参数列表
+ if (param != null) {
+ List paramList = new ArrayList<>();
+ for (String key : param.keySet()) {
+ paramList.add(new BasicNameValuePair(key, param.get(key)));
+ }
+ // 模拟表单
+ UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
+ httpPost.setEntity(entity);
+ }
+ // 执行http请求
+ response = httpClient.execute(httpPost);
+ resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return resultString;
+ }
+
+ public static String doPost(String url) {
+ return doPost(url, null);
+ }
+
+ public static String doPostJson(String url, String json) {
+ // 创建Httpclient对象
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+ CloseableHttpResponse response = null;
+ String resultString = "";
+ try {
+ // 创建Http Post请求
+ HttpPost httpPost = new HttpPost(url);
+ // 创建请求内容
+ StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
+ httpPost.setEntity(entity);
+ // 执行http请求
+ response = httpClient.execute(httpPost);
+ resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ response.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return resultString;
+ }
+}