zoukankan      html  css  js  c++  java
  • 百度ocr接口,Future限制调用的响应时间

    一、百度提供的工具类

    1.HttpUtil

    package com.baidu.ai.aip.utils;
    
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.List;
    import java.util.Map;
    
    /**
     * http 工具类
     */
    public class HttpUtil {
    
        public static String post(String requestUrl, String accessToken, String params)
                throws Exception {
            String contentType = "application/x-www-form-urlencoded";
            return HttpUtil.post(requestUrl, accessToken, contentType, params);
        }
    
        public static String post(String requestUrl, String accessToken, String contentType, String params)
                throws Exception {
            String encoding = "UTF-8";
            if (requestUrl.contains("nlp")) {
                encoding = "GBK";
            }
            return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
        }
    
        public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
                throws Exception {
            String url = requestUrl + "?access_token=" + accessToken;
            return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
        }
    
        public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
                throws Exception {
            URL url = new URL(generalUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            // 设置通用的请求属性
            connection.setRequestProperty("Content-Type", contentType);
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setUseCaches(false);
            connection.setDoOutput(true);
            connection.setDoInput(true);
    
            // 得到请求的输出流对象
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.write(params.getBytes(encoding));
            out.flush();
            out.close();
    
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> headers = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : headers.keySet()) {
                System.err.println(key + "--->" + headers.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = null;
            in = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), encoding));
            String result = "";
            String getLine;
            while ((getLine = in.readLine()) != null) {
                result += getLine;
            }
            in.close();
            System.err.println("result:" + result);
            return result;
        }
    }
    View Code

    2.FileUtil

    package com.baidu.ai.aip.utils;
    
    import java.io.*;
    
    /**
     * 文件读取工具类
     */
    public class FileUtil {
    
        /**
         * 读取文件内容,作为字符串返回
         */
        public static String readFileAsString(String filePath) throws IOException {
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            } 
    
            if (file.length() > 1024 * 1024 * 1024) {
                throw new IOException("File is too large");
            } 
    
            StringBuilder sb = new StringBuilder((int) (file.length()));
            // 创建字节输入流  
            FileInputStream fis = new FileInputStream(filePath);  
            // 创建一个长度为10240的Buffer
            byte[] bbuf = new byte[10240];  
            // 用于保存实际读取的字节数  
            int hasRead = 0;  
            while ( (hasRead = fis.read(bbuf)) > 0 ) {  
                sb.append(new String(bbuf, 0, hasRead));  
            }  
            fis.close();  
            return sb.toString();
        }
    
        /**
         * 根据文件路径读取byte[] 数组
         */
        public static byte[] readFileByBytes(String filePath) throws IOException {
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException(filePath);
            } else {
                ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
                BufferedInputStream in = null;
    
                try {
                    in = new BufferedInputStream(new FileInputStream(file));
                    short bufSize = 1024;
                    byte[] buffer = new byte[bufSize];
                    int len1;
                    while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
                        bos.write(buffer, 0, len1);
                    }
    
                    byte[] var7 = bos.toByteArray();
                    return var7;
                } finally {
                    try {
                        if (in != null) {
                            in.close();
                        }
                    } catch (IOException var14) {
                        var14.printStackTrace();
                    }
    
                    bos.close();
                }
            }
        }
    }
    View Code

    3.Base64Util

    package com.baidu.ai.aip.utils;
    
    /**
     * Base64 工具类
     */
    public class Base64Util {
        private static final char last2byte = (char) Integer.parseInt("00000011", 2);
        private static final char last4byte = (char) Integer.parseInt("00001111", 2);
        private static final char last6byte = (char) Integer.parseInt("00111111", 2);
        private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
        private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
        private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
        private static final char[] encodeTable = 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', '+', '/'};
    
        public Base64Util() {
        }
    
        public static String encode(byte[] from) {
            StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);
            int num = 0;
            char currentByte = 0;
    
            int i;
            for (i = 0; i < from.length; ++i) {
                for (num %= 8; num < 8; num += 6) {
                    switch (num) {
                        case 0:
                            currentByte = (char) (from[i] & lead6byte);
                            currentByte = (char) (currentByte >>> 2);
                        case 1:
                        case 3:
                        case 5:
                        default:
                            break;
                        case 2:
                            currentByte = (char) (from[i] & last6byte);
                            break;
                        case 4:
                            currentByte = (char) (from[i] & last4byte);
                            currentByte = (char) (currentByte << 2);
                            if (i + 1 < from.length) {
                                currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);
                            }
                            break;
                        case 6:
                            currentByte = (char) (from[i] & last2byte);
                            currentByte = (char) (currentByte << 4);
                            if (i + 1 < from.length) {
                                currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);
                            }
                    }
    
                    to.append(encodeTable[currentByte]);
                }
            }
    
            if (to.length() % 4 != 0) {
                for (i = 4 - to.length() % 4; i > 0; --i) {
                    to.append("=");
                }
            }
    
            return to.toString();
        }
    }
    View Code

    4.GsonUtils

    /*
     * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
     */
    package com.baidu.ai.aip.utils;
    
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonParseException;
    
    import java.lang.reflect.Type;
    
    /**
     * Json工具类.
     */
    public class GsonUtils {
        private static Gson gson = new GsonBuilder().create();
    
        public static String toJson(Object value) {
            return gson.toJson(value);
        }
    
        public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {
            return gson.fromJson(json, classOfT);
        }
    
        public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
            return (T) gson.fromJson(json, typeOfT);
        }
    }
    View Code

    二、ocr接口调用

    import com.alibaba.fastjson.JSON;import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiParam;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URLEncoder;
    import java.util.Calendar;
    import java.util.concurrent.*;
    
    @Slf4j
    @RestController
    @RequestMapping(value = "api/ocr")
    @Api(value = "百度ocr接口", description = "百度ocr接口")
    public class BaiDuOcrController {
    
    
        @Autowired
        private BaiduOcrToken ocr;
    
        private JSONObject auth;
        private long expireDate;
        private int limitTime = 5700;
    
    
       /* @PostConstruct
        public void initOcrToken() {
            initOcrAuth();
        }*/
    
        /**
         * 初次调用或已经过期,初始化百度ocr调用权限
         */
        public void initOcrAuth() {
            log.info("初次调用或已经过期,初始化百度ocr调用权限Accesstoken开始");
            auth = getAuth(ocr.getClientId(), ocr.getClientSecret());
            log.info("初始化百度ocr调用权限Accesstoken成功 : 
    " + auth);
    
            String expiresIn = auth.getString("expires_in");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, Integer.valueOf(expiresIn));
    
            expireDate = calendar.getTimeInMillis();
            log.info("初始化百度ocr调用权限Accesstoken成功,过期时间 ======= " + expireDate);
        }
    
    
        /**
         * 获取API访问token
         * 该token有一定的有效期,需要自行管理,当失效时需重新获取.
         * @param ak - 百度云官网获取的 API Key
         * @param sk - 百度云官网获取的 Securet Key
         * @return assess_token 示例:
         * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
         */
        public JSONObject getAuth(String ak, String sk) {
            // 获取token地址
            String authHost = ocr.getOcrAuthApi();
            String getAccessTokenUrl = authHost
                    // 1. grant_type为固定参数
                    + "grant_type=client_credentials"
                    // 2. 官网获取的 API Key
                    + "&client_id=" + ak
                    // 3. 官网获取的 Secret Key
                    + "&client_secret=" + sk;
            try {
                // 打开和URL之间的连接
                HttpURLConnection connection = FileHelper.getHttpURLConnection(getAccessTokenUrl);
                connection.setRequestMethod("POST");
                connection.connect();
    
                // 定义 BufferedReader输入流来读取URL的响应
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String result = "";
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
                /* 返回结果 */
                JSONObject jo = JSON.parseObject(result);
                return jo;
            } catch (Exception e) {
                log.error("获取百度ocr访问权限token失败!", e);
            }
            return null;
        }
    
    
        @RequestMapping(value = "auth", method = RequestMethod.GET)
        public Result<Boolean> ocrAccessToken() {
    
            if(expireDate == 0 || System.currentTimeMillis() >= expireDate) {
                initOcrAuth();
            }
    
            return Result.success().result(true);
        }
    
    
        @RequestMapping(value = "idcard", method = RequestMethod.POST)
        public Result<String> idcard(@ApiParam(value = "front:身份证含照片的一面;back:身份证带国徽的一面") String idCardSide,
                                     @ApiParam(value = "身份证url地址")String imgUrl) throws Exception {
    
            Future<String> future = null;
            try {
    
                future = ConcurrentUtil.getThreadPool().submit( () -> {
                    byte[] imgData = FileHelper.readBytesByUrl(imgUrl);
                    String imgStr = Base64Util.encode(imgData);
                    String imgParam = URLEncoder.encode(imgStr, "UTF-8");
    
                    String param = "id_card_side=" + idCardSide + "&image=" + imgParam + "&detect_direction=true";
    
                    // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                    String accessToken = auth.getString("access_token");
    
                    String result = HttpUtil.post(ocr.getIdcardApi(), accessToken, param);
    
                    return result;
                });
    
                String result = future.get(limitTime, TimeUnit.MILLISECONDS);
    
                return Result.success().result(result);
    
            } catch (Exception  e) {
                if(future != null)
                    future.cancel(true);
                log.error("身份证识别失败, url为 : {}", imgUrl);
                throw e;
            }
        }
    
    
        @RequestMapping(value = "bankCard", method = RequestMethod.POST)
        public Result<String> bankCard(@ApiParam(value = "银行卡url地址") String imgUrl) throws Exception {
    
            Future<String> future = null;
            try {
    
                future = ConcurrentUtil.getThreadPool().submit( () -> {
    
                    byte[] imgData = FileHelper.readBytesByUrl(imgUrl);
                    String imgStr = Base64Util.encode(imgData);
                    String imgParam = URLEncoder.encode(imgStr, "UTF-8");
    
                    String param = "image=" + imgParam;
    
                    // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                    String accessToken = auth.getString("access_token");
    
                    String result = HttpUtil.post(ocr.getBankcardApi(), accessToken, param);
    
                    return result;
                });
    
                String result = future.get(limitTime, TimeUnit.MILLISECONDS);
    
                return Result.success().result(result);
    
            } catch (Exception  e) {
                if(future != null)
                    future.cancel(true);
                log.error("银行卡识别失败, url为 : {}", imgUrl);
                throw e;
            }
        }
    
    
        @RequestMapping(value = "businessLicense", method = RequestMethod.POST)
        public Result businessLicense(@ApiParam(value = "营业执照url地址") String imgUrl) throws Exception {
    
            Future<String> future = null;
            try {
    
    
                /*Callable<String> callable = new Callable<String>() {
                    @Override
                    public String call() throws Exception {
    
                        return "";
                    }
                };
    
                FutureTask<String> futureTask = new FutureTask<>(callable);*/
    
    
                future = ConcurrentUtil.getThreadPool().submit( () -> {
    
                    byte[] imgData = FileHelper.readBytesByUrl(imgUrl);
                    String imgStr = Base64Util.encode(imgData);
                    String imgParam = URLEncoder.encode(imgStr, "UTF-8");
    
                    String param = "image=" + imgParam + "&detect_direction=true";//&accuracy=high";
    
                    // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                    String accessToken = auth.getString("access_token");
    
                    String result = HttpUtil.post(ocr.getLicenseApi(), accessToken, param);
                    return result;
                });
                //加上前端请求时间限制在6s,超过强制返回结果,取消识别
                String result = future.get(limitTime, TimeUnit.MILLISECONDS);
    
                return Result.success().result(result);
    
            } catch (Exception  e) {
                if(future != null)
                    future.cancel(true);
                log.error("营业执照识别失败, url为 : {}", imgUrl);
                throw e;
            }
        }
    
        @RequestMapping(value = "words", method = RequestMethod.POST)
        public Result words(String imgUrl) throws Exception {
    
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general";
    
            String param = "url=" + imgUrl + "&detect_direction=true";
            // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
            String accessToken = auth.getString("access_token");
    
            String result = HttpUtil.post("https://aip.baidubce.com/rest/2.0/ocr/v1/general", accessToken, param);
    
            return Result.success().result(result);
        }
    
    }

    根据url读取图片内容:

    HttpURLConnection -> conn.getContentLength();图片内容长度
    /**
         * 根据ali oss url读取文件字节
         * @param imgUrl
         * @return
         * @throws IOException
         */
        public static byte[] readBytesByUrl(String imgUrl) throws IOException {
    
            String limitUrl = FileHelper.limit500KbImgUrl(imgUrl);
            HttpURLConnection conn = FileHelper.getHttpURLConnection(limitUrl);
            InputStream ins = FileHelper.getInputStreaFromConnection(conn);
    
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            BufferedInputStream bis;
    
            try {
                bis = new BufferedInputStream(ins);
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len1;
                while (-1 != (len1 = bis.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len1);
                }
    
                byte[] bytes = bos.toByteArray();
                return bytes;
            } finally {
                try {
                    if (ins != null) {
                        ins.close();
                    }
                } catch (IOException var14) {
                    ;
                }
    
                bos.close();
            }
        }

    ……

     百度api地址

    JAVA Future类详解

    详解Java中的Future、FutureTask的原理以及与线程池的搭配使用

    .

  • 相关阅读:
    程序员的7中武器
    需要强化的知识
    微软中国联合小i推出MSN群Beta 不需任何插件
    XML Notepad 2006 v2.0
    Sandcastle August 2006 Community Technology Preview
    [推荐] TechNet 广播 SQL Server 2000完结篇
    《太空帝国 4》(Space Empires IV)以及 xxMod 英文版 中文版 TDM Mod 英文版 中文版
    IronPython 1.0 RC2 更新 1.0.60816
    Microsoft .NET Framework 3.0 RC1
    《Oracle Developer Suite 10g》(Oracle Developer Suite 10g)V10.1.2.0.2
  • 原文地址:https://www.cnblogs.com/foolash/p/12168251.html
Copyright © 2011-2022 走看看