diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java new file mode 100644 index 0000000000..e3077fd00a --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java @@ -0,0 +1,38 @@ +package me.chanjar.weixin.common.bean.result; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +@Data +public class WxMinishopImageUploadCustomizeResult implements Serializable { + private String errcode; + private String errmsg; + + private WxMinishopPicFileCustomizeResult imgInfo; + + public static WxMinishopImageUploadCustomizeResult fromJson(String json) { + JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject(); + WxMinishopImageUploadCustomizeResult result = new WxMinishopImageUploadCustomizeResult(); + result.setErrcode(jsonObject.get("errcode").getAsNumber().toString()); + if (result.getErrcode().equals("0")) { + WxMinishopPicFileCustomizeResult picFileResult = new WxMinishopPicFileCustomizeResult(); + JsonObject picObject = jsonObject.get("img_info").getAsJsonObject(); + picFileResult.setMediaId(picObject.get("media_id").getAsString()); + if (picObject.has("temp_img_url")) { + picFileResult.setTempImgUrl(picObject.get("temp_img_url").getAsString()); + } + result.setImgInfo(picFileResult); + + } + return result; + } + + @Override + public String toString() { + return WxGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopPicFileCustomizeResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopPicFileCustomizeResult.java new file mode 100644 index 0000000000..8f2f36f8dd --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopPicFileCustomizeResult.java @@ -0,0 +1,11 @@ +package me.chanjar.weixin.common.bean.result; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxMinishopPicFileCustomizeResult implements Serializable { + private String mediaId; + private String tempImgUrl; +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MinishopUploadRequestCustomizeExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MinishopUploadRequestCustomizeExecutor.java new file mode 100644 index 0000000000..d782466c3b --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MinishopUploadRequestCustomizeExecutor.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.common.util.http; + +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.apache.ApacheMinishopMediaUploadRequestCustomizeExecutor; +import me.chanjar.weixin.common.util.http.jodd.JoddHttpMinishopMediaUploadRequestCustomizeExecutor; +import me.chanjar.weixin.common.util.http.okhttp.OkHttpMinishopMediaUploadRequestCustomizeExecutor; + +import java.io.File; +import java.io.IOException; + +public abstract class MinishopUploadRequestCustomizeExecutor implements RequestExecutor { + protected RequestHttp requestHttp; + + public MinishopUploadRequestCustomizeExecutor(RequestHttp requestHttp) { + this.requestHttp = requestHttp; + } + + @Override + public void execute(String uri, File data, ResponseHandler handler, WxType wxType) throws WxErrorException, IOException { + handler.handle(this.execute(uri, data, wxType)); + } + + public static RequestExecutor create(RequestHttp requestHttp) { + switch (requestHttp.getRequestType()) { + case APACHE_HTTP: + return new ApacheMinishopMediaUploadRequestCustomizeExecutor(requestHttp); + case JODD_HTTP: + return new JoddHttpMinishopMediaUploadRequestCustomizeExecutor(requestHttp); + case OK_HTTP: + return new OkHttpMinishopMediaUploadRequestCustomizeExecutor(requestHttp); + default: + return null; + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMinishopMediaUploadRequestCustomizeExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMinishopMediaUploadRequestCustomizeExecutor.java new file mode 100644 index 0000000000..dc38fbae5a --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMinishopMediaUploadRequestCustomizeExecutor.java @@ -0,0 +1,58 @@ +package me.chanjar.weixin.common.util.http.apache; + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.MinishopUploadRequestCustomizeExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.File; +import java.io.IOException; + +/** + * Created by liming1019 on 2021/8/10. + */ +@Slf4j +public class ApacheMinishopMediaUploadRequestCustomizeExecutor extends MinishopUploadRequestCustomizeExecutor { + public ApacheMinishopMediaUploadRequestCustomizeExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMinishopImageUploadCustomizeResult execute(String uri, File file, WxType wxType) throws WxErrorException, IOException { + HttpPost httpPost = new HttpPost(uri); + if (requestHttp.getRequestHttpProxy() != null) { + RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); + httpPost.setConfig(config); + } + if (file != null) { + HttpEntity entity = MultipartEntityBuilder + .create() + .addBinaryBody("media", file) + .setMode(HttpMultipartMode.RFC6532) + .build(); + httpPost.setEntity(entity); + } + try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { + String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); + WxError error = WxError.fromJson(responseContent, wxType); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + log.info("responseContent: " + responseContent); + return WxMinishopImageUploadCustomizeResult.fromJson(responseContent); + } finally { + httpPost.releaseConnection(); + } + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMinishopMediaUploadRequestCustomizeExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMinishopMediaUploadRequestCustomizeExecutor.java new file mode 100644 index 0000000000..8fa1de4279 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMinishopMediaUploadRequestCustomizeExecutor.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.common.util.http.jodd; + +import jodd.http.HttpConnectionProvider; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; +import jodd.http.ProxyInfo; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.MinishopUploadRequestCustomizeExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * @author liming1019 + * @date 2021/8/10 + */ +@Slf4j +public class JoddHttpMinishopMediaUploadRequestCustomizeExecutor extends MinishopUploadRequestCustomizeExecutor { + public JoddHttpMinishopMediaUploadRequestCustomizeExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMinishopImageUploadCustomizeResult execute(String uri, File file, WxType wxType) throws WxErrorException, IOException { + HttpRequest request = HttpRequest.post(uri); + if (requestHttp.getRequestHttpProxy() != null) { + requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); + } + request.withConnectionProvider(requestHttp.getRequestHttpClient()); + request.form("media", file); + HttpResponse response = request.send(); + response.charset(StandardCharsets.UTF_8.name()); + + String responseContent = response.bodyText(); + WxError error = WxError.fromJson(responseContent, wxType); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + log.info("responseContent: " + responseContent); + + return WxMinishopImageUploadCustomizeResult.fromJson(responseContent); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMinishopMediaUploadRequestCustomizeExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMinishopMediaUploadRequestCustomizeExecutor.java new file mode 100644 index 0000000000..8b2cdc7b6c --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMinishopMediaUploadRequestCustomizeExecutor.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.common.util.http.okhttp; + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.MinishopUploadRequestCustomizeExecutor; +import me.chanjar.weixin.common.util.http.RequestHttp; +import okhttp3.*; + +import java.io.File; +import java.io.IOException; + +/** + * @author liming1019 + * @date 2021/8/10 + */ +@Slf4j +public class OkHttpMinishopMediaUploadRequestCustomizeExecutor extends MinishopUploadRequestCustomizeExecutor { + public OkHttpMinishopMediaUploadRequestCustomizeExecutor(RequestHttp requestHttp) { + super(requestHttp); + } + + @Override + public WxMinishopImageUploadCustomizeResult execute(String uri, File file, WxType wxType) throws WxErrorException, IOException { + + RequestBody body = new MultipartBody.Builder() + .setType(MediaType.parse("multipart/form-data")) + .addFormDataPart("media", + file.getName(), + RequestBody.create(MediaType.parse("application/octet-stream"), file)) + .build(); + Request request = new Request.Builder().url(uri).post(body).build(); + + Response response = requestHttp.getRequestHttpClient().newCall(request).execute(); + String responseContent = response.body().string(); + WxError error = WxError.fromJson(responseContent, wxType); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + log.info("responseContent: " + responseContent); + + return WxMinishopImageUploadCustomizeResult.fromJson(responseContent); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java index 7b311952e8..3115a7d5b9 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java @@ -426,6 +426,13 @@ public interface WxMaService extends WxService { */ WxMaShopCatService getShopCatService(); + /** + * 小程序交易组件-接入商品前必需接口-上传图片 + * + * @return + */ + WxMaShopImgService getShopImgService(); + /** * 获取小程序 URL Link服务接口 * diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaShopImgService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaShopImgService.java new file mode 100644 index 0000000000..c44bc7df35 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaShopImgService.java @@ -0,0 +1,21 @@ +package cn.binarywang.wx.miniapp.api; + +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.io.File; + +/** + * 小程序交易组件-接入商品前必需接口 + * + * @author liming1019 + */ +public interface WxMaShopImgService { + /** + * 上传图片 + * + * @return WxMinishopImageUploadCustomizeResult + * @throws WxErrorException + */ + WxMinishopImageUploadCustomizeResult uploadImg(File file) throws WxErrorException; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java index 48cd6f4189..1de659e603 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java @@ -68,6 +68,7 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH private final WxMaShopRegisterService shopRegisterService = new WxMaShopRegisterServiceImpl(this); private final WxMaShopAccountService shopAccountService = new WxMaShopAccountServiceImpl(this); private final WxMaShopCatService shopCatService = new WxMaShopCatServiceImpl(this); + private final WxMaShopImgService shopImgService = new WxMaShopImgServiceImpl(this); private final WxMaLinkService linkService = new WxMaLinkServiceImpl(this); private final WxMaReimburseInvoiceService reimburseInvoiceService = new WxMaReimburseInvoiceServiceImpl(this); private Map configMap; @@ -534,6 +535,11 @@ public WxMaShopCatService getShopCatService() { return this.shopCatService; } + @Override + public WxMaShopImgService getShopImgService() { + return this.shopImgService; + } + @Override public WxMaLinkService getLinkService() { return this.linkService; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImpl.java new file mode 100644 index 0000000000..f253bca280 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImpl.java @@ -0,0 +1,29 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaShopImgService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.MinishopUploadRequestCustomizeExecutor; + +import java.io.File; + +import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.Shop.Img.IMG_UPLOAD; + +/** + * @author liming1019 + */ +@RequiredArgsConstructor +@Slf4j +public class WxMaShopImgServiceImpl implements WxMaShopImgService { + private final WxMaService service; + + @Override + public WxMinishopImageUploadCustomizeResult uploadImg(File file) throws WxErrorException { + WxMinishopImageUploadCustomizeResult result = this.service.execute( + MinishopUploadRequestCustomizeExecutor.create(this.service.getRequestHttp()), IMG_UPLOAD, file); + return result; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java index c6b428db85..c76c8963d6 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java @@ -337,6 +337,10 @@ interface Account { interface Cat { String GET_CAT = "https://api.weixin.qq.com/shop/cat/get"; } + + interface Img { + String IMG_UPLOAD = "https://api.weixin.qq.com/shop/img/upload"; + } } /** diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImplTest.java new file mode 100644 index 0000000000..191b429630 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaShopImgServiceImplTest.java @@ -0,0 +1,31 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.inject.Inject; +import me.chanjar.weixin.common.bean.result.WxMinishopImageUploadCustomizeResult; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author liming1019 + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaShopImgServiceImplTest { + + @Inject + private WxMaService wxService; + + @Test + public void testUploadImg() throws WxErrorException { + File file = new File("/Users/liming/Desktop/test.jpeg"); + WxMinishopImageUploadCustomizeResult result = wxService.getShopImgService().uploadImg(file); + assertThat(result).isNotNull(); + } +}