根据图片的描述是通过发送https请求上传图片。微信公众号提供的文档是通过curl命令来实现发送https post请求,但是我现在的程序是通过java程序来发送https post请求。以下是我的3个问题:
1、既然是发送https post请求上传图片,java应该也可以实现,我只实现过java https post的简单请求,没有实现过java https post图片上传。有大神能帮帮我吗?
2、既然微信公众号文档上说是通过curl来发送请求,那java是否提供模拟curl来发送https post请求来实现图片上传。如果java提供,有大神能帮帮我吗?
3、或者有没有谁实现过微信公众号以上截图描述的用java实现的多媒体文件上传功能,有实现过的话,共享以下代码啊!本人感激不尽!。
求大神帮帮忙!
2个回答
这个类,刚忘了一个方法httpsRequestToString,补充如下:
/**
* 发送请求以https方式发送请求并将请求响应内容以String方式返回
* @param path 请求路径
* @param method 请求方法
* @param body 请求数据体
* @return 请求响应内容转换成字符串信息
*/
public static String httpsRequestToString(String path, String method, String body) {
if(path==null||method==null){
return null;
}
String response = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
HttpsURLConnection conn = null;
try {
TrustManager[] tm = { new JEEWeiXinX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
SSLSocketFactory ssf = sslContext.getSocketFactory();
System.out.println(path);
URL url = new URL(path);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(method);
if (null != body) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
response = buffer.toString();
} catch (Exception e) {
logger.error(e);
}finally{
if(conn!=null){
conn.disconnect();
}
try {
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
} catch (IOException execption) {
logger.error(execption);
}
}
return response;
}
此外,还有一个证书实现类,发送https请求用的,也要定义的。
class JEEWeiXinX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
可以的。这个接口岁说是https的,但是用http仍然能上传资源的。我以前开发公众号的时候文档还是http协议上传的。今天试了,还是可以的。
我给你上传、下载的例子。你修改appId和appSecret测试上传下载图片文件看看。上传文件使用HttpClient类完成,需要net.sf.json和httpclient的jar。
API实现类代码如下,你修改上传文件路径和开发者账户直接运行试试。祝好!
public class WeChatApiUtil {
// token 接口(GET)
private static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
// 素材上传(POST)
private static final String UPLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/upload";
// 素材下载:不支持视频文件的下载(GET)
private static final String DOWNLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
public static String getTokenUrl(String appId, String appSecret) {
return String.format(ACCESS_TOKEN, appId, appSecret);
}
public static String getDownloadUrl(String token, String mediaId) {
return String.format(DOWNLOAD_MEDIA, token, mediaId);
}
/**
* 通用接口获取Token凭证
* @param appId
* @param appSecret
* @return
*/
public static String getToken(String appId, String appSecret) {
if(appId==null||appSecret==null){
return null;
}
String token = null;
String tockenUrl = WeChatApiUtil.getTokenUrl(appId, appSecret);
String response = httpsRequestToString(tockenUrl, "GET", null);
JSONObject jsonObject = JSONObject.fromObject(response);
if (null != jsonObject) {
try {
token =jsonObject.getString("access_token");
} catch (JSONException e) {
token = null;// 获取token失败
logger.error(e);
}
}
return token;
}
/**
* 微信服务器素材上传
* @param file 表单名称media
* @param token access_token
* @param type type只支持四种类型素材(video/image/voice/thumb)
*/
public static JSONObject uploadMedia(File file, String token, String type) {
if(file==null||token==null||type==null){
return null;
}
if(!file.exists()){
logger.info("上传文件不存在,请检查!");
return null;
}
String url = UPLOAD_MEDIA;
JSONObject jsonObject = null;
PostMethod post = new PostMethod(url);
post.setRequestHeader("Connection", "Keep-Alive");
post.setRequestHeader("Cache-Control", "no-cache");
FilePart media = null;
HttpClient httpClient = new HttpClient();
//信任任何类型的证书
Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps);
try {
media = new FilePart("media", file);
Part[] parts = new Part[] { new StringPart("access_token", token),
new StringPart("type", type), media };
MultipartRequestEntity entity = new MultipartRequestEntity(parts,
post.getParams());
post.setRequestEntity(entity);
int status = httpClient.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String text = post.getResponseBodyAsString();
jsonObject = JSONObject.fromObject(text);
} else {
logger.info("upload Media failure status is:" + status);
}
} catch (FileNotFoundException execption) {
logger.error(execption);
} catch (HttpException execption) {
logger.error(execption);
} catch (IOException execption) {
logger.error(execption);
}
return jsonObject;
}
/**
* 多媒体下载接口
* @comment 不支持视频文件的下载
* @param fileName 素材存储文件路径
* @param token 认证token
* @param mediaId 素材ID(对应上传后获取到的ID)
* @return 素材文件
*/
public static File downloadMedia(String fileName, String token,
String mediaId) {
String url = getDownloadUrl(token, mediaId);
return httpRequestToFile(fileName, url, "GET", null);
}
/**
* 以http方式发送请求,并将请求响应内容输出到文件
* @param path 请求路径
* @param method 请求方法
* @param body 请求数据
* @return 返回响应的存储到文件
*/
public static File httpRequestToFile(String fileName,String path, String method, String body) {
if(fileName==null||path==null||method==null){
return null;
}
File file = null;
HttpURLConnection conn = null;
InputStream inputStream = null;
FileOutputStream fileOut = null;
try {
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(method);
if (null != body) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
inputStream = conn.getInputStream();
if(inputStream!=null){
file = new File(fileName);
}else{
return file;
}
//写入到文件
fileOut = new FileOutputStream(file);
if(fileOut!=null){
int c = inputStream.read();
while(c!=-1){
fileOut.write(c);
c = inputStream.read();
}
}
} catch (Exception e) {
logger.error(e);
}finally{
if(conn!=null){
conn.disconnect();
}
/*
* 必须关闭文件流
* 否则JDK运行时,文件被占用其他进程无法访问
*/
try {
inputStream.close();
fileOut.close();
} catch (IOException execption) {
logger.error(execption);
}
}
return file;
}
public static void main(String[] args) {
File f = new File("D:/test.png");
String appId = "";
String appSecret = "";
String token = WeChatApiUtil.getToken(appId, appSecret);
JSONObject o = WeChatApiUtil.uploadMedia(f, token.getAccessToken(), "image");
System.out.println(o.toString());
//下载刚刚上传的图片以id命名
String media_id = o.getString("media_id");
File t = WeChatApiUtil.downloadMedia("D:/"+media_id+".png", token.getAccessToken(), media_id);
}
}