import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import com.hikvision.cloudSave.Picture;
import com.hikvision.cloudSave.Utils;
import com.hikvision.cloudSave.download.TransportPic;
import com.sun.istack.internal.logging.Logger;
import net.sf.json.JSONObject;
import sun.misc.BASE64Encoder;
/**
* @author tangze 2016年12月6日 下午7:27:58
* @version V1.0
* @modify: 上传图片,返回url
*/
public class PicStoreHandle {
private static Logger LOG = Logger.getLogger(PicStoreHandle.class);
//最优节点ip
private String gatewayIP = null;
//最有节点端口
private int gatewayPort = 0;
//上传图片到云存储的token
private String token = null;
//获取时间
private long tokenTime = 0;
//上传图片到云存储的socket对象
private Socket socket = null;
//上传图片到云存储的dataOutputStream对象
private DataOutputStream dos = null;
//上传图片到云存储的InputStream对象
private InputStream inputStream = null;
//基本http变量
private final static String END_STR = "\r\n";
private final static String TWO_HYPHENS = "--";
private final static String CONTENT_TYPE = "multipart/form-data";
private final static String BOUNDARY_STR = "7e02362550dc4";
private final static String DIVIDE = TWO_HYPHENS+BOUNDARY_STR;
private final static String TAIL_STR = DIVIDE + TWO_HYPHENS + END_STR + END_STR;
private final static String SERIAL_ID = "19216812001s";
//上传图片到云存储
public String uploadImageDataToHikStore(Picture picture){
synchronized(this){
String time_str = getGmtTime();
try{
if((System.currentTimeMillis() - tokenTime) > 2 * 60 * 1000){
closeSocket();
List<String> tokenList = getToken();
if (tokenList == null || tokenList.size() == 0) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
tokenList = getToken();
}
if (tokenList == null || tokenList.size() == 0) {
return null;
}
gatewayIP = tokenList.get(0);
String port = tokenList.get(1);
gatewayPort = Integer.parseInt(port);
token = tokenList.get(2);
tokenTime = System.currentTimeMillis();
try{
socket = new Socket(gatewayIP,gatewayPort);
dos = new DataOutputStream(socket.getOutputStream());
}catch(Exception e){
LOG.info("----->>>与存储建立连接出错:"+e.getMessage());
return null;
}
}
String url = "/HikCStor/Picture/Write";
String digest_info = stringToSign("POST","",CONTENT_TYPE,time_str,url);
String author_str = getAuthorization(time_str,digest_info);
//表单内容
String pic_len = Integer.toString(picture.getData().length);
String format_head = DIVIDE + END_STR;
format_head = format_head + " Content-Disposition: form-data;";
format_head = format_head + " name=\"SerialID\"" + END_STR + END_STR + SERIAL_ID + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"PoolID\"" + END_STR + END_STR + Utils.POOL_ID + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"TimeStamp\"" + END_STR + END_STR + picture.getTimeStamp() + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"PictureType\"" + END_STR + END_STR + picture.getType() + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"Token\"" + END_STR + END_STR + token + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"PictureLength\"" + END_STR + END_STR + pic_len + END_STR + DIVIDE + END_STR + "Content-Disposition: form-data;";
format_head = format_head + " name=\"Picture\"" + END_STR + "Content-Type: text/plain" + END_STR + END_STR;
long content_len = format_head.length() + picture.getData().length + TAIL_STR.length();
//http请求头
String http_head = "POST /HikCStor/Picture/Write HTTP/1.1" + END_STR;
http_head = http_head + "Host: " + gatewayIP + ":" + gatewayPort + END_STR;
http_head = http_head + "Accept-Language: zh-cn" + END_STR;
http_head = http_head + "Authorization: " + author_str + END_STR;
http_head = http_head + "Date: " + time_str + END_STR;
http_head = http_head + "Content-Type: " + CONTENT_TYPE + ";boundary=" + BOUNDARY_STR + END_STR;
http_head = http_head + "Content-Length: " + content_len + END_STR;
http_head = http_head + "Connection: keep-alive" + END_STR + END_STR;
// 1.先发送协议头
dos.write(http_head.getBytes());
// 2.发送表单内容
dos.write(format_head.getBytes());
// 3.发送图片数据
dos.write(picture.getData(), 0, picture.getData().length);
// 4.发送结束标志
dos.write(TAIL_STR.getBytes());
// 5.flush、close
dos.flush();
// 接收云存储的回复
byte[] response_buf = new byte[1024];
inputStream = socket.getInputStream();
inputStream.read(response_buf, 0, 1024);
String ret = new String(response_buf);
Pattern pattern = Pattern.compile("\"/pic\\?.*\"");
Matcher matcher = pattern.matcher(ret);
if (matcher.find()) {
String imageUrl = matcher.group(0);
imageUrl = "http://"+Utils.CLOUD_URL+":"+Utils.PORT_DOWLOAD+imageUrl.replace("\"", "");
return imageUrl;
} else {
closeSocket();
}
}catch(Exception e){
}
}
return null;
}
//生成云存储调用时最优节点
public List<String> getToken(){
String endpoint = "http://"+Utils.CLOUD_URL+":"+Utils.PORT_UPLOAD;
String url = "/HikCStor/BestNode?SerialID=" + SERIAL_ID + "&PoolID=" + Utils.POOL_ID + "&Replication=0";
endpoint = endpoint + url;
try{
String date = getGmtTime();
String sts = stringToSign("GET","","text/json",date,url);
String authorization = getAuthorization(date, sts);
URL restServiceURL = new URL(endpoint);
HttpURLConnection httpConnection = (HttpURLConnection)restServiceURL.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setConnectTimeout(2000);
httpConnection.setReadTimeout(1000);
httpConnection.setRequestProperty("Date", date);
httpConnection.setRequestProperty("Accept-Language", "zh-CN");
httpConnection.setRequestProperty("Content-Type", "text/json");
httpConnection.setRequestProperty("Authorization", authorization);
if (httpConnection.getResponseCode() != 200) {
LOG.info("----->>>获取云存储的Token出错, Error code : " + httpConnection.getResponseCode());
}
BufferedReader responseBuffer = new BufferedReader(new InputStreamReader((httpConnection.getInputStream())));
String output = "";
String result = "";
while ((output = responseBuffer.readLine()) != null) {
result = result + output;
}
httpConnection.disconnect();
httpConnection = null;
JSONObject obj = JSONObject.fromObject(result);
String GatewayIP = obj.getString("GatewayIP");
String GatewayPort = obj.getString("GatewayPort");
String token = obj.getString("Token");
List<String> retList = new ArrayList<String>();
retList.add(GatewayIP);
retList.add(GatewayPort);
retList.add(token);
return retList;
}catch(Exception e){
LOG.info("----->>>获取云存储的Token出错:" + e.getMessage());
}
return null;
}
//关闭Socket连接
public void closeSocket(){
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
}
inputStream = null;
}
if (dos != null) {
try {
dos.close();
} catch (Exception e) {
}
dos = null;
}
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
}
socket = null;
}
tokenTime = 0;
}
//加密算法
private static String getAuthorization(String date, String sts) {
String result = "";
try {
String StringToSign = new String(sts.getBytes(), "utf-8");
// 定义加密算法
String Algorithm = "HmacSHA1";
byte[] keyBytes = Utils.SERECT_KEY.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, Algorithm);
Mac mac = Mac.getInstance(Algorithm);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(StringToSign.getBytes());
String ret = new BASE64Encoder().encode(rawHmac);
result = "hikcstor " + Utils.ACCESS_KEY + ":" + ret;
} catch (Exception e) {
LOG.info("----->>>获取云存储的Authorization出错:" + e.getMessage());
}
return result;
}
//组装sign
public static String stringToSign(String httpverb,String contentmd5,String contenttype,String date,String url){
StringBuffer str = new StringBuffer("");
str.append(httpverb).append("\n");
str.append(contentmd5).append("\n");
str.append(contenttype).append("\n");
str.append(date).append("\n");
str.append(url);
return str.toString();
}
//获取GMT时间
private static String getGmtTime() {
Calendar cd = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE,d MMM yyyy HH:mm:ss 'GMT'",Locale.UK);
sdf.setTimeZone(TimeZone.getTimeZone("GMT")); // 设置时区为GMT
String str = sdf.format(cd.getTime());
return str;
}
public static void main(String[] args){
byte[] data = new TransportPic().downPic("http://c.hiphotos.baidu.com/image/h%3D200/sign=0915f9664aa98226a7c12c27ba83b97a/b3fb43166d224f4ac275080000f790529822d131.jpg");
Picture pic = new Picture(data,"1","1461745125");
String url = new PicStoreHandle().uploadImageDataToHikStore(pic);
System.out.println(url);
}
}
HTTP请求java组装
最新推荐文章于 2022-02-09 11:20:58 发布