@@ -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); | |||||
} | |||||
} | } |