| @@ -294,6 +294,17 @@ public interface WxService { | |||||
| */ | */ | ||||
| public WxQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; | public WxQrCodeTicket qrCodeCreateLastTicket(int scene_id) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 换取二维码图片 | |||||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码 | |||||
| * </pre> | |||||
| * @param ticket 二维码ticket | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| public File qrCodePicture(WxQrCodeTicket ticket) throws WxErrorException; | |||||
| /** | /** | ||||
| * 注入 {@link WxConfigStorage} 的实现 | * 注入 {@link WxConfigStorage} 的实现 | ||||
| * @param wxConfigProvider | * @param wxConfigProvider | ||||
| @@ -35,9 +35,10 @@ import chanjarster.weixin.bean.result.WxQrCodeTicket; | |||||
| import chanjarster.weixin.bean.result.WxUser; | import chanjarster.weixin.bean.result.WxUser; | ||||
| import chanjarster.weixin.bean.result.WxUserList; | import chanjarster.weixin.bean.result.WxUserList; | ||||
| import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
| import chanjarster.weixin.util.fs.FileUtil; | |||||
| import chanjarster.weixin.util.fs.FileUtils; | |||||
| import chanjarster.weixin.util.http.MediaDownloadRequestExecutor; | import chanjarster.weixin.util.http.MediaDownloadRequestExecutor; | ||||
| import chanjarster.weixin.util.http.MediaUploadRequestExecutor; | import chanjarster.weixin.util.http.MediaUploadRequestExecutor; | ||||
| import chanjarster.weixin.util.http.QrCodeRequestExecutor; | |||||
| import chanjarster.weixin.util.http.RequestExecutor; | import chanjarster.weixin.util.http.RequestExecutor; | ||||
| import chanjarster.weixin.util.http.SimpleGetRequestExecutor; | import chanjarster.weixin.util.http.SimpleGetRequestExecutor; | ||||
| import chanjarster.weixin.util.http.SimplePostRequestExecutor; | import chanjarster.weixin.util.http.SimplePostRequestExecutor; | ||||
| @@ -161,7 +162,7 @@ public class WxServiceImpl implements WxService { | |||||
| } | } | ||||
| public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException { | public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException { | ||||
| return mediaUpload(mediaType,FileUtil.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | |||||
| return mediaUpload(mediaType,FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | |||||
| } | } | ||||
| public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { | public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { | ||||
| @@ -293,6 +294,11 @@ public class WxServiceImpl implements WxService { | |||||
| return WxQrCodeTicket.fromJson(responseContent); | return WxQrCodeTicket.fromJson(responseContent); | ||||
| } | } | ||||
| public File qrCodePicture(WxQrCodeTicket ticket) throws WxErrorException { | |||||
| String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode"; | |||||
| return execute(new QrCodeRequestExecutor(), url, ticket); | |||||
| } | |||||
| /** | /** | ||||
| * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
| * @param executor | * @param executor | ||||
| @@ -5,7 +5,7 @@ import java.io.FileOutputStream; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| public class FileUtil { | |||||
| public class FileUtils { | |||||
| /** | /** | ||||
| * 创建临时文件 | * 创建临时文件 | ||||
| @@ -15,10 +15,10 @@ import org.apache.http.entity.ContentType; | |||||
| import chanjarster.weixin.bean.result.WxError; | import chanjarster.weixin.bean.result.WxError; | ||||
| import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
| import chanjarster.weixin.util.fs.FileUtil; | |||||
| import chanjarster.weixin.util.fs.FileUtils; | |||||
| /** | /** | ||||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是String | |||||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||||
| * @author chanjarster | * @author chanjarster | ||||
| * | * | ||||
| */ | */ | ||||
| @@ -52,7 +52,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| return null; | return null; | ||||
| } | } | ||||
| String[] name_ext = fileName.split("\\."); | String[] name_ext = fileName.split("\\."); | ||||
| File localFile = FileUtil.createTmpFile(inputStream, name_ext[0], name_ext[1]); | |||||
| File localFile = FileUtils.createTmpFile(inputStream, name_ext[0], name_ext[1]); | |||||
| return localFile; | return localFile; | ||||
| } | } | ||||
| @@ -0,0 +1,56 @@ | |||||
| package chanjarster.weixin.util.http; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.net.URLEncoder; | |||||
| import java.util.UUID; | |||||
| import org.apache.http.Header; | |||||
| import org.apache.http.client.ClientProtocolException; | |||||
| import org.apache.http.client.methods.CloseableHttpResponse; | |||||
| import org.apache.http.client.methods.HttpGet; | |||||
| import org.apache.http.entity.ContentType; | |||||
| import chanjarster.weixin.bean.result.WxError; | |||||
| import chanjarster.weixin.bean.result.WxQrCodeTicket; | |||||
| import chanjarster.weixin.exception.WxErrorException; | |||||
| import chanjarster.weixin.util.fs.FileUtils; | |||||
| /** | |||||
| * 获得QrCode图片 请求执行器 | |||||
| * @author chanjarster | |||||
| * | |||||
| */ | |||||
| public class QrCodeRequestExecutor implements RequestExecutor<File, WxQrCodeTicket> { | |||||
| @Override | |||||
| public File execute(String uri, WxQrCodeTicket ticket) throws WxErrorException, ClientProtocolException, IOException { | |||||
| if (ticket != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? | |||||
| "ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8") | |||||
| : | |||||
| "&ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8"); | |||||
| } | |||||
| HttpGet httpGet = new HttpGet(uri); | |||||
| CloseableHttpResponse response = httpclient.execute(httpGet); | |||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | |||||
| if (contentTypeHeader != null && contentTypeHeader.length > 0) { | |||||
| // 出错 | |||||
| if (ContentType.TEXT_PLAIN.getMimeType().equals(contentTypeHeader[0].getValue())) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||||
| } | |||||
| } | |||||
| InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response); | |||||
| File localFile = FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg"); | |||||
| return localFile; | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| package chanjarster.weixin.api; | package chanjarster.weixin.api; | ||||
| import java.io.File; | |||||
| import org.testng.Assert; | import org.testng.Assert; | ||||
| import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
| @@ -12,8 +13,8 @@ import com.google.inject.Inject; | |||||
| /** | /** | ||||
| * 测试用户相关的接口 | * 测试用户相关的接口 | ||||
| * | |||||
| * @author chanjarster | * @author chanjarster | ||||
| * | |||||
| */ | */ | ||||
| @Test(groups = "qrCodeAPI", dependsOnGroups = { "baseAPI" }) | @Test(groups = "qrCodeAPI", dependsOnGroups = { "baseAPI" }) | ||||
| @Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
| @@ -21,19 +22,25 @@ public class WxQrCodeAPITest { | |||||
| @Inject | @Inject | ||||
| protected WxServiceImpl wxService; | protected WxServiceImpl wxService; | ||||
| public void testQrCodeCreateTmpTicket() throws WxErrorException { | |||||
| public void testQrCodeCreateTmpTicket() throws WxErrorException { | |||||
| WxQrCodeTicket ticket = wxService.qrCodeCreateTmpTicket(1, null); | WxQrCodeTicket ticket = wxService.qrCodeCreateTmpTicket(1, null); | ||||
| Assert.assertNotNull(ticket.getUrl()); | Assert.assertNotNull(ticket.getUrl()); | ||||
| Assert.assertNotNull(ticket.getTicket()); | Assert.assertNotNull(ticket.getTicket()); | ||||
| Assert.assertTrue(ticket.getExpire_seconds() != -1); | Assert.assertTrue(ticket.getExpire_seconds() != -1); | ||||
| } | } | ||||
| public void testQrCodeCreateLastTicket() throws WxErrorException { | |||||
| public void testQrCodeCreateLastTicket() throws WxErrorException { | |||||
| WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(1); | WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(1); | ||||
| Assert.assertNotNull(ticket.getUrl()); | Assert.assertNotNull(ticket.getUrl()); | ||||
| Assert.assertNotNull(ticket.getTicket()); | Assert.assertNotNull(ticket.getTicket()); | ||||
| Assert.assertTrue(ticket.getExpire_seconds() == -1); | Assert.assertTrue(ticket.getExpire_seconds() == -1); | ||||
| } | } | ||||
| public void testQrCodePicture() throws WxErrorException { | |||||
| WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(1); | |||||
| File file = wxService.qrCodePicture(ticket); | |||||
| Assert.assertNotNull(file); | |||||
| } | |||||
| } | } | ||||