| | |
| | | <version>2.3.30</version> |
| | | </dependency> |
| | | |
| | | |
| | | <dependency> |
| | | <groupId>com.alipay.sdk</groupId> |
| | | <artifactId>alipay-sdk-java</artifactId> |
| | | <version>4.8.10.ALL</version> |
| | | </dependency> |
| | | <!-- oos对象存储 --> |
| | | <dependency> |
| | | <groupId>com.aliyun.oss</groupId> |
| | | <artifactId>aliyun-sdk-oss</artifactId> |
| | | <version>3.8.0</version> |
| | | </dependency> |
| | | <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core --> |
| | | <dependency> |
| | | <groupId>com.aliyun</groupId> |
| | | <artifactId>aliyun-java-sdk-core</artifactId> |
| | | <version>4.4.3</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.jsonwebtoken</groupId> |
| | | <artifactId>jjwt</artifactId> |
| | | <version>0.9.0</version> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | package com.dsh.account.controller; |
| | | |
| | | import com.dsh.account.model.AddAppUserVo; |
| | | import com.dsh.account.model.LoginSMSCodeVo; |
| | | import com.dsh.account.model.LoginWeChatVo; |
| | | import com.dsh.account.service.TAppUserService; |
| | | import com.dsh.account.util.ResultUtil; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/getSMSCode") |
| | | @ApiOperation(value = "获取短信验证码", tags = {"用户—登录注册"}) |
| | | @ApiOperation(value = "获取短信验证码", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "类型(1:登录,2:注册,3:修改密码,4:忘记密码)", name = "type", dataType = "int", required = true), |
| | | @ApiImplicitParam(value = "电话号码", name = "phone", dataType = "string", required = true) |
| | |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/addAppUser") |
| | | @ApiOperation(value = "注册用户", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | }) |
| | | public ResultUtil addAppUser(@RequestBody AddAppUserVo addAppUserVo){ |
| | | try { |
| | | return appUserService.addAppUser(addAppUserVo); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/loginPassword") |
| | | @ApiOperation(value = "账号密码登录", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "电话号码", name = "phone", dataType = "string", required = true), |
| | | @ApiImplicitParam(value = "登录密码", name = "password", dataType = "string", required = true) |
| | | }) |
| | | public ResultUtil<String> loginPassword(@RequestBody String phone, @RequestBody String password){ |
| | | try { |
| | | return appUserService.loginPassword(phone, password); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/loginSMSCode") |
| | | @ApiOperation(value = "短信验证码登录", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | }) |
| | | public ResultUtil<String> loginSMSCode(@RequestBody LoginSMSCodeVo loginSMSCodeVo){ |
| | | try { |
| | | return appUserService.loginSMSCode(loginSMSCodeVo); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/loginWeChat") |
| | | @ApiOperation(value = "微信登录", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | }) |
| | | public ResultUtil<String> loginWeChat(@RequestBody LoginWeChatVo loginWeChatVo){ |
| | | try { |
| | | return appUserService.loginWechat(loginWeChatVo); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/updatePassword") |
| | | @ApiOperation(value = "修改密码", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "电话号码", name = "phone", dataType = "string", required = true), |
| | | @ApiImplicitParam(value = "短信验证码", name = "code", dataType = "string", required = true), |
| | | @ApiImplicitParam(value = "新密码", name = "password", dataType = "string", required = true) |
| | | }) |
| | | public ResultUtil updatePassword(@RequestBody String phone, @RequestBody String code, @RequestBody String password){ |
| | | try { |
| | | return appUserService.updatePassword(phone, code, password); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/base/appUser/forgetPassword") |
| | | @ApiOperation(value = "忘记密码", tags = {"APP-登录注册"}) |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(value = "电话号码", name = "phone", dataType = "string", required = true), |
| | | @ApiImplicitParam(value = "短信验证码", name = "code", dataType = "string", required = true), |
| | | @ApiImplicitParam(value = "新密码", name = "password", dataType = "string", required = true) |
| | | }) |
| | | public ResultUtil forgetPassword(@RequestBody String phone, @RequestBody String code, @RequestBody String password){ |
| | | try { |
| | | return appUserService.updatePassword(phone, code, password); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | return ResultUtil.runErr(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.model; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel |
| | | public class AddAppUserVo{ |
| | | @ApiModelProperty(value = "手机号", dataType = "string", required = true) |
| | | private String phone; |
| | | @ApiModelProperty(value = "验证码", dataType = "string", required = true) |
| | | private String code; |
| | | @ApiModelProperty(value = "密码", dataType = "string", required = true) |
| | | private String password; |
| | | @ApiModelProperty(value = "邀请人id", dataType = "int", required = false) |
| | | private Integer referralUserId; |
| | | @ApiModelProperty(value = "注册纬度", dataType = "string", required = true) |
| | | private String latitude; |
| | | @ApiModelProperty(value = "注册经度", dataType = "string", required = true) |
| | | private String longitude; |
| | | } |
New file |
| | |
| | | package com.dsh.account.model; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @date 2023/6/15 18:59 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class LoginSMSCodeVo { |
| | | @ApiModelProperty(value = "手机号", dataType = "string", required = true) |
| | | private String phone; |
| | | @ApiModelProperty(value = "验证码", dataType = "string", required = true) |
| | | private String code; |
| | | @ApiModelProperty(value = "注册纬度", dataType = "string", required = true) |
| | | private String latitude; |
| | | @ApiModelProperty(value = "注册经度", dataType = "string", required = true) |
| | | private String longitude; |
| | | } |
New file |
| | |
| | | package com.dsh.account.model; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @date 2023/6/15 18:51 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class LoginWeChatVo { |
| | | @ApiModelProperty(value = "微信openId", dataType = "string", required = true) |
| | | private String openId; |
| | | @ApiModelProperty(value = "手机号", dataType = "string", required = true) |
| | | private String phone; |
| | | @ApiModelProperty(value = "注册纬度", dataType = "string", required = true) |
| | | private String latitude; |
| | | @ApiModelProperty(value = "注册经度", dataType = "string", required = true) |
| | | private String longitude; |
| | | } |
| | |
| | | package com.dsh.account.service; |
| | | |
| | | import com.dsh.account.entity.TAppUser; |
| | | import com.dsh.account.model.AddAppUserVo; |
| | | import com.dsh.account.model.LoginSMSCodeVo; |
| | | import com.dsh.account.model.LoginWeChatVo; |
| | | import com.dsh.account.model.vo.classDetails.classInsVo.ClassInfoVo; |
| | | import com.dsh.account.util.ResultUtil; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil getSMSCode(Integer type, String phone) throws Exception; |
| | | |
| | | |
| | | /** |
| | | * 注册账号 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil addAppUser(AddAppUserVo addAppUserVo) throws Exception; |
| | | |
| | | |
| | | /** |
| | | * 账号密码登录 |
| | | * @param phone |
| | | * @param password |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil loginPassword(String phone, String password) throws Exception; |
| | | |
| | | |
| | | /** |
| | | * 验证码登录 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil loginSMSCode(LoginSMSCodeVo loginSMSCodeVo) throws Exception; |
| | | |
| | | |
| | | /** |
| | | * 微信登录 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil loginWechat(LoginWeChatVo loginWechatVo) throws Exception; |
| | | |
| | | |
| | | /** |
| | | * 修改密码 |
| | | * @param phone |
| | | * @param code |
| | | * @param password |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | ResultUtil updatePassword(String phone, String code, String password) throws Exception; |
| | | } |
| | |
| | | import com.dsh.account.mapper.TStudentMapper; |
| | | import com.dsh.account.feignclient.other.ImgConfigClient; |
| | | import com.dsh.account.feignclient.other.model.TImgConfig; |
| | | import com.dsh.account.model.AddAppUserVo; |
| | | import com.dsh.account.model.LoginSMSCodeVo; |
| | | import com.dsh.account.model.LoginWeChatVo; |
| | | import com.dsh.account.model.vo.classDetails.RegisteredCourse; |
| | | import com.dsh.account.service.TAppUserService; |
| | | import com.dsh.account.entity.TAppUser; |
| | |
| | | import com.dsh.account.mapper.TAppUserMapper; |
| | | import com.dsh.account.model.vo.classDetails.classInsVo.ClassInfoVo; |
| | | |
| | | import com.dsh.account.util.DateUtil; |
| | | import com.dsh.account.util.ResultUtil; |
| | | import com.dsh.account.util.ToolUtil; |
| | | import com.dsh.account.util.*; |
| | | import com.dsh.account.util.akeylogin.Md5Util; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | |
| | | @Resource |
| | | private ImgConfigClient configClient; |
| | | |
| | | @Autowired |
| | | private ALiSendSms aLiSendSms; |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | |
| | | @Autowired |
| | | private JwtTokenUtil jwtTokenUtil; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | @Resource |
| | | private CoursePaymentClient paymentClient; |
| | |
| | | @Override |
| | | public ResultUtil getSMSCode(Integer type, String phone) throws Exception { |
| | | if(type == 2){ |
| | | // this.baseMapper.selectOne(new EntityWrapper<>()) |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", phone).ne("state", 3)); |
| | | if(null != tAppUser){ |
| | | return ResultUtil.error("账号已存在"); |
| | | } |
| | | return null; |
| | | } |
| | | String numberRandom = UUIDUtil.getNumberRandom(6); |
| | | aLiSendSms.sendSms(phone, "SMS_161275250", "{\"code\":\"" + numberRandom + "\"}"); |
| | | redisUtil.setStrValue(phone, numberRandom, 300); |
| | | return ResultUtil.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 注册用户 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | public ResultUtil addAppUser(AddAppUserVo addAppUserVo) throws Exception { |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", addAppUserVo.getPhone()).ne("state", 3)); |
| | | if(null != tAppUser){ |
| | | return ResultUtil.error("账号已存在"); |
| | | } |
| | | String value = redisUtil.getValue(addAppUserVo.getPhone()); |
| | | if(ToolUtil.isEmpty(value) || !value.equals(addAppUserVo.getCode())){ |
| | | return ResultUtil.error("验证码无效"); |
| | | } |
| | | |
| | | tAppUser = new TAppUser(); |
| | | tAppUser.setPhone(addAppUserVo.getPhone()); |
| | | tAppUser.setPassword(Md5Util.MD5Encode(addAppUserVo.getPassword(), null)); |
| | | tAppUser.setIsVip(0); |
| | | tAppUser.setState(1); |
| | | if(ToolUtil.isNotEmpty(addAppUserVo.getLatitude()) && ToolUtil.isNotEmpty(addAppUserVo.getLongitude())){ |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(addAppUserVo.getLongitude(), addAppUserVo.getLatitude()); |
| | | if(null != geocode){ |
| | | String province = geocode.get("province"); |
| | | String provinceCode = geocode.get("provinceCode"); |
| | | String city = geocode.get("city"); |
| | | String cityCode = geocode.get("cityCode"); |
| | | tAppUser.setProvince(province); |
| | | tAppUser.setProvinceCode(provinceCode); |
| | | tAppUser.setCity(city); |
| | | tAppUser.setCityCode(cityCode); |
| | | } |
| | | } |
| | | this.baseMapper.insert(tAppUser); |
| | | return ResultUtil.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 账号密码登录 |
| | | * @param phone |
| | | * @param password |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | public ResultUtil loginPassword(String phone, String password) throws Exception { |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", phone).ne("state", 3)); |
| | | if(null == tAppUser){ |
| | | return ResultUtil.error("请先注册", ""); |
| | | } |
| | | if(tAppUser.getState() == 2){ |
| | | return ResultUtil.error("您的账号已被冻结", ""); |
| | | } |
| | | password = Md5Util.MD5Encode(password, null); |
| | | if(!tAppUser.getPassword().equals(password)){ |
| | | return ResultUtil.error("账号密码错误", ""); |
| | | } |
| | | String token = getToken(tAppUser); |
| | | return ResultUtil.success(token); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 验证码登录 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | public ResultUtil loginSMSCode(LoginSMSCodeVo loginSMSCodeVo) throws Exception { |
| | | String value = redisUtil.getValue(loginSMSCodeVo.getPhone()); |
| | | if(ToolUtil.isEmpty(value) || !value.equals(loginSMSCodeVo.getCode())){ |
| | | return ResultUtil.error("验证码无效"); |
| | | } |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", loginSMSCodeVo.getPhone()).ne("state", 3)); |
| | | if(null == tAppUser){ |
| | | tAppUser = new TAppUser(); |
| | | tAppUser.setPhone(loginSMSCodeVo.getPhone()); |
| | | tAppUser.setPassword(Md5Util.MD5Encode("111111", null)); |
| | | tAppUser.setIsVip(0); |
| | | tAppUser.setState(1); |
| | | if(ToolUtil.isNotEmpty(loginSMSCodeVo.getLatitude()) && ToolUtil.isNotEmpty(loginSMSCodeVo.getLongitude())){ |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(loginSMSCodeVo.getLongitude(), loginSMSCodeVo.getLatitude()); |
| | | if(null != geocode){ |
| | | String province = geocode.get("province"); |
| | | String provinceCode = geocode.get("provinceCode"); |
| | | String city = geocode.get("city"); |
| | | String cityCode = geocode.get("cityCode"); |
| | | tAppUser.setProvince(province); |
| | | tAppUser.setProvinceCode(provinceCode); |
| | | tAppUser.setCity(city); |
| | | tAppUser.setCityCode(cityCode); |
| | | } |
| | | } |
| | | this.baseMapper.insert(tAppUser); |
| | | } |
| | | if(tAppUser.getState() == 2){ |
| | | return ResultUtil.error("您的账号已被冻结", ""); |
| | | } |
| | | String token = getToken(tAppUser); |
| | | return ResultUtil.success(token); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 微信登录 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | public ResultUtil loginWechat(LoginWeChatVo loginWechatVo) throws Exception { |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("openid", loginWechatVo.getOpenId()).ne("state", 3)); |
| | | if(null == tAppUser){ |
| | | tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", loginWechatVo.getPhone()).ne("state", 3)); |
| | | if(null == tAppUser){ |
| | | tAppUser = new TAppUser(); |
| | | tAppUser.setOpenid(loginWechatVo.getOpenId()); |
| | | tAppUser.setPhone(loginWechatVo.getPhone()); |
| | | tAppUser.setPassword(Md5Util.MD5Encode("111111", null)); |
| | | tAppUser.setIsVip(0); |
| | | tAppUser.setState(1); |
| | | if(ToolUtil.isNotEmpty(loginWechatVo.getLatitude()) && ToolUtil.isNotEmpty(loginWechatVo.getLongitude())){ |
| | | Map<String, String> geocode = gdMapGeocodingUtil.geocode(loginWechatVo.getLongitude(), loginWechatVo.getLatitude()); |
| | | if(null != geocode){ |
| | | String province = geocode.get("province"); |
| | | String provinceCode = geocode.get("provinceCode"); |
| | | String city = geocode.get("city"); |
| | | String cityCode = geocode.get("cityCode"); |
| | | tAppUser.setProvince(province); |
| | | tAppUser.setProvinceCode(provinceCode); |
| | | tAppUser.setCity(city); |
| | | tAppUser.setCityCode(cityCode); |
| | | } |
| | | } |
| | | this.baseMapper.insert(tAppUser); |
| | | } |
| | | } |
| | | if(tAppUser.getState() == 2){ |
| | | return ResultUtil.error("您的账号已被冻结", ""); |
| | | } |
| | | |
| | | if(ToolUtil.isNotEmpty(tAppUser.getOpenid())){ |
| | | tAppUser.setOpenid(loginWechatVo.getOpenId()); |
| | | } |
| | | if(ToolUtil.isNotEmpty(tAppUser.getPhone())){ |
| | | tAppUser.setPhone(loginWechatVo.getPhone()); |
| | | } |
| | | this.updateById(tAppUser); |
| | | |
| | | String token = getToken(tAppUser); |
| | | return ResultUtil.success(token); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取JWT token和存储个人信息 |
| | | * @param appUser |
| | | * @return |
| | | */ |
| | | private String getToken(TAppUser appUser){ |
| | | String randomKey = jwtTokenUtil.getRandomKey(); |
| | | String token = jwtTokenUtil.generateToken(appUser.getId().toString(), randomKey); |
| | | redisUtil.setStrValue(token.substring(token.length() - 32), String.valueOf(appUser.getId()), 7 * 24 * 60 * 60); |
| | | redisUtil.setStrValue("USER_" + appUser.getPhone(), token.substring(token.length() - 32)); |
| | | redisUtil.setStrValue("USER_" + appUser.getId(), token); |
| | | return token; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 修改密码 |
| | | * @param phone |
| | | * @param code |
| | | * @param password |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @Override |
| | | public ResultUtil updatePassword(String phone, String code, String password) throws Exception { |
| | | String value = redisUtil.getValue(phone); |
| | | if(ToolUtil.isEmpty(value) || !value.equals(code)){ |
| | | return ResultUtil.error("验证码无效"); |
| | | } |
| | | TAppUser tAppUser = this.baseMapper.selectOne(new QueryWrapper<TAppUser>().eq("phone", phone).ne("state", 3)); |
| | | if(tAppUser.getState() == 2){ |
| | | return ResultUtil.error("您的账号已被冻结", ""); |
| | | } |
| | | tAppUser.setPassword(Md5Util.MD5Encode(password, null)); |
| | | this.updateById(tAppUser); |
| | | return ResultUtil.success(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util; |
| | | |
| | | |
| | | import com.aliyuncs.CommonRequest; |
| | | import com.aliyuncs.CommonResponse; |
| | | import com.aliyuncs.DefaultAcsClient; |
| | | import com.aliyuncs.IAcsClient; |
| | | import com.aliyuncs.exceptions.ClientException; |
| | | import com.aliyuncs.profile.DefaultProfile; |
| | | import com.google.gson.Gson; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 阿里云短信工具类 |
| | | */ |
| | | @Component |
| | | public class ALiSendSms { |
| | | |
| | | // 设置鉴权参数,初始化客户端 |
| | | private DefaultProfile profile = DefaultProfile.getProfile( |
| | | "cn-hangzhou",// 地域ID |
| | | "LTAI4G9Zez9H4B36vakPXGy4",// 您的AccessKey ID |
| | | "BOVPUeZndKVbrPOq6Ef5j6oiydB3XZ");// 您的AccessKey Secret |
| | | private IAcsClient client = new DefaultAcsClient(profile); |
| | | |
| | | private static void log_print(String functionName, Object result) { |
| | | Gson gson = new Gson(); |
| | | System.out.println("-------------------------------" + functionName + "-------------------------------"); |
| | | System.out.println(gson.toJson(result)); |
| | | } |
| | | |
| | | /** |
| | | * 添加短信模板 |
| | | */ |
| | | public String addSmsTemplate() throws ClientException { |
| | | CommonRequest addSmsTemplateRequest = new CommonRequest(); |
| | | addSmsTemplateRequest.setSysDomain("dysmsapi.aliyuncs.com"); |
| | | addSmsTemplateRequest.setSysAction("AddSmsTemplate"); |
| | | addSmsTemplateRequest.setSysVersion("2017-05-25"); |
| | | // 短信类型。0:验证码;1:短信通知;2:推广短信;3:国际/港澳台消息 |
| | | addSmsTemplateRequest.putQueryParameter("TemplateType", "0"); |
| | | // 模板名称,长度为1~30个字符 |
| | | addSmsTemplateRequest.putQueryParameter("TemplateName", "测试短信模板"); |
| | | // 模板内容,长度为1~500个字符 |
| | | addSmsTemplateRequest.putQueryParameter("TemplateContent", "您正在申请手机注册,验证码为:${code},5分钟内有效!"); |
| | | // 短信模板申请说明 |
| | | addSmsTemplateRequest.putQueryParameter("Remark", "测试"); |
| | | CommonResponse addSmsTemplateResponse = client.getCommonResponse(addSmsTemplateRequest); |
| | | String data = addSmsTemplateResponse.getData(); |
| | | // 消除返回文本中的反转义字符 |
| | | String sData = data.replaceAll("'\'", ""); |
| | | log_print("addSmsTemplate", sData); |
| | | Gson gson = new Gson(); |
| | | // 将字符串转换为Map类型,取TemplateCode字段值 |
| | | Map map = gson.fromJson(sData, Map.class); |
| | | Object templateCode = map.get("TemplateCode"); |
| | | return templateCode.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 发送短信 |
| | | */ |
| | | public String sendSms(String phone, String templateCode, String json) throws ClientException { |
| | | CommonRequest request = new CommonRequest(); |
| | | request.setSysDomain("dysmsapi.aliyuncs.com"); |
| | | request.setSysVersion("2017-05-25"); |
| | | request.setSysAction("SendSms"); |
| | | // 接收短信的手机号码 |
| | | request.putQueryParameter("PhoneNumbers", phone); |
| | | // 短信签名名称。请在控制台签名管理页面签名名称一列查看(必须是已添加、并通过审核的短信签名)。 |
| | | request.putQueryParameter("SignName", "玩湃"); |
| | | // 短信模板ID |
| | | request.putQueryParameter("TemplateCode", templateCode); |
| | | // 短信模板变量对应的实际值,JSON格式。 |
| | | request.putQueryParameter("TemplateParam", json); |
| | | CommonResponse commonResponse = client.getCommonResponse(request); |
| | | String data = commonResponse.getData(); |
| | | String sData = data.replaceAll("'\'", ""); |
| | | log_print("sendSms", sData); |
| | | return sData; |
| | | } |
| | | |
| | | /** |
| | | * 查询发送详情 |
| | | */ |
| | | private void querySendDetails(String bizId) throws ClientException { |
| | | CommonRequest request = new CommonRequest(); |
| | | request.setSysDomain("dysmsapi.aliyuncs.com"); |
| | | request.setSysVersion("2017-05-25"); |
| | | request.setSysAction("QuerySendDetails"); |
| | | // 接收短信的手机号码 |
| | | request.putQueryParameter("PhoneNumber", "156xxxxxxxx"); |
| | | // 短信发送日期,支持查询最近30天的记录。格式为yyyyMMdd,例如20191010。 |
| | | request.putQueryParameter("SendDate", "20191010"); |
| | | // 分页记录数量 |
| | | request.putQueryParameter("PageSize", "10"); |
| | | // 分页当前页码 |
| | | request.putQueryParameter("CurrentPage", "1"); |
| | | // 发送回执ID,即发送流水号。 |
| | | request.putQueryParameter("BizId", bizId); |
| | | CommonResponse response = client.getCommonResponse(request); |
| | | log_print("querySendDetails", response.getData()); |
| | | } |
| | | |
| | | public static void main(String[] args) { |
| | | ALiSendSms sendSmsDemo = new ALiSendSms(); |
| | | try { |
| | | // 创建短信模板 |
| | | String templateCode = sendSmsDemo.addSmsTemplate(); |
| | | // 使用刚创建的短信模板发送短信 |
| | | String sData = sendSmsDemo.sendSms("156xxxxxxxx", templateCode, "{\"code\":\"8888\"}"); |
| | | Gson gson = new Gson(); |
| | | Map map = gson.fromJson(sData, Map.class); |
| | | String bizId = map.get("BizId").toString(); |
| | | // 根据短信发送流水号查询短信发送情况 |
| | | sendSmsDemo.querySendDetails(bizId); |
| | | } catch (ClientException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.dsh.account.util.httpClinet.HttpClientUtil; |
| | | import com.dsh.account.util.httpClinet.HttpResult; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 高德地图的地理编码工具类 |
| | | */ |
| | | @Component |
| | | public class GDMapGeocodingUtil { |
| | | |
| | | private String key = "fb131ad2dbfb3f39d7d37d244b92aa2d"; |
| | | |
| | | @Autowired |
| | | private HttpClientUtil httpClientUtil; |
| | | |
| | | |
| | | /** |
| | | * 将行政区域名称转化为坐标 |
| | | * @param province |
| | | * @param city |
| | | * @param county |
| | | * @param address |
| | | * @return |
| | | */ |
| | | public Map<String, Object> geocoding(String province, String city, String county, String address) throws Exception{ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if(ToolUtil.isEmpty(province)){ |
| | | map.put("status", -1); |
| | | map.put("data", "省不能为空"); |
| | | return map; |
| | | } |
| | | if((ToolUtil.isEmpty(city) && ToolUtil.isNotEmpty(county)) || (ToolUtil.isEmpty(city) && ToolUtil.isNotEmpty(address))){ |
| | | map.put("status", -1); |
| | | map.put("data", "市不能为空"); |
| | | return map; |
| | | } |
| | | if((ToolUtil.isEmpty(county) && ToolUtil.isNotEmpty(address))){ |
| | | map.put("status", -1); |
| | | map.put("data", "县/区不能为空"); |
| | | return map; |
| | | } |
| | | |
| | | String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON"; |
| | | url += "&address=" + province + (ToolUtil.isNotEmpty(city) ? city : "") + (ToolUtil.isNotEmpty(county) ? county : "") + (ToolUtil.isNotEmpty(address) ? address : ""); |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | String status = jsonObject.getString("status"); |
| | | List<String> list = new ArrayList<>(); |
| | | |
| | | // gdInterfaceService.saveData("https://restapi.amap.com/v3/geocode/geo", "行政区域转经纬度"); |
| | | |
| | | if(status.equals("1")){ |
| | | JSONArray geocodes = jsonObject.getJSONArray("geocodes"); |
| | | for(int i = 0; i < geocodes.size(); i++){ |
| | | String location = geocodes.getJSONObject(i).getString("location"); |
| | | list.add(location); |
| | | } |
| | | } |
| | | map.put("status", 0); |
| | | map.put("data", list); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | |
| | | public Map<String, Object> geocoding(String address) throws Exception{ |
| | | Map<String, Object> map = new HashMap<>(); |
| | | String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON&address=" + address; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | String status = jsonObject.getString("status"); |
| | | List<String> list = new ArrayList<>(); |
| | | |
| | | // gdInterfaceService.saveData("https://restapi.amap.com/v3/geocode/geo", "行政区域转经纬度"); |
| | | |
| | | if(status.equals("1")){ |
| | | JSONArray geocodes = jsonObject.getJSONArray("geocodes"); |
| | | for(int i = 0; i < geocodes.size(); i++){ |
| | | String location = geocodes.getJSONObject(i).getString("location"); |
| | | list.add(location); |
| | | } |
| | | } |
| | | map.put("status", 0); |
| | | map.put("data", list); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 根据经纬度获取行政区域信息 |
| | | * @param lon |
| | | * @param lan |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public Map<String, String> geocode(String lon, String lan) throws Exception{ |
| | | String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | Map<String, String> map = new HashMap<>(); |
| | | |
| | | // gdInterfaceService.saveData("https://restapi.amap.com/v3/geocode/regeo", "经纬度转行政区域"); |
| | | |
| | | if(jsonObject.getString("status").equals("1")){ |
| | | JSONObject regeocode = jsonObject.getJSONObject("regeocode"); |
| | | JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); |
| | | String address = regeocode.getString("formatted_address"); |
| | | map.put("address", address); |
| | | String code = addressComponent.getString("adcode"); |
| | | String province = addressComponent.getString("province"); |
| | | String city = addressComponent.getString("city"); |
| | | String district = addressComponent.getString("district"); |
| | | map.put("province", province); |
| | | map.put("provinceCode", code.substring(0, 2) + "0000"); |
| | | map.put("city", city); |
| | | map.put("cityCode", code.substring(0, 4) + "00"); |
| | | map.put("district", district); |
| | | map.put("districtCode", code); |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 坐标转换 |
| | | * @param locations 经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位。多个坐标对之间用”|”进行分隔最多支持40对坐标。 |
| | | * @param coordsys 可选值:gps;mapbar;baidu;autonavi(不进行转换) |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public Map<String, String> convert(String locations, String coordsys) throws Exception{ |
| | | String url = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations=" + locations + "&coordsys=" + coordsys + "&output=json&key=" + key; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json"); |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if("1".equals(jsonObject.getString("status"))){ |
| | | map.put("code", jsonObject.getString("infocode"));//"10000" |
| | | map.put("info", jsonObject.getString("info"));//status为0时,info返回错误原;否则返回“OK”。 |
| | | map.put("locations", jsonObject.getString("locations").split(";")[0]);//转换之后的坐标。若有多个坐标,则用 “;”进行区分和间隔 |
| | | }else{ |
| | | map.put("code", jsonObject.getString("infocode")); |
| | | map.put("info", jsonObject.getString("info"));//status为0时,info返回错误原;否则返回“OK”。 |
| | | } |
| | | return map; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util; |
| | | |
| | | import com.dsh.config.JwtProperties; |
| | | import io.jsonwebtoken.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p>jwt token工具类</p> |
| | | * <pre> |
| | | * jwt的claim里一般包含以下几种数据: |
| | | * 1. iss -- token的发行者 token Publish |
| | | * 2. sub -- 该JWT所面向的用户 to user |
| | | * 3. aud -- 接收该JWT的一方 |
| | | * 4. exp -- token的失效时间 token invaild time |
| | | * 5. nbf -- 在此时间段之前,不会被处理 |
| | | * 6. iat -- jwt发布时间 |
| | | * 7. jti -- jwt唯一标识,防止重复使用 |
| | | * </pre> |
| | | * |
| | | * @author fengshuonan |
| | | * @Date 2017/8/25 10:59 |
| | | */ |
| | | @Component |
| | | public class JwtTokenUtil { |
| | | |
| | | @Autowired |
| | | private JwtProperties jwtProperties; |
| | | |
| | | /** |
| | | * 获取用户名从token中 obtain user token |
| | | */ |
| | | public String getUsernameFromToken(String token) { |
| | | return getClaimFromToken(token).getSubject(); |
| | | } |
| | | |
| | | /** |
| | | * 获取jwt发布时间 obtain jwt publish time |
| | | */ |
| | | public Date getIssuedAtDateFromToken(String token) { |
| | | return getClaimFromToken(token).getIssuedAt(); |
| | | } |
| | | |
| | | /** |
| | | * 获取jwt失效时间 obtain jwt invalid time |
| | | */ |
| | | public Date getExpirationDateFromToken(String token) { |
| | | return getClaimFromToken(token).getExpiration(); |
| | | } |
| | | |
| | | /** |
| | | * 获取jwt接收者 obtain jwt obserive |
| | | */ |
| | | public String getAudienceFromToken(String token) { |
| | | return getClaimFromToken(token).getAudience(); |
| | | } |
| | | |
| | | /** |
| | | * 获取私有的jwt claim |
| | | */ |
| | | public String getPrivateClaimFromToken(String token, String key) { |
| | | return getClaimFromToken(token).get(key).toString(); |
| | | } |
| | | |
| | | /** |
| | | * 获取md5 key从token中 obtain md5 key from token |
| | | */ |
| | | public String getMd5KeyFromToken(String token) { |
| | | return getPrivateClaimFromToken(token, jwtProperties.getMd5Key()); |
| | | } |
| | | |
| | | /** |
| | | * 获取jwt的payload部分 obtain paylod partent |
| | | */ |
| | | public Claims getClaimFromToken(String token) { |
| | | return Jwts.parser() |
| | | .setSigningKey(jwtProperties.getSecret()) |
| | | .parseClaimsJws(token) |
| | | .getBody(); |
| | | } |
| | | |
| | | /** |
| | | * 解析token是否正确,不正确会报异常<br> |
| | | */ |
| | | public void parseToken(String token) throws JwtException { |
| | | Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token).getBody(); |
| | | } |
| | | |
| | | /** |
| | | * <pre> |
| | | * 验证token是否失效 |
| | | * true:过期 false:没过期 |
| | | * </pre> |
| | | */ |
| | | public Boolean isTokenExpired(String token) { |
| | | try { |
| | | final Date expiration = getExpirationDateFromToken(token); |
| | | return expiration.before(new Date()); |
| | | } catch (ExpiredJwtException expiredJwtException) { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 生成token(通过用户名和签名时候用的随机数) |
| | | */ |
| | | public String generateToken(String userName, String randomKey) { |
| | | Map<String, Object> claims = new HashMap<>(); |
| | | claims.put(jwtProperties.getMd5Key(), randomKey); |
| | | return doGenerateToken(claims, userName); |
| | | } |
| | | |
| | | /** |
| | | * 生成token |
| | | */ |
| | | private String doGenerateToken(Map<String, Object> claims, String subject) { |
| | | final Date createdDate = new Date(); |
| | | final Date expirationDate = new Date(createdDate.getTime() + jwtProperties.getExpiration() * 1000); |
| | | |
| | | return Jwts.builder() |
| | | .setClaims(claims) |
| | | .setSubject(subject) |
| | | .setIssuedAt(createdDate) |
| | | .setExpiration(expirationDate) |
| | | .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) |
| | | .compact(); |
| | | } |
| | | |
| | | /** |
| | | * 获取混淆MD5签名用的随机字符串 |
| | | */ |
| | | public String getRandomKey() { |
| | | try { |
| | | return UUIDUtil.getRandomCode(6); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return ""; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util; |
| | | |
| | | |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 定义生成随机码的工具类 |
| | | */ |
| | | public class UUIDUtil { |
| | | |
| | | private int i = 1; |
| | | |
| | | |
| | | /** |
| | | * 定义生成原生的UUID随机码 |
| | | * @return |
| | | */ |
| | | public static String getNativeUUID(){ |
| | | return UUID.randomUUID().toString(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 生成32位随机码 |
| | | * @return |
| | | */ |
| | | public static String getRandomCode(){ |
| | | return UUIDUtil.getNativeUUID().replaceAll("-", ""); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取给定长度的随机码 |
| | | * @param num |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String getRandomCode(Integer num) throws Exception{ |
| | | String str = null; |
| | | if(0 < num){ |
| | | if(num % 32 > 0){ |
| | | Integer s = num / 32; |
| | | Integer l = num % 32; |
| | | StringBuffer sb = new StringBuffer(); |
| | | for(int i = 0; i < s; i++){ |
| | | sb.append(UUIDUtil.getRandomCode()); |
| | | } |
| | | sb.append(UUIDUtil.getRandomCode().substring(0, l)); |
| | | str = sb.toString(); |
| | | }else if(num % 32 == 0){ |
| | | Integer s = num / 32; |
| | | StringBuffer sb = new StringBuffer(); |
| | | for(int i = 0; i < s; i++){ |
| | | sb.append(UUIDUtil.getRandomCode()); |
| | | } |
| | | str = sb.toString(); |
| | | }else{ |
| | | str = UUIDUtil.getRandomCode().substring(0, num); |
| | | } |
| | | }else{ |
| | | throw new Exception("参数只能大于0"); |
| | | } |
| | | return str; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取根据当前时间的字符串数据 |
| | | * @return |
| | | */ |
| | | public synchronized static String getTimeStr(){ |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmssS"); |
| | | return simpleDateFormat.format(new Date()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @Description: 获取数字随机码 |
| | | * @Author pzb |
| | | * @Date 2021/8/11 16:52 |
| | | * @Param |
| | | * @Return |
| | | * @Exception |
| | | */ |
| | | public static String getNumberRandom(Integer num){ |
| | | if(null == num){ |
| | | num = 32; |
| | | } |
| | | StringBuffer sb = new StringBuffer(); |
| | | for(int i = 0; i < num; i++){ |
| | | sb.append(Double.valueOf(Math.random() * 10).intValue()); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.httpClinet; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.apache.http.NameValuePair; |
| | | import org.apache.http.client.config.RequestConfig; |
| | | 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.conn.ssl.SSLConnectionSocketFactory; |
| | | 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.impl.conn.PoolingHttpClientConnectionManager; |
| | | import org.apache.http.message.BasicNameValuePair; |
| | | import org.apache.http.ssl.SSLContexts; |
| | | import org.apache.http.util.EntityUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.InputStream; |
| | | import java.nio.charset.Charset; |
| | | import java.security.KeyStore; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * http工具类 |
| | | */ |
| | | @Component |
| | | public class HttpClientUtil { |
| | | |
| | | private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class); |
| | | |
| | | private PoolingHttpClientConnectionManager connectionManager; |
| | | |
| | | |
| | | public HttpClientUtil(){ |
| | | //1.创建连接池管理器 |
| | | connectionManager = new PoolingHttpClientConnectionManager(60000, |
| | | TimeUnit.MILLISECONDS); |
| | | connectionManager.setMaxTotal(1000); |
| | | connectionManager.setDefaultMaxPerRoute(50); |
| | | } |
| | | |
| | | /** |
| | | * 创建一个httpClient对象 |
| | | */ |
| | | private CloseableHttpClient getHttpCline(){ |
| | | return HttpClients.custom() |
| | | .setConnectionManager(connectionManager) |
| | | .disableAutomaticRetries() |
| | | .build(); |
| | | } |
| | | |
| | | private RequestConfig getRequestConfig(){ |
| | | RequestConfig.Builder builder = RequestConfig.custom(); |
| | | builder.setSocketTimeout(60000)//3.1设置客户端等待服务端返回数据的超时时间 |
| | | .setConnectTimeout(30000)//3.2设置客户端发起TCP连接请求的超时时间 |
| | | .setExpectContinueEnabled(true) |
| | | .setConnectionRequestTimeout(30000);//3.3设置客户端从连接池获取链接的超时时间 |
| | | return builder.build(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 创建一个POST请求实例 |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | */ |
| | | private CloseableHttpResponse setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | httpPost.setConfig(this.getRequestConfig()); |
| | | if(null != header){ |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | } |
| | | List<NameValuePair> list = new ArrayList<>(); |
| | | if(null != params){ |
| | | Set<String> keys = params.keySet(); |
| | | for(String key : keys){ |
| | | list.add(new BasicNameValuePair(key, null == params.get(key) ? null : params.get(key).toString())); |
| | | } |
| | | } |
| | | switch (contentType){ |
| | | case "form": |
| | | httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); |
| | | break; |
| | | case "json": |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | String s =objectMapper.writeValueAsString(params); |
| | | httpPost.setEntity(new StringEntity(s, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Charset.forName("UTF-8")))); |
| | | break; |
| | | } |
| | | return getHttpCline().execute(httpPost); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取get请求实例 |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | */ |
| | | private CloseableHttpResponse setGetHttpRequset(String url, Map<String, Object> params, Map<String, String> header) throws Exception{ |
| | | StringBuffer sb = new StringBuffer(); |
| | | String p = ""; |
| | | if(null != params){ |
| | | Set<String> keys = params.keySet(); |
| | | for(String key : keys){ |
| | | sb.append(key + "=" + params.get(key) + "&"); |
| | | } |
| | | p = "?" + sb.substring(0, sb.length() - 1); |
| | | } |
| | | HttpGet httpGet = new HttpGet(url + p); |
| | | httpGet.setConfig(getRequestConfig()); |
| | | if(null != header){ |
| | | for(String key : header.keySet()){ |
| | | httpGet.setHeader(key, header.get(key)); |
| | | } |
| | | } |
| | | return getHttpCline().execute(httpGet); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 发送http请求 |
| | | * @param mothed "GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS" |
| | | * @param url 请求地址 |
| | | * @param params 请求参数 |
| | | * @param header 请求头 |
| | | * @param contentType 参数请求方式form/json |
| | | * @return |
| | | */ |
| | | public HttpResult pushHttpRequset(String mothed, String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{ |
| | | String randome = UUID.randomUUID().toString(); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); |
| | | logger.info(sdf.format(new Date()) + "----(" + randome + ")请求参数:" + JSON.toJSONString(params)); |
| | | CloseableHttpResponse httpResponse = null; |
| | | switch (mothed){ |
| | | case "GET": |
| | | httpResponse = this.setGetHttpRequset(url, params, header); |
| | | break; |
| | | case "POST": |
| | | httpResponse = setPostHttpRequset(url, params, header, contentType); |
| | | break; |
| | | } |
| | | int statusCode = httpResponse.getStatusLine().getStatusCode(); |
| | | String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | logger.info(sdf.format(new Date()) + "----(" + randome + ")返回结果:" + content); |
| | | HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); |
| | | this.close(httpResponse); |
| | | return httpResult; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 发送XML请求 |
| | | * @param url 请求地址 |
| | | * @param xml XML数据 |
| | | * @param header 自定义请求头 |
| | | * @return |
| | | */ |
| | | public HttpResult pushHttpRequsetXml(String url, String xml, Map<String, String> header) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | httpPost.setConfig(getRequestConfig()); |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | httpPost.setHeader("Content-Type", "application/xml"); |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | CloseableHttpResponse httpResponse = getHttpCline().execute(httpPost); |
| | | int statusCode = httpResponse.getStatusLine().getStatusCode(); |
| | | String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | HttpResult httpResult = HttpResult.getHttpResult(statusCode, content); |
| | | this.close(httpResponse); |
| | | return httpResult; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 请求https发送XML请求 |
| | | * @param url 接口路径 |
| | | * @param xml 内容 |
| | | * @param header 请求头 |
| | | * @param certPassword 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public String pushHttpsRequsetXml(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception{ |
| | | HttpPost httpPost = new HttpPost(url); |
| | | for(String key : header.keySet()){ |
| | | httpPost.setHeader(key, header.get(key)); |
| | | } |
| | | httpPost.setHeader("Content-Type", "application/xml"); |
| | | httpPost.setEntity(new StringEntity(xml, "UTF-8")); |
| | | CloseableHttpClient httpCline = this.initCert(certPassword, certPath, certType); |
| | | CloseableHttpResponse httpResponse = httpCline.execute(httpPost); |
| | | String content = null; |
| | | if(httpResponse.getStatusLine().getStatusCode() == 200){ |
| | | content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); |
| | | }else{ |
| | | content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity()); |
| | | } |
| | | this.close(httpResponse); |
| | | httpCline.close(); |
| | | return content; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 初始化https对象(带证书) |
| | | * @param key 证书密码 |
| | | * @param certPath 证书路径 |
| | | * @param certType 证书类型 |
| | | * @throws Exception |
| | | */ |
| | | private CloseableHttpClient initCert(String key, String certPath, String certType) throws Exception { |
| | | KeyStore keyStore = KeyStore.getInstance(certType); |
| | | InputStream inputStream = new FileInputStream(new File(certPath)); |
| | | try { |
| | | keyStore.load(inputStream, key.toCharArray()); |
| | | } finally { |
| | | inputStream.close(); |
| | | } |
| | | SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build(); |
| | | SSLConnectionSocketFactory sslsf = |
| | | new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null, |
| | | SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); |
| | | return HttpClients.custom().setSSLSocketFactory(sslsf).build(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 关闭资源 |
| | | */ |
| | | private void close(CloseableHttpResponse httpResponse){ |
| | | try { |
| | | if(null != httpResponse){ |
| | | EntityUtils.consume(httpResponse.getEntity());//此处高能,通过源码分析,由EntityUtils是否回收HttpEntity |
| | | httpResponse.close(); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | }finally { |
| | | try { |
| | | if(null != httpResponse){ |
| | | httpResponse.close(); |
| | | } |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.httpClinet; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * http请求返回封装 |
| | | */ |
| | | @Data |
| | | public class HttpResult { |
| | | /** |
| | | * 返回状态码 |
| | | */ |
| | | private Integer code; |
| | | /** |
| | | * 返回结果 |
| | | */ |
| | | private String data; |
| | | |
| | | /** |
| | | * 返回封装结果 |
| | | * @param code |
| | | * @param data |
| | | * @return |
| | | */ |
| | | public static HttpResult getHttpResult(Integer code, String data){ |
| | | HttpResult httpResult = new HttpResult(); |
| | | httpResult.setCode(code); |
| | | httpResult.setData(data); |
| | | return httpResult; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.weChat; |
| | | |
| | | import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| | | |
| | | import javax.crypto.BadPaddingException; |
| | | import javax.crypto.Cipher; |
| | | import javax.crypto.IllegalBlockSizeException; |
| | | import javax.crypto.NoSuchPaddingException; |
| | | import javax.crypto.spec.IvParameterSpec; |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | import java.security.*; |
| | | |
| | | /** |
| | | * AES加密 |
| | | * @author pzb |
| | | * @Date 2021/12/3 15:43 |
| | | */ |
| | | public class AES { |
| | | |
| | | public static boolean initialized = false; |
| | | |
| | | /** |
| | | * AES解密 |
| | | * |
| | | * @param content |
| | | * 密文 |
| | | * @return |
| | | * @throws InvalidAlgorithmParameterException |
| | | * @throws NoSuchProviderException |
| | | */ |
| | | public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException { |
| | | initialize(); |
| | | try { |
| | | Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); |
| | | Key sKeySpec = new SecretKeySpec(keyByte, "AES"); |
| | | cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化 |
| | | byte[] result = cipher.doFinal(content); |
| | | return result; |
| | | } catch (NoSuchAlgorithmException e) { |
| | | e.printStackTrace(); |
| | | } catch (NoSuchPaddingException e) { |
| | | e.printStackTrace(); |
| | | } catch (InvalidKeyException e) { |
| | | e.printStackTrace(); |
| | | } catch (IllegalBlockSizeException e) { |
| | | e.printStackTrace(); |
| | | } catch (BadPaddingException e) { |
| | | e.printStackTrace(); |
| | | } catch (NoSuchProviderException e) { |
| | | // TODO Auto-generated catch block |
| | | e.printStackTrace(); |
| | | } catch (Exception e) { |
| | | // TODO Auto-generated catch block |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static void initialize() { |
| | | if (initialized) |
| | | return; |
| | | Security.addProvider(new BouncyCastleProvider()); |
| | | initialized = true; |
| | | } |
| | | |
| | | // 生成iv |
| | | public static AlgorithmParameters generateIV(byte[] iv) throws Exception { |
| | | AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); |
| | | params.init(new IvParameterSpec(iv)); |
| | | return params; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.weChat; |
| | | |
| | | import org.apache.commons.codec.binary.Base64; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | |
| | | public class WXCore { |
| | | |
| | | private static final String WATERMARK = "watermark"; |
| | | |
| | | @Value("${wx.appletsAppid}") |
| | | private static String appid ; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 解密数据 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String decrypt(String encryptedData, String sessionKey, String iv){ |
| | | String result = ""; |
| | | try { |
| | | AES aes = new AES(); |
| | | byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv)); |
| | | if(null != resultByte && resultByte.length > 0){ |
| | | result = new String(WxPKCS7Encoder.decode(resultByte), "UTF-8"); |
| | | // JSONObject jsonObject = JSON.parseObject(result); |
| | | // String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString("appid"); |
| | | // if(!appid.equals(decryptAppid)){ |
| | | // result = ""; |
| | | // } |
| | | } |
| | | } catch (Exception e) { |
| | | result = ""; |
| | | e.printStackTrace(); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | public static void main(String[] args) throws Exception{ |
| | | String appId = "wx4f4bc4dec97d474b"; |
| | | String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew=="; |
| | | String sessionKey = "tiihtNczf5v6AKRyjwEUhQ=="; |
| | | String iv = "r7BXXKkLb8qrSNn05n0qiA=="; |
| | | System.out.println(decrypt(encryptedData, sessionKey, iv)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.weChat; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.dsh.account.util.ToolUtil; |
| | | import com.dsh.account.util.UUIDUtil; |
| | | import com.dsh.account.util.httpClinet.HttpClientUtil; |
| | | import com.dsh.account.util.httpClinet.HttpResult; |
| | | import org.apache.commons.codec.digest.DigestUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.http.*; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.InputStream; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.net.URLDecoder; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 微信工具类 |
| | | */ |
| | | @Component |
| | | public class WeChatUtil { |
| | | |
| | | @Value("${wx.appletsAppid}") |
| | | private String wxAppletsAppid; |
| | | |
| | | @Value("${wx.appletsAppSecret}") |
| | | private String wxAppletsAppSecret; |
| | | |
| | | // @Value("${wx.officialAccountAppid}") |
| | | private String officialAccountAppid; |
| | | |
| | | @Value("{wx.officialAccountAppSecret}") |
| | | private String officialAccountAppSecret; |
| | | |
| | | @Value("${wx.appid}") |
| | | private String webAppId; |
| | | |
| | | @Value("${wx.appSecret}") |
| | | private String webAppSecret; |
| | | |
| | | @Autowired |
| | | private HttpClientUtil httpClientUtil; |
| | | |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | | |
| | | |
| | | /** |
| | | * 小程序使用jscode获取openid |
| | | * @param jscode |
| | | * @return |
| | | */ |
| | | public Map<String, Object> code2Session(String jscode) throws Exception{ |
| | | String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret |
| | | + "&js_code=" + jscode + "&grant_type=authorization_code"; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(null == httpResult || httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | int errcode = jsonObject.getIntValue("errcode"); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("errcode", errcode); |
| | | if(errcode == 0){//成功 |
| | | map.put("openid", jsonObject.getString("openid")); |
| | | map.put("sessionKey", jsonObject.getString("session_key")); |
| | | map.put("unionid", jsonObject.getString("unionid")); |
| | | return map; |
| | | } |
| | | if(errcode == -1){//系统繁忙,此时请开发者稍候再试 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 40029){//code 无效 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 45011){//频率限制,每个用户每分钟100次 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取微信小程序token |
| | | * @return |
| | | */ |
| | | public String getWxAppletsAccessToken() throws Exception{ |
| | | String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return ""; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | return jsonObject.getString("access_token"); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 网站应用登录 |
| | | * @param code |
| | | * @return |
| | | */ |
| | | public Map<String, String> webAccessToken(String code) throws Exception{ |
| | | String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + webAppId + "&secret=" + webAppSecret + "&code=" + code + "&grant_type=authorization_code"; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | int errcode = jsonObject.getIntValue("errcode"); |
| | | Map<String, String> map = new HashMap<>(); |
| | | if(errcode == 0){//成功 |
| | | map.put("access_token", jsonObject.getString("access_token")); |
| | | map.put("openid", jsonObject.getString("openid")); |
| | | map.put("refresh_token", jsonObject.getString("refresh_token")); |
| | | map.put("unionid", jsonObject.getString("unionid")); |
| | | return map; |
| | | } |
| | | if(errcode == -1){//系统繁忙,此时请开发者稍候再试 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 40029){//code 无效 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 45011){//频率限制,每个用户每分钟100次 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取微信个人信息 |
| | | * @param access_token |
| | | * @param openid |
| | | * @return |
| | | */ |
| | | public Map<String, Object> getUserInfo(String access_token, String openid) throws Exception{ |
| | | String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject jsonObject = JSON.parseObject(httpResult.getData()); |
| | | int errcode = jsonObject.getIntValue("errcode"); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | if(errcode == 0){//成功 |
| | | map.put("nickname", jsonObject.getString("nickname")); |
| | | map.put("openid", jsonObject.getString("openid")); |
| | | map.put("sex", jsonObject.getString("sex")); |
| | | map.put("headimgurl", jsonObject.getString("headimgurl")); |
| | | return map; |
| | | } |
| | | if(errcode == -1){//系统繁忙,此时请开发者稍候再试 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 40029){//code 无效 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | if(errcode == 45011){//频率限制,每个用户每分钟100次 |
| | | map.put("msg", jsonObject.getString("errmsg")); |
| | | return map; |
| | | } |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 公众号获取openid |
| | | * @param code |
| | | * @return |
| | | */ |
| | | public Map<String,Object> getOpenId(String code) throws Exception{ |
| | | if (code == null || code.length() == 0) { |
| | | return null; |
| | | } |
| | | String grantType = "authorization_code"; |
| | | String params = "appid=" + officialAccountAppid + "&secret=" + officialAccountAppSecret + "&code=" + code + "&grant_type=" + grantType; |
| | | System.out.println("sssss"+params); |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", "https://api.weixin.qq.com/sns/oauth2/access_token?" + params, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | JSONObject json = JSON.parseObject(httpResult.getData()); |
| | | System.out.println(json); |
| | | String openId = json.get("openid").toString(); |
| | | String accessToken = json.get("access_token").toString(); |
| | | Integer expiresIn = json.getInteger("expires_in"); |
| | | String refresh_token = json.getString("refresh_token"); |
| | | String unionid = json.getString("unionid"); |
| | | Map<String,Object> map=new HashMap<>(); |
| | | map.put("openId",openId); |
| | | map.put("accessToken",accessToken); |
| | | map.put("expiresIn", expiresIn); |
| | | map.put("refreshToken", refresh_token); |
| | | map.put("unionid", unionid); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /*** |
| | | * 获取acess_token (公众号) |
| | | * 来源www.vxzsk.com |
| | | * @return |
| | | */ |
| | | public String getAccessToken() throws Exception{ |
| | | String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + officialAccountAppid |
| | | + "&secret=" + officialAccountAppSecret; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | String accessToken = JSONObject.parseObject(httpResult.getData()).getString("access_token"); |
| | | return accessToken; |
| | | } |
| | | |
| | | /*** |
| | | * 获取jsapiTicket(公众号) |
| | | * 来源 www.vxzsk.com |
| | | * @return |
| | | */ |
| | | public String getJSApiTicket() throws Exception{ |
| | | //获取token |
| | | String acess_token= this.getAccessToken(); |
| | | String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acess_token + "&type=jsapi"; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", urlStr, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | System.out.println(httpResult.getData()); |
| | | String ticket = JSONObject.parseObject(httpResult.getData()).getString("ticket"); |
| | | return ticket; |
| | | } |
| | | |
| | | /** |
| | | * 通过config接口注入权限验证配置(公众号) |
| | | * 附录1-JS-SDK使用权限签名算法, |
| | | * @return |
| | | */ |
| | | public Map<String,Object> getSignatureConfig(String url) throws Exception{ |
| | | //获取token |
| | | try { |
| | | url = URLDecoder.decode(url, "UTF-8"); |
| | | } catch (UnsupportedEncodingException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | String ticket = getJSApiTicket(); |
| | | String noncestr = UUIDUtil.getRandomCode(); |
| | | Long timestamp = System.currentTimeMillis(); |
| | | String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; |
| | | String signature = DigestUtils.sha1Hex(content); |
| | | Map<String,Object> map=new HashMap<>(); |
| | | map.put("appId", officialAccountAppid); |
| | | map.put("timestamp", timestamp); |
| | | map.put("nonceStr", noncestr); |
| | | map.put("signature", signature); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 公众号获取用户个人信息 |
| | | * @param access_token |
| | | * @param openid |
| | | * @return |
| | | */ |
| | | public Map<String, Object> queryUserInfo(String access_token, String openid) throws Exception{ |
| | | String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN"; |
| | | HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form"); |
| | | if(httpResult.getCode() != 200){ |
| | | return null; |
| | | } |
| | | System.err.println(httpResult.getData()); |
| | | JSONObject j = JSON.parseObject(httpResult.getData()); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("nickname", j.getString("nickname")); |
| | | map.put("sex", j.getInteger("sex")); |
| | | map.put("headimgurl", j.getString("headimgurl")); |
| | | map.put("unionid", j.getString("unionid")); |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取小程序二维码 |
| | | * @param page 跳转页 例如 pages/index/index |
| | | * @param scene 参数 a=1&b=2 |
| | | */ |
| | | public InputStream getwxacodeunlimit(String page, String scene){ |
| | | try { |
| | | String token = getWxAppletsAccessToken(); |
| | | if(ToolUtil.isEmpty(token)){ |
| | | System.err.println("获取接口调用凭证失败"); |
| | | } |
| | | String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token; |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("scene", scene); |
| | | param.put("page", page); |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | MediaType type= MediaType.parseMediaType("application/json;charset=UTF-8"); |
| | | httpHeaders.setContentType(type); |
| | | HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class, new Object[0]); |
| | | String body1 = exchange.getBody(); |
| | | // System.err.println(body1); |
| | | ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]); |
| | | byte[] body = entity.getBody(); |
| | | // System.err.println(Base64.encodeBase64String(body)); |
| | | return new ByteArrayInputStream(body); |
| | | }catch (Exception e){ |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.account.util.weChat; |
| | | |
| | | import java.nio.charset.Charset; |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 微信小程序加解密 |
| | | * @author pzb |
| | | * @Date 2021/12/3 15:43 |
| | | */ |
| | | public class WxPKCS7Encoder { |
| | | private static final Charset CHARSET = Charset.forName("utf-8"); |
| | | private static final int BLOCK_SIZE = 32; |
| | | |
| | | /** |
| | | * 获得对明文进行补位填充的字节. |
| | | * |
| | | * @param count |
| | | * 需要进行填充补位操作的明文字节个数 |
| | | * @return 补齐用的字节数组 |
| | | */ |
| | | public static byte[] encode(int count) { |
| | | // 计算需要填充的位数 |
| | | int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); |
| | | if (amountToPad == 0) { |
| | | amountToPad = BLOCK_SIZE; |
| | | } |
| | | // 获得补位所用的字符 |
| | | char padChr = chr(amountToPad); |
| | | String tmp = new String(); |
| | | for (int index = 0; index < amountToPad; index++) { |
| | | tmp += padChr; |
| | | } |
| | | return tmp.getBytes(CHARSET); |
| | | } |
| | | |
| | | /** |
| | | * 删除解密后明文的补位字符 |
| | | * |
| | | * @param decrypted |
| | | * 解密后的明文 |
| | | * @return 删除补位字符后的明文 |
| | | */ |
| | | public static byte[] decode(byte[] decrypted) { |
| | | int pad = decrypted[decrypted.length - 1]; |
| | | if (pad < 1 || pad > 32) { |
| | | pad = 0; |
| | | } |
| | | return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); |
| | | } |
| | | |
| | | /** |
| | | * 将数字转化成ASCII码对应的字符,用于对明文进行补码 |
| | | * |
| | | * @param a |
| | | * 需要转化的数字 |
| | | * @return 转化得到的字符 |
| | | */ |
| | | public static char chr(int a) { |
| | | byte target = (byte) (a & 0xFF); |
| | | return (char) target; |
| | | } |
| | | } |
New file |
| | |
| | | package com.dsh.config; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * jwt相关配置 |
| | | * |
| | | * @author fengshuonan |
| | | * @date 2017-08-23 9:23 |
| | | */ |
| | | @Configuration |
| | | @ConfigurationProperties(prefix = JwtProperties.JWT_PREFIX) |
| | | public class JwtProperties { |
| | | |
| | | public static final String JWT_PREFIX = "jwt"; |
| | | |
| | | private String header = "Authorization"; |
| | | |
| | | private String secret = "defaultSecret"; |
| | | |
| | | private Long expiration = 604800L; |
| | | |
| | | private String authPath = "auth"; |
| | | |
| | | private String md5Key = "randomKey"; |
| | | |
| | | public static String getJwtPrefix() { |
| | | return JWT_PREFIX; |
| | | } |
| | | |
| | | public String getHeader() { |
| | | return header; |
| | | } |
| | | |
| | | public void setHeader(String header) { |
| | | this.header = header; |
| | | } |
| | | |
| | | public String getSecret() { |
| | | return secret; |
| | | } |
| | | |
| | | public void setSecret(String secret) { |
| | | this.secret = secret; |
| | | } |
| | | |
| | | public Long getExpiration() { |
| | | return expiration; |
| | | } |
| | | |
| | | public void setExpiration(Long expiration) { |
| | | this.expiration = expiration; |
| | | } |
| | | |
| | | public String getAuthPath() { |
| | | return authPath; |
| | | } |
| | | |
| | | public void setAuthPath(String authPath) { |
| | | this.authPath = authPath; |
| | | } |
| | | |
| | | public String getMd5Key() { |
| | | return md5Key; |
| | | } |
| | | |
| | | public void setMd5Key(String md5Key) { |
| | | this.md5Key = md5Key; |
| | | } |
| | | } |
| | |
| | | @Autowired |
| | | AuthService authService; |
| | | |
| | | @Value("${cn.mbcloud.gateway.permissions.basic}") |
| | | private Boolean isBasic = Boolean.FALSE; |
| | | |
| | | |
| | | private AntPathMatcher pathMatcher = new AntPathMatcher(); |
| | | |
| | | /** |
| | | * Redis Token 仓库前缀 |
| | | */ |
| | | private String REDIS_TOKEN_STORE_PREFIX = "oauth2_"; |
| | | |
| | | /** |
| | | * 账户 |