对接百度OCR发票识别功能

对接百度OCR

怎么对接百度OCR平台?

  1. 对接开放平台首先需要阅读api文档:->百度OCR-API文档地址, 按照文档操作看起来是不是特别的简单了,如果你需要在你的项目中使用的话你需要申请一个app应用才能开展后面的工作,申请app应用的地址:–>百度OCR-申请app应用地址
  • 申请app应用
    在这里插入图片描述
    按照操作指引一步一步的操作,一定要先领取,不然的接口调用的时候会受限制;创建好应用后你会得到appkey和SecretKey这两个保存好.
    在这里插入图片描述

springboot + OCR

下面我们从项目中具体操作springboot整合OCR实现发票的识别和发票的验真等接口测试;

  • 首先我们引入所需要的依赖
		<!-- 对接百度发票识别接口 -->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.16.5</version>
        </dependency>


        <!--  httpclient  -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

        <!--  httpcore  -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.5</version>
        </dependency>
  • 编写一个http请求调用的工具类
package com.sq.ws.order.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: swang
 * @Date: 2022/10/11 下午8:16
 * http请求工具类
 */
@Slf4j
public class HttpUtils {

    private static HttpClient httpClient;

    static {
        httpClient = getHttpClient();
    }


    public static String post(String requestUrl, String accessToken, String params)
            throws Exception {
        String contentType = "application/x-www-form-urlencoded";
        return HttpUtils.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 HttpUtils.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 HttpUtils.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();
        return result;
    }


    /**
     * 微信统一下单接口发送post请求
     *
     * @param url        发送请求的URL
     * @param requestXml map转换xml的报文
     * @return 所代表远程资源的响应结果
     */
    public static String doPost(String url, String requestXml) {
        CloseableHttpClient httpClient;
        CloseableHttpResponse httpResponse;
        // 创建httpClient连接对象
        httpClient = HttpClients.createDefault();
        // 创建post请求连接对象
        HttpPost httpPost = new HttpPost(url);
        // 创建连接请求对象,并设置连接参数
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(15000)   // 连接服务区主机超时时间
                .setConnectionRequestTimeout(60000) // 连接请求超时时间
                .setSocketTimeout(60000).build(); // 设置读取响应数据超时时间
        // 为httppost请求设置参数
        httpPost.setConfig(requestConfig);
        // 将上传参数放到entity属性中
        httpPost.setEntity(new StringEntity(requestXml, "UTF-8"));
        // 添加头信息
        httpPost.addHeader("Content-type", "text/xml");
        String result = "";
        try {
            // 发送请求
            httpResponse = httpClient.execute(httpPost);
            // 从相应对象中获取返回内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        return sendGet(url, param, "UTF-8");
    }

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url         发送请求的 URL
     * @param param       请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @param contentType 编码类型
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param, String contentType) {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection 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.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception ex) {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            log.info("sendPost - {}", url);
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            log.info("recv - {}", result);
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    public static String sendSSLPost(String url, String param) {
        StringBuilder result = new StringBuilder();
        String urlNameString = url + "?" + param;
        try {
            log.info("sendSSLPost - {}", urlNameString);
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
            URL console = new URL(urlNameString);
            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String ret;
            while ((ret = br.readLine()) != null) {
                if (!"".equals(ret.trim())) {
                    result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
                }
            }
            log.info("recv - {}", result);
            conn.disconnect();
            br.close();
        } catch (ConnectException e) {
            log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
        } catch (SocketTimeoutException e) {
            log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        } catch (IOException e) {
            log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
        } catch (Exception e) {
            log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
        }
        return result.toString();
    }

    /**
     * Http Get请求 请求地址
     *
     * @param url    Get参数
     * @param params 编码
     * @param encode 返回请求结果
     */
    public static String sendGetRequest(String url, Map<String, String> params, String encode) {
        String result = null;
        try {
            HttpGet httpGet;
            if (null == params) {
                httpGet = new HttpGet(url);
            } else {
                httpGet = new HttpGet(url + dealGetParams(params, encode));
            }
            HttpResponse response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result != null ? result : "";
    }

    public static String sendGetRequest(String url, Map<String, String> params) {
        return sendGetRequest(url, params, "UTF-8");
    }

    public static String sendGetRequest(String url) {
        return sendGetRequest(url, null, "UTF-8");
    }

    public static String sendGetRequestGB2312(String url) {
        return sendGetRequest(url, null, "GB2312");
    }

    /**
     * POST请求 返回请求结果 HashMap键值参数
     */
    @SuppressWarnings({"unchecked"})
    public static String sendPostRequest(String url, String header, Object params, String encode) throws Exception {
        String resultStr = null;
        HttpPost httpPost = new HttpPost(url);
        if (params != null) {
            StringEntity entity;
            if (params instanceof Map) {
                entity = new StringEntity(dealPostParams((HashMap<String, String>) params, encode));
            } else if (params instanceof String) {
                entity = new StringEntity((String) params, encode);
            } else if (params instanceof List) {
                entity = new UrlEncodedFormEntity((List<? extends NameValuePair>) params, encode);
            } else {
                throw new Exception("参数有误!");
            }
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Client-Sign", header);
            httpPost.setEntity(entity);
        }
        try {
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                resultStr = EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultStr;
    }

    public static String sendPostRequest(String url, String header) throws Exception {
        return sendPostRequest(url, header, "");
    }

    /**
     * 键值对请求 默认UTF-8编码
     */
    public static String sendPostRequest(String url, String header, Map<String, String> params) throws Exception {
        return sendPostRequest(url, header, params, "UTF-8");
    }

    /**
     * String 默认UTF-8编码
     */
    public static String sendPostRequest(String url, String header, String params) throws Exception {
        return sendPostRequest(url, header, params, "UTF-8");
    }

    /**
     * 键值对请求 默认UTF-8编码
     */
    public static String sendPostRequest(String url, String header, List<NameValuePair> params) throws Exception {
        return sendPostRequest(url, header, params, "UTF-8");
    }

    /**
     * 处理Get方式请求的URL
     */
    private static String dealGetParams(Map<String, String> params, String enc) throws UnsupportedEncodingException {
        StringBuffer sb = new StringBuffer();
        sb.append("?");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            // 参数名=参数&参数名=参数
            sb.append(entry.getKey()).append("=")
                    .append(URLEncoder.encode(entry.getValue(), enc))
                    .append("&");
        }
        // 删除最后一个&
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    /**
     * 处理POST请求URL
     */
    private static String dealPostParams(Map<String, String> params, String enc) {
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            try {
                sb.append(entry.getKey()).append("=")
                        .append(URLEncoder.encode(entry.getValue(), enc))
                        .append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    /**
     * 获取HttpClient
     */
    @SuppressWarnings("deprecation")
    public static synchronized HttpClient getHttpClient() {
        if (null == httpClient) {
            httpClient = new DefaultHttpClient();
        }
        return httpClient;
    }

    private static class TrustAnyTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }

    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

}
  • 首先我们先获取授权token,直接上代码;
public class BaiDuApi {

    private static final Logger logger = LoggerFactory.getLogger(BaiDuApi.class);

   
    private static String API_KEY = "你申请的appkey";

    private static String SECRET_KEY = "你申请的SECRET_KEY";

	// 这里我简单的测试,你可以将获取的token信息根据返回的过期时间存储到redis中,避免每次请求都调去接口获取token影响效率
	public static String getAccessToken() {

        String token_url = "https://aip.baidubce.com/oauth/2.0/token";
        Map<String, String> params = new HashMap<>();
        params.put("grant_type", "client_credentials");
        params.put("client_id", API_KEY);
        params.put("client_secret", SECRET_KEY);

        try {
            String result = HttpUtils.sendGet(token_url, appendParams(params));
            System.out.println(result);
            ObjectMapper objectMapper = new ObjectMapper();
            ResultToken resultToken = objectMapper.readValue(result, ResultToken.class);
            return resultToken.getAccess_token();
        }catch (Exception e) {
            logger.error(" 获取百度OCR授权失败:{} ", e.getMessage());
        }
        return null;
    }
}

@Data
class ResultToken{

    private String refresh_token;

    private Long expires_in;

    private String session_key;

    private String access_token;

    private String scope;

    private String session_secret;

}

这样就可以获取请求的token了,代码我已经测试过了,可以自行测试;

  • 发票识别接口
// 发票识别
    public static String invoiceSb() {

        String invoiceUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice";
        try {
            String filePath = "/Users/wangshuai/img/47.jpeg";
            byte[] imgData = FileUtil.readFileByBytes(filePath);
            String imgStr = Base64Util.encode(imgData);
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");
            String param = "image=" + imgParam;

            logger.info(" 请求的url:{} ", invoiceUrl);
            String result = HttpUtils.sendPost(requestAppendToken(invoiceUrl), param);
            ObjectMapper objectMapper = new ObjectMapper();
            Map invoiceResponse = objectMapper.readValue(result, Map.class);
            logger.info(" 返回的结果信息:{} ", invoiceResponse);
        }catch (Exception e) {
            logger.info(e.getMessage());
        }
        return null;
    }


    // 请求拼接token
    private static String requestAppendToken(String reqUrl) {
        return reqUrl+"?access_token=" + getAccessToken();
    }
  • 发票验真接口
// 发票验真
    public static String invoiceCheck(Map<String, String> params) {

        String checkUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice_verification";
        try {
            String result = HttpUtils.sendPost(requestAppendToken(checkUrl), appendParams(params));
            ObjectMapper objectMapper = new ObjectMapper();
            Map readValue = objectMapper.readValue(result, Map.class);
            logger.info(" 获取发票验证结果:{} ", readValue);
        }catch (Exception e) {
            logger.error(" 发票验证异常:{} ", e.getMessage());
        }
        return null;
    }

	// 请求拼接token
    private static String requestAppendToken(String reqUrl) {
        return reqUrl+"?access_token=" + getAccessToken();
    }

    // 参数拼接 name=admin&pwd=123 这种格式
    private static String appendParams(Map<String, String> params) {

        StringBuffer str = new StringBuffer();
        if(params.size() > 0) {
            for (Map.Entry entry : params.entrySet()) {
                str.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            str.deleteCharAt(str.length() -1);
        }

        System.out.println("请求参数打印 ="+str.toString());
        return str.toString();
    }

springboot对接百度OCR分享就到这里了,有什么问题欢迎在评论区留言! 有什么不足的地方希望大家给出宝贵建议!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值