| @@ -294,6 +294,17 @@ public interface WxService { | |||
| */ | |||
| 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} 的实现 | |||
| * @param wxConfigProvider | |||
| @@ -35,9 +35,10 @@ import chanjarster.weixin.bean.result.WxQrCodeTicket; | |||
| import chanjarster.weixin.bean.result.WxUser; | |||
| import chanjarster.weixin.bean.result.WxUserList; | |||
| 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.MediaUploadRequestExecutor; | |||
| import chanjarster.weixin.util.http.QrCodeRequestExecutor; | |||
| import chanjarster.weixin.util.http.RequestExecutor; | |||
| import chanjarster.weixin.util.http.SimpleGetRequestExecutor; | |||
| 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 { | |||
| 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 { | |||
| @@ -293,6 +294,11 @@ public class WxServiceImpl implements WxService { | |||
| 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过期时才去刷新,然后重新执行请求,而不是全局定时请求 | |||
| * @param executor | |||
| @@ -5,7 +5,7 @@ import java.io.FileOutputStream; | |||
| import java.io.IOException; | |||
| 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.exception.WxErrorException; | |||
| import chanjarster.weixin.util.fs.FileUtil; | |||
| import chanjarster.weixin.util.fs.FileUtils; | |||
| /** | |||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是String | |||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||
| * @author chanjarster | |||
| * | |||
| */ | |||
| @@ -52,7 +52,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||
| return null; | |||
| } | |||
| 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; | |||
| } | |||
| @@ -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; | |||
| import java.io.File; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.Guice; | |||
| @@ -12,8 +13,8 @@ import com.google.inject.Inject; | |||
| /** | |||
| * 测试用户相关的接口 | |||
| * | |||
| * @author chanjarster | |||
| * | |||
| */ | |||
| @Test(groups = "qrCodeAPI", dependsOnGroups = { "baseAPI" }) | |||
| @Guice(modules = ApiTestModule.class) | |||
| @@ -21,19 +22,25 @@ public class WxQrCodeAPITest { | |||
| @Inject | |||
| protected WxServiceImpl wxService; | |||
| public void testQrCodeCreateTmpTicket() throws WxErrorException { | |||
| public void testQrCodeCreateTmpTicket() throws WxErrorException { | |||
| WxQrCodeTicket ticket = wxService.qrCodeCreateTmpTicket(1, null); | |||
| Assert.assertNotNull(ticket.getUrl()); | |||
| Assert.assertNotNull(ticket.getTicket()); | |||
| Assert.assertTrue(ticket.getExpire_seconds() != -1); | |||
| } | |||
| public void testQrCodeCreateLastTicket() throws WxErrorException { | |||
| public void testQrCodeCreateLastTicket() throws WxErrorException { | |||
| WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(1); | |||
| Assert.assertNotNull(ticket.getUrl()); | |||
| Assert.assertNotNull(ticket.getTicket()); | |||
| Assert.assertTrue(ticket.getExpire_seconds() == -1); | |||
| } | |||
| public void testQrCodePicture() throws WxErrorException { | |||
| WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(1); | |||
| File file = wxService.qrCodePicture(ticket); | |||
| Assert.assertNotNull(file); | |||
| } | |||
| } | |||