OcrDemo.java
腾讯API调用通过工具类,只要修改相应的参数即可。
public class OcrDemo {
public static void main(String[] args) throws TencentCloudSDKException {
//以文字识别为例
String base64 = imgToBase64("https://xxxx.png");
//修改Action,verstion等参数,这个接口是通用的
JSONObject requestParams = new JSONObject();
requestParams.put("RequestMethod", "POST");
requestParams.put("Nonce", new Random().nextInt(java.lang.Integer.MAX_VALUE));
requestParams.put("Timestamp", System.currentTimeMillis() / 1000);
requestParams.put("Action", "GeneralBasicOCR");
requestParams.put("Version", "2018-11-19");
requestParams.put("Region", "ap-guangzhou");
requestParams.put("ImageBase64", base64);
TencentUtil tencentUtil = new TencentUtil();
String result = tencentUtil.callTencentApi("ocr","GeneralBasicOCR",
"ocr.tencentcloudapi.com","/","填入你的appid",
"填入你的secret",
requestParams);
JSONObject jsonObject = JSONObject.parseObject(result);
System.out.println(jsonObject.toJSONString());
}
/**
* 服务器图片转换base64 path:服务器图片路径 返回 base64编码(String 类型)
* @param path
* @return
*/
public static String imgToBase64(String path){
byte[] data = null;
InputStream in = null;
ByteArrayOutputStream out = null;
try{
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
in = connection.getInputStream();
out = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len = 0;
while((len =in.read(b)) != -1){
out.write(b,0,len);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(in != null ){
in.close();
}
}catch (IOException e){
e.getStackTrace();
}
}
System.out.println("转换后的图片大小:"+out.toByteArray().length/1024);
BASE64Encoder base = new BASE64Encoder();
return base.encode(out.toByteArray());
}
}
TencentUtil.java
@Component
public class TencentUtil {
public String callTencentApi(String productCode, String action, String productDomain, String productDomainSuffix, String secretId, String secretKey, JSONObject requestParams) throws TencentCloudSDKException {
String result = "";
String url = "https://"+productDomain+productDomainSuffix;
TreeMap<String, Object> treeMap = new TreeMap<>();
treeMap.putAll(requestParams);
String requestMethod = "";
if(treeMap.get("RequestMethod")==null) {
requestMethod = "GET";
} else {
requestMethod = treeMap.get("RequestMethod").toString();
}
if(StringUtils.isBlank(requestMethod)){
requestMethod = "GET";
}
if (treeMap.containsKey("RequestMethod")) {
treeMap.remove("RequestMethod");
}
if (!treeMap.containsKey("SecretId")) {
treeMap.put("SecretId", secretId);
}
if (!treeMap.containsKey("Action")) {
treeMap.put("Action", action);
}
if (!treeMap.containsKey("Nonce")) {
treeMap.put("Nonce", new Random().nextInt(Integer.MAX_VALUE));
}
if (!treeMap.containsKey("Timestamp")) {
treeMap.put("Timestamp", System.currentTimeMillis() / 1000L);
}
if("GET".equalsIgnoreCase(requestMethod)){
//计算v1签名
String signatureMethod = "HmacSHA1";
if (treeMap.containsKey("SignatureMethod") && treeMap.get("SignatureMethod").toString().equals("HmacSHA256")) {
signatureMethod = "HmacSHA256";
}
String plainText = Sign.makeSignPlainText(treeMap,"GET",productDomain,productDomainSuffix);
try {
treeMap.put("Signature", Sign.sign(plainText, secretKey, signatureMethod));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
//调用腾讯接口
result = sendTencentGet(url,treeMap,requestMethod);
}else {
//计算v3签名
result = sendTencentPost(url,treeMap,requestMethod,productCode,productDomain,secretId,secretKey);
}
return result;
}
public static String sendTencentPost(String url, TreeMap<String, Object> requestParams,String requestMethod,String service,String host,String secretId,String secretKey) {
String action = requestParams.get("Action").toString();
String version = requestParams.get("Version").toString();
String region = requestParams.get("Region").toString();
String algorithm = "TC3-HMAC-SHA256";
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 注意时区,否则容易出错
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));
// ************* 步骤 1:拼接规范请求串 *************
String httpRequestMethod = "POST";
String canonicalUri = "/";
String canonicalQueryString = "";
String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";
String signedHeaders = "content-type;host";
String payload = getBodyString(requestParams);
String hashedRequestPayload = sha256Hex(payload);
String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
// ************* 步骤 2:拼接待签名字符串 *************
String credentialScope = date + "/" + service + "/" + "tc3_request";
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
// ************* 步骤 3:计算签名 *************
byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(StandardCharsets.UTF_8), date);
byte[] secretService = hmac256(secretDate, service);
byte[] secretSigning = hmac256(secretService, "tc3_request");
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
// ************* 步骤 4:拼接 Authorization *************
String authorization = algorithm + " " + "Credential=" + secretId + "/" + credentialScope + ", "
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
//调用腾讯接口
StringBuffer stringBuffer =new StringBuffer();
BufferedReader responseReader = null;
InputStream in1 = null;
// 创建url资源
try {
URL urlClient = new URL(url);
// 建立http连接
HttpsURLConnection conn = (HttpsURLConnection) urlClient.openConnection();
// 设置不用缓存
conn.setUseCaches(false);
// 设置允许输出
conn.setDoOutput(true);
// 设置允许输入
conn.setDoInput(true);
conn.setInstanceFollowRedirects(true);
// 设置传递方式
conn.setRequestMethod(requestMethod);
// 设置维持长连接
conn.setRequestProperty("Connection", "Keep-Alive");
// 设置文件字符集:
conn.setRequestProperty("Charset", "UTF-8");
// 设置文件类型:
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn.setRequestProperty("Authorization", authorization);
conn.setRequestProperty("Host", host);
conn.setRequestProperty("X-TC-Action", action);
conn.setRequestProperty("X-TC-Timestamp", timestamp);
conn.setRequestProperty("X-TC-Version", version);
conn.setRequestProperty("X-TC-Region", region);
// 开始连接请求
conn.connect();
//一定要用BufferedReader 来接收响应, 使用字节来接收响应的方法是接收不到内容的
// utf-8编码
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
out.append(payload);
out.flush();
out.close();
// 请求返回的状态
if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {
System.out.println("连接成功");
// 请求返回的数据
in1 = conn.getInputStream();
String readLine;
responseReader = new BufferedReader(new InputStreamReader(in1,"UTF-8"));
while((readLine=responseReader.readLine()) != null){
stringBuffer.append(readLine);
}
} else {
System.out.println("error++");
}
} catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {
try{
if (null != responseReader){
responseReader.close();
}
if (null != in1){
in1.close();
}
}catch (IOException e){}
}
return stringBuffer.toString();
}
/**
* 请求腾讯API
* @param requestParams
* @param requestMethod
* @return
*/
public static String sendTencentGet(String url, TreeMap<String, Object> requestParams,String requestMethod){
final long t = System.currentTimeMillis();
String result = "";
BufferedReader in = null;
String paramStr = "";
final JSONObject log_info = new JSONObject();
for (final String key : requestParams.keySet()) {
if (!paramStr.isEmpty()) {
paramStr += '&';
}
try {
paramStr = paramStr + key + '=' + URLEncoder.encode(requestParams.get(key).toString(), "utf-8");
} catch (UnsupportedEncodingException e) {
result = "{\"code\":-2300,\"location\":\"com.qcloud.Common.Request:129\",\"message\":\"api sdk throw exception! "
+ e.toString() + "\"}";
} catch (NullPointerException ex) {
out.println("NLL>>" + key);
}
}
try {
if (requestMethod.equals("GET")) {
if (url.indexOf(63) > 0) {
url = url + '&' + paramStr;
} else {
url = url + '?' + paramStr;
}
}
log_info.fluentPut("param", requestParams).fluentPut("url", url);
final String BOUNDARY = "---------------------------"
+ MD5.stringToMD5(String.valueOf(System.currentTimeMillis())).substring(0, 15);
final URL realUrl = new URL(url);
URLConnection connection = null;
if (url.toLowerCase().startsWith("https")) {
final HttpsURLConnection httpsConn = (HttpsURLConnection) (connection = realUrl.openConnection());
} else {
connection = realUrl.openConnection();
}
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.setConnectTimeout(1000);
connection.connect();
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e2) {
result = "{\"code\":-2700,\"location\":\"com.qcloud.Common.Request:225\",\"message\":\"api sdk throw exception! "
+ e2.toString() + "\"}";
try {
if (in != null) {
in.close();
}
} catch (Exception e3) {
result = "{\"code\":-2800,\"location\":\"com.qcloud.Common.Request:234\",\"message\":\"api sdk throw exception! "
+ e3.toString() + "\"}";
}
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e4) {
result = "{\"code\":-2800,\"location\":\"com.qcloud.Common.Request:234\",\"message\":\"api sdk throw exception! "
+ e4.toString() + "\"}";
}
}
log_info.fluentPut("resp", JSON.parse(result)).fluentPut("spk", (System.currentTimeMillis() - t));
System.out.println(log_info.toJSONString());
return result;
}
public static String getBodyString(TreeMap<String, Object> requestParams){
if (requestParams.containsKey("Action")) {
requestParams.remove("Action");
}
if (requestParams.containsKey("Timestamp")) {
requestParams.remove("Timestamp");
}
if (requestParams.containsKey("Version")) {
requestParams.remove("Version");
}
if (requestParams.containsKey("Region")) {
requestParams.remove("Region");
}
if (requestParams.containsKey("Nonce")) {
requestParams.remove("Nonce");
}
if (requestParams.containsKey("SecretId")) {
requestParams.remove("SecretId");
}
JSONObject jsonObject = new JSONObject(requestParams);
return jsonObject.toJSONString();
}
public static String sha256Hex(String s) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] d = md.digest(s.getBytes(StandardCharsets.UTF_8));
return DatatypeConverter.printHexBinary(d).toLowerCase();
}
public static byte[] hmac256(byte[] key, String msg) {
Mac mac = null;
try {
mac = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
try {
mac.init(secretKeySpec);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
}
}
Base64.java
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
public class Base64 {
private static final char[] base64EncodeChars;
private static final byte[] base64DecodeChars;
public static String encode(final byte[] data) {
final StringBuilder sb = new StringBuilder();
final int len = data.length;
int i = 0;
while (i < len) {
final int b1 = data[i++] & 0xFF;
if (i == len) {
sb.append(Base64.base64EncodeChars[b1 >>> 2]);
sb.append(Base64.base64EncodeChars[(b1 & 0x3) << 4]);
sb.append("==");
break;
}
final int b2 = data[i++] & 0xFF;
if (i == len) {
sb.append(Base64.base64EncodeChars[b1 >>> 2]);
sb.append(Base64.base64EncodeChars[(b1 & 0x3) << 4 | (b2 & 0xF0) >>> 4]);
sb.append(Base64.base64EncodeChars[(b2 & 0xF) << 2]);
sb.append("=");
break;
}
final int b3 = data[i++] & 0xFF;
sb.append(Base64.base64EncodeChars[b1 >>> 2]);
sb.append(Base64.base64EncodeChars[(b1 & 0x3) << 4 | (b2 & 0xF0) >>> 4]);
sb.append(Base64.base64EncodeChars[(b2 & 0xF) << 2 | (b3 & 0xC0) >>> 6]);
sb.append(Base64.base64EncodeChars[b3 & 0x3F]);
}
return sb.toString();
}
public static byte[] decode(final String str) throws UnsupportedEncodingException {
final StringBuilder sb = new StringBuilder();
final byte[] data = str.getBytes(StandardCharsets.US_ASCII);
final int len = data.length;
int i = 0;
while (i < len) {
int b1;
do {
b1 = Base64.base64DecodeChars[data[i++]];
} while (i < len && b1 == -1);
if (b1 == -1) {
break;
}
int b2;
do {
b2 = Base64.base64DecodeChars[data[i++]];
} while (i < len && b2 == -1);
if (b2 == -1) {
break;
}
sb.append((char) (b1 << 2 | (b2 & 0x30) >>> 4));
int b3;
do {
b3 = data[i++];
if (b3 == 61) {
return sb.toString().getBytes(StandardCharsets.ISO_8859_1);
}
b3 = Base64.base64DecodeChars[b3];
} while (i < len && b3 == -1);
if (b3 == -1) {
break;
}
sb.append((char) ((b2 & 0xF) << 4 | (b3 & 0x3C) >>> 2));
int b4;
do {
b4 = data[i++];
if (b4 == 61) {
return sb.toString().getBytes(StandardCharsets.ISO_8859_1);
}
b4 = Base64.base64DecodeChars[b4];
} while (i < len && b4 == -1);
if (b4 == -1) {
break;
}
sb.append((char) ((b3 & 0x3) << 6 | b4));
}
return sb.toString().getBytes(StandardCharsets.ISO_8859_1);
}
static {
base64EncodeChars = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '+', '/' };
base64DecodeChars = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
-1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1,
-1, -1 };
}
}
MD5.java
import lombok.extern.slf4j.Slf4j;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
@Slf4j
public class MD5 {
public static String stringToMD5(final String str) {
try {
final byte[] strTemp = str.getBytes();
final MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(strTemp);
return toHexString(mdTemp.digest());
} catch (Exception e) {
return null;
}
}
public static String fileNameToMD5(final String fileName) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(fileName);
return streamToMD5(inputStream);
} catch (Exception e2) {
return null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage(),e);
}
}
}
}
public static String streamToMD5(final InputStream inputStream) {
try {
final MessageDigest mdTemp = MessageDigest.getInstance("MD5");
final byte[] buffer = new byte[1024];
int numRead = 0;
while ((numRead = inputStream.read(buffer)) > 0) {
mdTemp.update(buffer, 0, numRead);
}
return toHexString(mdTemp.digest());
} catch (Exception e) {
return null;
}
}
private static String toHexString(final byte[] md) {
final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
final int j = md.length;
final char[] str = new char[j * 2];
for (int i = 0; i < j; ++i) {
final byte byte0 = md[i];
str[2 * i] = hexDigits[byte0 >>> 4 & 0xF];
str[i * 2 + 1] = hexDigits[byte0 & 0xF];
}
return new String(str);
}
}
Sign.java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.TreeMap;
public class Sign {
public static String sign(final String signStr, final String secret, final String signatureMethod)
throws NoSuchAlgorithmException, InvalidKeyException {
final Mac mac1 = Mac.getInstance("HmacSHA1");
final Mac mac2 = Mac.getInstance("HmacSHA256");
byte[] hash;
if (signatureMethod.equals("HmacSHA256")) {
final SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),
mac2.getAlgorithm());
mac2.init(secretKey);
hash = mac2.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
} else {
final SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),
mac1.getAlgorithm());
mac1.init(secretKey);
hash = mac1.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
}
final String sig = Base64.encode(hash);
return sig;
}
public static String makeSignPlainText(final TreeMap<String, Object> requestParams, final String requestMethod,
final String productDomain,final String productDomainSuffix) {
String retStr = "";
retStr += requestMethod;
retStr += productDomain;
retStr += productDomainSuffix;
retStr += buildParamStr(requestParams, requestMethod);
return retStr;
}
protected static String buildParamStr(final TreeMap<String, Object> requestParams, final String requestMethod) {
String retStr = "";
for (final String key : requestParams.keySet()) {
if(requestParams.get(key)==null) {
continue;
}
final String xx = requestParams.get(key).toString();
if ("POST".equals(requestMethod) && !xx.isEmpty() && xx.substring(0, 1).equals("@")) {
continue;
}
if (retStr.length() == 0) {
retStr += '?';
} else {
retStr += '&';
}
if (requestParams.get(key) == null) {
retStr = retStr + key.replace("_", ".") + '=';
} else {
retStr = retStr + key.replace("_", ".") + '=' + requestParams.get(key).toString();
}
}
return retStr;
}
}