java获取微信小程序码(太阳码)使用base64编码后返回附带处理异常情况

获取不限制的小程序码

接口地址:接口应在服务器端调用,详细说明参见服务端API

调用方式

HTTPS 调用


POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN 

请求参数

属性类型必填说明
access_tokenstring接口调用凭证,该参数为 URL 参数,非 Body 参数。使用getAccessToken 或者 authorizer_access_token
scenestring最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
pagestring默认是主页,页面 page,例如 pages/index/index,根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面。scancode_time为系统保留参数,不允许配置
check_pathbool默认是true,检查page 是否存在,为 true 时 page 必须是已经发布的小程序存在的页面(否则报错);为 false 时允许小程序未发布或者 page 不存在, 但page 有数量上限(60000个)请勿滥用。
env_versionstring要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。
widthnumber默认430,二维码的宽度,单位 px,最小 280px,最大 1280px
auto_colorbool自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
line_colorobject默认是{"r":0,"g":0,"b":0} 。auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
is_hyalinebool默认是false,是否需要透明底色,为 true 时,生成透明底色的小程序

返回参数

属性类型说明
bufferbuffer图片 Buffer
errcodenumber错误码
errmsgstring错误信息

请求数据示例


{
 "page": "pages/index/index",
 "scene": "a=1",
 "check_path": true,
 "env_version": "release"
} 

成功返回数据示例


图片 Buffer 

失败数据示例


{
 "errcode":  40097,
 "errmsg": "invalid args"
} 

 

错误码

错误码错误描述解决方案
-1system error系统繁忙,此时请开发者稍候再试
40001invalid credential  access_token isinvalid or not latest获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口
40129invalid scene最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
41030invalid pagepage路径不正确:根路径前不要填加 /,不能携带参数(参数请放在scene字段里),需要保证在现网版本小程序中存在,与app.json保持一致。
设置check_path=false可不检查page参数。
85096not allow include scancode_time fieldscancode_time为系统保留参数,不允许配置
40097invalid args参数错误
40169invalid length for scene  or thedata is not json stringscene 不合法

 *****具体代码****

token的获取与自动刷新

@Value("${wx.service.configs.appid}")
private String appId;

@Value("${wx.service.configs.secret}")
private String secret;

@Value("${wechat.interface_sendURL}")
private String sendURL;

public TokenAndExpires getTokenAndExpires() {
    TokenAndExpires tokenAndExpires = new TokenAndExpires();
    Map<String, String> accToken = redisCache.getCacheMap(WxConstants.MESSAGETOKEN_SESSION);
    String acc_token = accToken.get(WxConstants.ACC_TOKEN);
    String expiresTime = accToken.get(WxConstants.EXPIRESTIME);
    Long nowTime = System.currentTimeMillis();
    if (acc_token != null && accToken.size() > 0) {
        Long time = Long.valueOf(expiresTime);
        if (time < nowTime) {
            String refreshToken = this.refreshToken();
            tokenAndExpires.setAccessToken(refreshToken);
            tokenAndExpires.setExpires(7200L);
            return tokenAndExpires;
        }
        tokenAndExpires.setAccessToken(acc_token);
        tokenAndExpires.setExpires(7200L);
        return tokenAndExpires;
    } else {
        String refreshToken = this.refreshToken();
        tokenAndExpires.setAccessToken(refreshToken);
        tokenAndExpires.setExpires(7200L);
        return tokenAndExpires;
    }

}

/**
 * 刷新token
 */
public String refreshToken() {
    TokenAndExpires tokenAndExpires = new TokenAndExpires();
    String tokenUrl = sendURL + "/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
    String s = HttpUtils.sendGet(tokenUrl);
    JSONObject object = JSONObject.parseObject(s.trim());
    String accessToken = object.getString("access_token");
    Long expires_in = object.getLong("expires_in");
    if (accessToken == null) {
        System.out.println("无法获取token,请添加白名单IP");
        throw new XftException(XftError.ERROR_NO_TOKEN);
    }
    Long expirationTime = expires_in * 1000 + System.currentTimeMillis();
    tokenAndExpires.setAccessToken(accessToken);
    tokenAndExpires.setExpires(expires_in);
    Map<String, String> map = new HashMap<>();
    map.put(WxConstants.ACC_TOKEN, accessToken);
    map.put(WxConstants.EXPIRESTIME, expirationTime.toString());
    redisCache.setCacheMap(WxConstants.MESSAGETOKEN_SESSION, map);
    redisCache.expire(WxConstants.MESSAGETOKEN_SESSION, 1, TimeUnit.DAYS);
    return accessToken;
}

请求参数VO

@Data
public class WxQrCodeVO {

    private String token;
    /**
     * string  是
     * 最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,
     * 其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
     */
    private String scene;

    /**
     * string  否
     * 默认是主页,页面 page,例如 pages/index/index,
     * 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面。scancode_time为系统保留参数,不允许配置
     */
    private String page;

    /**
     * bool    否
     * 默认是true,检查page 是否存在,为 true 时 page 必须是已经发布的小程序存在的页面(否则报错);
     * 为 false 时允许小程序未发布或者 page 不存在, 但page 有数量上限(60000个)请勿滥用。
     */
    private  Boolean checkPath;

    /**
     * string  否
     * 要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。
     */
    private String envVersion;

    /**
     * number  否
     * 默认430,二维码的宽度,单位 px,最小 280px,最大 1280px
     */
    private Integer width;

    /**
     * bool    否
     * 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false
     */
    private Boolean autoColor;

    /**
     * object  否
     * 默认是{"r":0,"g":0,"b":0} 。auto_color 为 false 时生效,
     * 使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示
     */
    private LineColor lineColor;

    /**
     * bool    否
     * 默认是false,是否需要透明底色,为 true 时,生成透明底色的小程序
     */
    private Boolean isHyaline;

}
@Data
public class LineColor {

    private Integer r;

    private Integer g;

    private Integer b;
}

获取二维码方法--通过响应类型判断是否生成成功

public String createWxQR(WxQrCodeVO vo) throws Exception {
    String token = vo.getToken();
    if (token == null){
        TokenAndExpires tokenAndExpires = accessTokenService.getTokenAndExpires();
        token = tokenAndExpires.getAccessToken();
    }
    String sendUrl = createWxQrUrl.replace("TOKEN", token);
    Map<String, Object> map = new HashMap<>();
    map.put("scene", vo.getScene());
    map.put("page", vo.getPage());
    map.put("env_version", vo.getEnvVersion());
    map.put("width", vo.getWidth());
    map.put("auto_color", vo.getAutoColor());
    map.put("line_color", vo.getLineColor());
    map.put("is_hyaline", vo.getIsHyaline());
    String mapJson = JSON.toJSONString(map);
    URL url = new URL(sendUrl);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);
    // 发送请求体
    conn.getOutputStream().write(mapJson.getBytes("UTF-8"));
    conn.connect();
    // 读取返回的图片数据
    String contentType = conn.getContentType();
    if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
        InputStream inputStream = conn.getInputStream();
        if (contentType.startsWith("image")) {
            // 正常情况
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
            byte[] bytes = byteArrayOutputStream.toByteArray();
            String encode = Base64.getEncoder().encodeToString(bytes);
            inputStream.close();
            byteArrayOutputStream.close();
            return encode;
        } else {
            String responseBody = readInputStream(inputStream);
            JSONObject jsonObject = JSON.parseObject(responseBody);
            Integer errcode = (Integer) jsonObject.get("errcode");
            String errmsg = (String) jsonObject.get("errmsg");
            if (errcode != null) {
                throw new ServiceException(errmsg, errcode);
            }
        }
    }
    conn.disconnect();
    return null;
}
private static String readInputStream(InputStream inputStream) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder stringBuilder = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        stringBuilder.append(line);
    }
    reader.close();
    return stringBuilder.toString();
}

HTML测试小程序显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Display Base64 Image</title>
</head>
<body>
 
    <img src="data:image/png;base64,
    替换为base64字符串即可显示
    "/>
    
</body>
</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值