10 changed files with 318 additions and 18 deletions
@ -0,0 +1,23 @@ |
|||
package com.ccsens.util; |
|||
|
|||
import org.junit.Test; |
|||
|
|||
import java.io.IOException; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2022/3/9 11:36 |
|||
*/ |
|||
public class JacksonUtilTest { |
|||
|
|||
@Test |
|||
public void test01() throws IOException { |
|||
|
|||
String xml = "<xml><ToUserName><![CDATA[gh_4bbe9a56a99d]]></ToUserName><FromUserName><![CDATA[oVyk85japz_obxoz9SoEAeLSm2fs]]></FromUserName><CreateTime>1646796877</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[subscribe]]></Event><EventKey><![CDATA[qrscene_0]]></EventKey><Ticket><![CDATA[gQHq7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUnJXRzR3bkZjWUMxN3RnTjF5MVMAAgRdFihiAwSAOgkA]]></Ticket></xml>"; |
|||
|
|||
|
|||
System.out.println(JacksonUtil.xmlToJson(xml)); |
|||
System.out.println(JacksonUtil.xmlToBean(xml, NoticeDto.Notice.class)); |
|||
} |
|||
} |
@ -0,0 +1,86 @@ |
|||
package com.ccsens.util; |
|||
|
|||
import cn.hutool.core.util.ArrayUtil; |
|||
import com.ccsens.util.enterprisewx.SHA1; |
|||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; |
|||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; |
|||
import lombok.Data; |
|||
|
|||
import javax.validation.constraints.NotEmpty; |
|||
import java.security.NoSuchAlgorithmException; |
|||
import java.util.Arrays; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2021/10/21 15:51 |
|||
*/ |
|||
public class NoticeDto { |
|||
|
|||
/** |
|||
* 微信小程序通知校验 |
|||
*/ |
|||
@Data |
|||
public static class ValidMsg{ |
|||
@NotEmpty |
|||
private String signature; |
|||
@NotEmpty |
|||
private String timestamp; |
|||
@NotEmpty |
|||
private String nonce; |
|||
@NotEmpty |
|||
private String echostr; |
|||
|
|||
|
|||
public boolean check(String token) throws NoSuchAlgorithmException { |
|||
String[] dict = {token, timestamp, nonce}; |
|||
Arrays.sort(dict); |
|||
String str = ArrayUtil.join(dict, ""); |
|||
String shaStr = SHA1.getSha1(str); |
|||
return signature.equals(shaStr); |
|||
} |
|||
} |
|||
|
|||
@Data |
|||
@JacksonXmlRootElement(localName = "xml") |
|||
public static class Notice { |
|||
/** |
|||
* 小程序的原始ID |
|||
*/ |
|||
@JacksonXmlProperty(localName = "ToUserName") |
|||
private String ToUserName; |
|||
/** |
|||
* 发送者的openid |
|||
*/ |
|||
@JacksonXmlProperty(localName = "FromUserName") |
|||
private String FromUserName; |
|||
@JacksonXmlProperty(localName = "CreateTime") |
|||
private String CreateTime; |
|||
/** |
|||
* text: 文本 Content |
|||
* image:PicUrl MediaId |
|||
* miniprogrampage: 小程序卡片 Title AppId PagePath ThumbUrl ThumbMediaId |
|||
*/ |
|||
private String MsgType; |
|||
private String Event; |
|||
private String SessionFrom; |
|||
private String Content; |
|||
private String MsgId; |
|||
private String PicUrl; |
|||
|
|||
/**事件KEY值,qrscene_为前缀,后面为二维码的参数值*/ |
|||
private String EventKey; |
|||
/**二维码的ticket,可用来换取二维码图片*/ |
|||
private String Ticket; |
|||
|
|||
/** |
|||
* 图片消息媒体id,可以调用[获取临时素材]((getTempMedia)接口拉取数据。 |
|||
*/ |
|||
private String MediaId; |
|||
private String Title; |
|||
private String AppId; |
|||
private String PagePath; |
|||
private String ThumbUrl; |
|||
private String ThumbMediaId; |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
package com.ccsens.wechatutil.bean.dto.wxofficial; |
|||
|
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2022/3/7 9:09 |
|||
*/ |
|||
public class WxQrCodeDto { |
|||
|
|||
@Data |
|||
@ApiModel("生成带参数的二维码-公众号") |
|||
public static class Create{ |
|||
|
|||
@ApiModelProperty("该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为60秒。") |
|||
private Long expire_seconds; |
|||
@ApiModelProperty("二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值") |
|||
private String action_name; |
|||
@ApiModelProperty |
|||
private ActionInfo action_info; |
|||
public Create(){} |
|||
|
|||
public Create(Long expire_seconds, String action_name, Integer scene_id, String scene_str) { |
|||
this.expire_seconds = expire_seconds; |
|||
this.action_name = action_name; |
|||
this.action_info = new ActionInfo(); |
|||
Scene scene = new Scene(); |
|||
scene.setScene_id(scene_id); |
|||
scene.setScene_str(scene_str); |
|||
this.action_info.setScene(scene); |
|||
} |
|||
} |
|||
|
|||
|
|||
@Data |
|||
@ApiModel("生成带参数的二维码场景值1-公众号") |
|||
public static class ActionInfo { |
|||
private Scene scene; |
|||
} |
|||
|
|||
@Data |
|||
@ApiModel("生成带参数的二维码场景值2-公众号") |
|||
public static class Scene { |
|||
@ApiModelProperty("场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)") |
|||
private Integer scene_id; |
|||
@ApiModelProperty("场景值ID(字符串形式的ID),字符串类型,长度限制为1到64") |
|||
private String scene_str; |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,25 @@ |
|||
package com.ccsens.wechatutil.bean.vo.wxofficial; |
|||
|
|||
import io.swagger.annotations.ApiModel; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2022/3/7 9:52 |
|||
*/ |
|||
public class WxQrCodeVo { |
|||
|
|||
@Data |
|||
@ApiModel("生成带参数的二维码-公众号返回") |
|||
public static class QrCodeUrl{ |
|||
@ApiModelProperty("获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码") |
|||
private String ticket; |
|||
@ApiModelProperty("该二维码有效时间,以秒为单位。 最大不超过2592000(即30天)") |
|||
private Long expire_seconds; |
|||
@ApiModelProperty("二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片") |
|||
private String url; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,26 @@ |
|||
package com.ccsens.wechatutil.util; |
|||
|
|||
import com.ccsens.wechatutil.wxofficial.OfficialAccountSigninUtil; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2022/3/4 17:22 |
|||
*/ |
|||
@Component |
|||
public class WeiXinPropUtil { |
|||
public static String appIdOfficial; |
|||
public static String secretOfficial; |
|||
|
|||
@Value("${official.appId:}") |
|||
public void setAppIdOfficial(String appIdOfficial) { |
|||
WeiXinPropUtil.appIdOfficial = appIdOfficial; |
|||
} |
|||
@Value("${official.secret:}") |
|||
public void setApplication(String secretOfficial) { |
|||
WeiXinPropUtil.secretOfficial = secretOfficial; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,62 @@ |
|||
package com.ccsens.wechatutil.wxofficial; |
|||
|
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.ccsens.util.RestTemplateUtil; |
|||
import com.ccsens.wechatutil.bean.dto.wxofficial.WxQrCodeDto; |
|||
import com.ccsens.wechatutil.bean.vo.wxofficial.WxQrCodeVo; |
|||
import com.ccsens.wechatutil.util.WeiXinPropUtil; |
|||
import com.ccsens.wechatutil.util.WxConstant; |
|||
import com.ccsens.wechatutil.wxcommon.WxCommonUtil; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
/** |
|||
* @description: |
|||
* @author: whj |
|||
* @time: 2022/3/4 17:14 |
|||
*/ |
|||
@Slf4j |
|||
public class OfficialQrCodeUtil { |
|||
/**临时的整型参数值*/ |
|||
public static final String QR_SCENE = "QR_SCENE"; |
|||
/**临时的字符串参数值*/ |
|||
public static final String QR_STR_SCENE = "QR_STR_SCENE"; |
|||
/**永久的整型参数值*/ |
|||
public static final String QR_LIMIT_SCENE = "QR_LIMIT_SCENE"; |
|||
/**永久的字符串参数值*/ |
|||
public static final String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE"; |
|||
|
|||
|
|||
/** |
|||
* 生成带参数的二维码 |
|||
* @param expire_seconds 有效时间 |
|||
* @param action_name 应用名 |
|||
* @param scene_id 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000 |
|||
* @param scene_str 场景值ID(字符串形式的ID),字符串类型,长度限制为1到64 |
|||
* @return 二维码路径 |
|||
*/ |
|||
public static WxQrCodeVo.QrCodeUrl send (Long expire_seconds, String action_name, Integer scene_id, String scene_str){ |
|||
WxQrCodeDto.Create create = new WxQrCodeDto.Create(expire_seconds, action_name, scene_id, scene_str); |
|||
String url = String.format(WxConstant.QR_CODE_CREATE, WxCommonUtil.getAccessToken(WeiXinPropUtil.appIdOfficial, WeiXinPropUtil.secretOfficial)); |
|||
String response = RestTemplateUtil.postBody(url, create); |
|||
log.info("url: {}\nresponse: {}", url, response); |
|||
WxConstant.pageResult(response); |
|||
return JSONObject.parseObject(response, WxQrCodeVo.QrCodeUrl.class); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 生成带参数的二维码 |
|||
* @param create 二维码参数 |
|||
* @param appIdOfficia appId |
|||
* @param secretOfficial secret |
|||
* @return 二维码路径 |
|||
*/ |
|||
public static WxQrCodeVo.QrCodeUrl send (WxQrCodeDto.Create create, String appIdOfficia, String secretOfficial){ |
|||
String url = StrUtil.format(WxConstant.QR_CODE_CREATE, WxCommonUtil.getAccessToken(appIdOfficia,secretOfficial)); |
|||
String response = RestTemplateUtil.postBody(url, create); |
|||
log.info("url: {}\nresponse: {}", url, response); |
|||
WxConstant.pageResult(response); |
|||
return JSONObject.parseObject(response, WxQrCodeVo.QrCodeUrl.class); |
|||
} |
|||
} |
Loading…
Reference in new issue