Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

公众号开发永久下载图片和声音的接口 materialImageOrVoiceDownload 无法正常刷新 AccessToken #3196

Closed
shenliuming opened this issue Dec 26, 2023 · 0 comments · Fixed by #3197

Comments

@shenliuming
Copy link

第一次提Issue 暂时不会提PR 麻烦修复一下这个BUG

简要描述

请简单概括描述下你所遇到的问题。

模块版本情况

  • WxJava 模块名: weixin-java-mp
  • WxJava 版本号: 4.5.0
    具体的包名:me.chanjar.weixin.mp.util.requestexecuter.material

详细描述

正常刷新Token的逻辑:只有抛出异常了,才会去刷新 AccessToken

  public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
    int retryTimes = 0;
    do {
      try {
        return this.executeInternal(executor, uri, data, false);
      } catch (WxErrorException e) {
        WxError error = e.getError();
        // -1 系统繁忙, 1000ms后重试
        if (error.getErrorCode() == -1) {
          // 判断是否已经超了最大重试次数
          if (retryTimes + 1 > this.maxRetryTimes) {
            log.warn("重试达到最大次数【{}】", maxRetryTimes);
            //最后一次重试失败后,直接抛出异常,不再等待
            throw new WxRuntimeException("微信服务端异常,超出重试次数");
          }

          int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
          try {
            log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
            Thread.sleep(sleepMillis);
          } catch (InterruptedException e1) {
            throw new WxRuntimeException(e1);
          }
        } else {
          throw e;
        }
      }
    } while (retryTimes++ < this.maxRetryTimes);

    log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
    throw new WxRuntimeException("微信服务端异常,超出重试次数");
  }

这三个是下载永久 声音和图片的实现类

  public static RequestExecutor<InputStream, String> create(RequestHttp requestHttp, File tmpDirFile) {
    switch (requestHttp.getRequestType()) {
      case APACHE_HTTP:
        return new MaterialVoiceAndImageDownloadApacheHttpRequestExecutor(requestHttp, tmpDirFile);
      case JODD_HTTP:
        return new MaterialVoiceAndImageDownloadJoddHttpRequestExecutor(requestHttp, tmpDirFile);
      case OK_HTTP:
        return new MaterialVoiceAndImageDownloadOkhttpRequestExecutor(requestHttp, tmpDirFile);
      default:
        return null;
    }
  }

问题发生在 获取微信IO流的时候,没有正确判断ContentType 导致没有及时报错导致的:
MaterialVoiceAndImageDownloadOkhttpRequestExecutor

  @Override
  public InputStream execute(String uri, String materialId, WxType wxType) throws WxErrorException, IOException {
    logger.debug("MaterialVoiceAndImageDownloadOkhttpRequestExecutor is running");
    OkHttpClient client = requestHttp.getRequestHttpClient();

    RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"),
      WxGsonBuilder.create().toJson(ImmutableMap.of("media_id", materialId)));
    Request request = new Request.Builder().url(uri).get().post(requestBody).build();
    Response response = client.newCall(request).execute();
    String contentTypeHeader = response.header("Content-Type");
    // 问题发生在这个判断,没有及时抛出 微信异常,导致的,因为微信返回的ContentType 是application/json; encoding=utf-8
    if ("text/plain".equals(contentTypeHeader)) {
      String responseContent = response.body().string();
      throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP));
    }
    
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BufferedSink sink = Okio.buffer(Okio.sink(outputStream))) {
      sink.writeAll(response.body().source());
      return new ByteArrayInputStream(outputStream.toByteArray());
    }
  }

代码修复 只需要增加 这个application/json判断即可

ApiPost 返回

image

image

@binarywang binarywang changed the title weixin-java-mp 公众号开发永久下载图片和声音的接口 materialImageOrVoiceDownload 无法正常刷新 AccessToken 的BUG 公众号开发永久下载图片和声音的接口 materialImageOrVoiceDownload 无法正常刷新 AccessToken Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant