package cn.jmessage.api.resource; import cn.jiguang.common.ServiceHelper; import cn.jiguang.common.utils.Preconditions; import cn.jiguang.common.connection.HttpProxy; import cn.jiguang.common.resp.APIConnectionException; import cn.jiguang.common.resp.APIRequestException; import cn.jiguang.common.resp.ResponseWrapper; import cn.jmessage.api.common.BaseClient; import cn.jmessage.api.common.JMessageConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class ResourceClient extends BaseClient { private static Logger LOG = LoggerFactory.getLogger(ResourceClient.class); private String resourcePath; private String authCode; public ResourceClient(String appkey, String masterSecret) { this(appkey, masterSecret, null, JMessageConfig.getInstance()); } public ResourceClient(String appkey, String masterSecret, HttpProxy proxy) { this(appkey, masterSecret, proxy, JMessageConfig.getInstance()); } /** * Create a JMessage Base Client * * @param appkey The KEY of one application on JPush. * @param masterSecret API access secret of the appKey. * @param proxy The proxy, if there is no proxy, should be null. * @param config The client configuration. Can use JMessageConfig.getInstance() as default. */ public ResourceClient(String appkey, String masterSecret, HttpProxy proxy, JMessageConfig config) { super(appkey, masterSecret, proxy, config); this.resourcePath = (String) config.get(JMessageConfig.RESOURCE_PATH); this.authCode = ServiceHelper.getBasicAuthorization(appkey, masterSecret); } /** * Download file with mediaId, will return DownloadResult which include url. * @param mediaId Necessary * @return DownloadResult * @throws APIConnectionException connect exception * @throws APIRequestException request exception */ public DownloadResult downloadFile(String mediaId) throws APIConnectionException, APIRequestException { Preconditions.checkArgument(null != mediaId, "mediaId is necessary"); ResponseWrapper response = _httpClient.sendGet(_baseUrl + resourcePath + "?mediaId=" + mediaId); return DownloadResult.fromResponse(response, DownloadResult.class); } /** * Upload file, only support image file(jpg, bmp, gif, png) currently, * file size should not larger than 8M. * @param path Necessary, the native path of the file you want to upload * @param fileType should be "image" or "file" or "voice" * @return UploadResult * @throws APIConnectionException connect exception * @throws APIRequestException request exception */ public UploadResult uploadFile(String path, String fileType) throws APIConnectionException, APIRequestException { Preconditions.checkArgument(null != path, "filename is necessary"); Preconditions.checkArgument(fileType.equals("image") || fileType.equals("file") || fileType.equals("voice"), "Illegal file type!"); File file = new File(path); if (file.exists() && file.isFile()) { long fileSize = file.length(); if (fileSize > 8 * 1024 * 1024) { throw new IllegalArgumentException("File size should not larger than 8M"); } try { // 换行符 final String newLine = "\r\n"; final String boundaryPrefix = "--"; // 定义数据分隔线 String BOUNDARY = "========7d4a6d158c9"; URL url = new URL(_baseUrl + resourcePath + "?type=" + fileType); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Charset", "UTF-8"); conn.setRequestProperty("Authorization", this.authCode); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); OutputStream out = new DataOutputStream(conn.getOutputStream()); StringBuilder sb = new StringBuilder(); sb.append(boundaryPrefix); sb.append(BOUNDARY); sb.append(newLine); sb.append("Content-Disposition: form-data;name=\"" + fileType + "\";filename=\"" + path + "\"" + newLine); sb.append("Content-Type:application/octet-stream"); // 参数头设置完以后需要两个换行,然后才是参数内容 sb.append(newLine); sb.append(newLine); out.write(sb.toString().getBytes()); DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file)); byte[] bufferOut = new byte[1024]; int bytes = 0; while ((bytes = dataInputStream.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } out.write(newLine.getBytes()); dataInputStream.close(); // 定义最后数据分隔线,即--加上BOUNDARY再加上--。 byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine) .getBytes(); // 写上结尾标识 out.write(end_data); out.flush(); out.close(); LOG.debug("Send request - POST" + " " + url); int status1 = conn.getResponseCode(); StringBuffer stringBuffer = new StringBuffer(); InputStream in = null; if(status1 / 100 == 2) { in = conn.getInputStream(); } else { in = conn.getErrorStream(); } if(null != in) { InputStreamReader responseContent = new InputStreamReader(in, "UTF-8"); char[] quota = new char[1024]; int remaining; while((remaining = responseContent.read(quota)) > 0) { stringBuffer.append(quota, 0, remaining); } } ResponseWrapper wrapper = new ResponseWrapper(); String responseContent1 = stringBuffer.toString(); wrapper.responseCode = status1; wrapper.responseContent = responseContent1; String quota1 = conn.getHeaderField("X-Rate-Limit-Limit"); String remaining1 = conn.getHeaderField("X-Rate-Limit-Remaining"); String reset = conn.getHeaderField("X-Rate-Limit-Reset"); wrapper.setRateLimit(quota1, remaining1, reset); if(status1 >= 200 && status1 < 300) { LOG.debug("Succeed to get response OK - responseCode:" + status1); LOG.debug("Response Content - " + responseContent1); } else { if(status1 < 300 || status1 >= 400) { LOG.warn("Got error response - responseCode:" + status1 + ", responseContent:" + responseContent1); wrapper.setErrorObject(); throw new APIRequestException(wrapper); } LOG.warn("Normal response but unexpected - responseCode:" + status1 + ", responseContent:" + responseContent1); } return UploadResult.fromResponse(wrapper, UploadResult.class); } catch (Exception e) { e.printStackTrace(); } } else { throw new IllegalArgumentException("File name is invalid, please check again"); } return null; } }