一、需求说明

二维码已经是随处可见,与二维码相关的功能也很多,常见的有扫码登录功能、扫码支付功能等等。那扫描二维码背后的原理是什么? 从功能应用的角度看,二维码可以看成是一个链接,用户扫描二维码的过程,就是点击链接的过程。我们都知道,点击链接之后,会跳转到指定页面;而扫描二维码之后,也同样会跳转到指定页面。 接下来就讲讲用Java如何生成一个可以跳转到微信小程序界面的二维码。

二、小程序码介绍

跳转到小程序页面的二维码称为小程序码,微信官方目前提供了三种方式,生成对应的小程序码。具体介绍可以看官方文档:wxacode.createQRCode | 微信开放文档 三种不同方式从编程角度看,是在调用三个不同的接口,三个不同接口的限制条件和生成的小程序码有一些区别,要根据具体的业务需求选用。接下来是对这三种生成小程序码方式的说明:

2.1 方式一:createQRCode
  • 介绍

这种方式适用于需要的码数量较少的业务场景。通过此接口生成的小程序码,永久有效,有数量限制。

  • 请求地址

POST https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN

  • 请求参数

属性

类型

默认值

必填

说明

access_token / cloudbase_access_token

string

接口调用凭证

path

string

扫码进入的小程序页面路径,最大长度 128 字节,不能为空;对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar",即可在 wx.getLaunchOptionsSync 接口中的 query 参数获取到 {foo:"bar"}。

width

number

430

二维码的宽度,单位 px。最小 280px,最大 1280px

  • 返回值

返回二维码图片的Buffer

2.2 方式二:getwxacode
  • 介绍

适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。

  • 请求地址

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

  • 请求参数

属性

类型

默认值

必填

说明

access_token / cloudbase_access_token

string

接口调用凭证

path

string

扫码进入的小程序页面路径,最大长度 1024 字节,不能为空;对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar",即可在 wx.getLaunchOptionsSync 接口中的 query 参数获取到 {foo:"bar"}。

env_version

string

"release"

要打开的小程序版本。正式版为 release,体验版为 trial,开发版为 develop

width

number

430

二维码的宽度,单位 px。最小 280px,最大 1280px

auto_color

boolean

false

自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调

line_color

Object

{"r":0,"g":0,"b":0}

auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示

is_hyaline

boolean

false

是否需要透明底色,为 true 时,生成透明底色的小程序码

  • 返回值

返回二维码图片的Buffer

2.3 方式三:getUnlimited
  • 介绍

适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。

  • 请求地址

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

  • 请求参数

属性

类型

默认值

必填

说明

access_token / cloudbase_access_token

string

接口调用凭证

scene

string

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

page

string

主页

页面 page,例如 pages/index/index,根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面

check_path

boolean

true

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

env_version

string

"release"

要打开的小程序版本。正式版为 release,体验版为 trial,开发版为 develop

width

number

430

二维码的宽度,单位 px,最小 280px,最大 1280px

auto_color

boolean

false

自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调,默认 false

line_color

Object

{"r":0,"g":0,"b":0}

auto_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示

is_hyaline

boolean

false

是否需要透明底色,为 true 时,生成透明底色的小程序

  • 返回值

返回二维码图片的Buffer

三、Java后台代码实现示例

接下来的案例是以方式二来实现的。

实现逻辑分为两步,第一,调用接口拿到ACCESS_TOKEN;第二,提供ACCESS_TOKEN等参数,拿到返回的小程序码的Buffer流。

  • 获取ACCESS_TOKEN接口
@RestController
class AccessTokenController {

    @GetMapping("/getAccessToken")
    public String getAccessToken() {
        // 微信小程序的APPID和SECRET
        String appid = "543543xxw";
        String secret = "343543";
        
        // 请求微信API获取ACCESS_TOKEN的URL
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;

        // 使用RestTemplate发送GET请求
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject(url, String.class);

        // 使用Jackson库解析JSON字符串
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(response);
            String accessToken = jsonNode.get("access_token").asText();
            
            // 输出获取到的ACCESS_TOKEN
            System.out.println("Access Token: " + accessToken);

            return accessToken;
        } catch (Exception e) {
            e.printStackTrace();
            return "Failed to retrieve access token";
        }
    }
}

  • 获取小程序码接口
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.HashMap;
import java.util.Map;

@RestController
class MiniProgramCodeController {

    private final String WECHAT_API_URL = "https://api.weixin.qq.com/wxa/getwxacode";

    @PostMapping("/generateMiniProgramCode")
    public byte[] generateMiniProgramCode(@RequestBody MiniProgramCodeRequest request) {
        // 构建请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("access_token", request.getAccessToken());
        params.put("path", request.getPath());
        params.put("width", request.getWidth());

        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 构建请求实体
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(params, headers);

        // 发送POST请求
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForObject(buildUrl(), httpEntity, byte[].class);
    }

    private String buildUrl() {
        // 构建带有access_token参数的URL
        return UriComponentsBuilder.fromHttpUrl(WECHAT_API_URL)
                .queryParam("access_token", "12323")
                .toUriString();
    }
}

class MiniProgramCodeRequest {
    private String accessToken;
    private String path;
    private int width;

    // 省略构造函数、getter和setter
}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐