当前位置: 首页 > wzjs >正文

可以做硬件外包项目的网站重庆大渝网

可以做硬件外包项目的网站,重庆大渝网,高端品牌网站建设公司哪家好,腾讯企业邮箱注册申请目录 一、编写目的 二、准备工作 2.1 OCR密钥 三、代码实现 3.1 配置文件 3.2 请求接收封装 3.3 请求响应封装 3.4 服务类参数初始化 3.5 服务类实现 3.6 解析结果 3.7 定义Web接口 四 测试效果 五、总结 欢迎来到盹猫🐱的博客 本篇文章主要介绍了 [百…

目录

一、编写目的

二、准备工作

2.1 OCR密钥

三、代码实现

3.1 配置文件

3.2 请求接收封装

3.3 请求响应封装

 3.4 服务类参数初始化

3.5 服务类实现

3.6 解析结果 

3.7 定义Web接口

四 测试效果

五、总结


欢迎来到盹猫🐱的博客

本篇文章主要介绍了

[百度OCR:证件识别]
❤博主广交技术好友,喜欢文章的可以关注一下❤

一、编写目的

        本篇文章是记录SpringBoot调用百度OCR识别身份证和银行卡信息服务接口的实现步骤,通过测试,识别速度快,识别信息准确。该功能可以用在方便用户认证、注册、用户信息更新等方面,为方便日后使用和查询,在这里对实现流程进行记录,希望可以帮到有需要的开发者。

二、准备工作

2.1 OCR密钥

        可以在OCR文字识别_免费试用_图片转文字-百度AI开放平台 进行账号的注册,如果已经有账号可以直接登录。点击立即使用进入百度控制台,开通[身份证识别]和[银行卡识别]两个功能:

这里有1000次的免费使用,当然付费该功能也很便宜。

        在应用列表功能中,单击创建一个应用,创建一个包含OCR识别功能的应用,当然可以选取全部功能,这样所有功能就都可以使用了。

        在应用列表中复制已创建应用的AppID、APIKey、Secret Key,在后续的application.yml配置文件中需要用到。

 

三、代码实现

3.1 配置文件

        创建一个基础的SpringBoot项目,并在配置文件中将已申请的AppID、APIKey、Secret Key 添加到application.yml文件(没有则在resources目录下进行创建)中,由于百度是通过access_token进行接口调用,在这里将access_token的获取地址和OCR功能请求地址一并配置,具体内容如下:

baidu:app_id: APPIDapi_key: API_KEYsecret_key: SECRET_KEYaccess_token_url: https://aip.baidubce.com/oauth/2.0/tokenocr:base_url: https://aip.baidubce.com/rest/2.0/ocr/v1

3.2 请求接收封装

        要实现的功能是用户可以对请求的识别的实体卡进行指定,同时可以指定识别正面和反面,所以这边先定期请求数据的接收(也就是接收POST的JSON数据),实体内容如下:

package com.uav.models;import com.uav.common.validator.group.UpdateGroup;
import lombok.Data;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;@Data
public class BaiduOcrRequestDTO {/**正反面*/@Pattern(regexp = "^(front|back)$",message = "side 只能是 'front' 或 'back'",groups = UpdateGroup.class) // 可选:分组校验private String side;@NotEmpty(message = "图片url不能为空")private String url;@Pattern(regexp = "^(idcard|bankcard)$",message = "type 只能是 'idcard' 或 'bankcard'",groups = UpdateGroup.class)private String type;
}

3.3 请求响应封装

        返回的数据可能是身份证,也可能是银行卡,所以这边需要定义两个请求响应的封装,内容如下:

银行卡响应

package com.uav.models;import lombok.Data;@Data
public class BankCardDTO {private String validDate;         // 有效期private String bankCardNumber;    // 银行卡号private String bankName;          // 银行名称private int bankCardType;         // 卡类型private String holderName;        // 持卡人姓名
}

身份证响应

package com.uav.models;import lombok.Data;@Data
public class OcrIdCardDTO {private String name;          // 姓名private String nation;        // 民族private String address;       // 住址private String idNumber;      // 公民身份号码private String birthDate;     // 出生日期private String gender;        // 性别// 反面信息private String expiryDate;    // 失效日期private String issuingAuthority; // 签发机关private String issueDate;     // 签发日期
}

 3.4 服务类参数初始化

        因为请求有两个类型,先进行识别类型枚举RecognizeType的定义,它可以在代码编写过程中减少硬编码,增加可维护性,内容如下:

    /*** 支持的识别类型枚举*/public enum RecognizeType {IDCARD("idcard"),BANKCARD("bankcard");private final String type;RecognizeType(String type) {this.type = type;}public String getType() {return type;}/*** 根据类型字符串获取枚举值** @param type 类型字符串* @return 对应的枚举值,如果不存在则抛出异常*/public static RecognizeType fromString(String type) {for (RecognizeType recognizeType : values()) {if (recognizeType.getType().equalsIgnoreCase(type)) {return recognizeType;}}throw new IllegalArgumentException("不支持的识别类型: " + type);}}

        同样的,我们需要用到Http请求,这里使用OKhttpClient进行请求,同时将之前定义的参数通过@Value进行注入,内容如下:

@Value("${baidu.api_key}")private String API_KEY;@Value("${baidu.secret_key}")private String SECRET_KEY;@Value("${baidu.access_token_url}")private String ACCESS_TOKEN_URL;@Value("${baidu.ocr.base_url}")private String ORC_BASE_URL;// 使用 final 确保线程安全,并在 @PostConstruct 中初始化private OkHttpClient httpClient;/*** 初始化 OkHttpClient 实例*/@PostConstructpublic void init() {httpClient = new OkHttpClient.Builder().readTimeout(300, TimeUnit.SECONDS).build();}

3.5 服务类实现

        在服务类的实现时,需要先获取百度的access_token然后进行OCR接口的请求,所以这里先定义一个获取access_token的方法,内容如下:

    private String getAccessToken() throws IOException {RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"),"grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY);Request request = new Request.Builder().url(ACCESS_TOKEN_URL).post(body).addHeader("Content-Type", "application/x-www-form-urlencoded").build();try (Response response = httpClient.newCall(request).execute()) {if (!response.isSuccessful()) {log.error("获取访问令牌失败,状态码: {}, 响应: {}", response.code(), response.body() != null ? response.body().string() : "null");throw new SysException("获取访问令牌失败,状态码: " + response.code());}String responseBody = Objects.requireNonNull(response.body()).string();JSONObject jsonResponse = JSON.parseObject(responseBody);if (!jsonResponse.containsKey("access_token")) {log.error("访问令牌响应中缺少 access_token 字段: {}", responseBody);throw new SysException("访问令牌响应格式错误");}return jsonResponse.getString("access_token");} catch (Exception e) {log.error("获取访问令牌过程中发生错误", e);throw new SysException("获取访问令牌失败,请重试!", e);}}

        然后开始编写识别图片方法,该方法的接收参数为一个请求封装的参数,即上面定义的BaiduOcrRequestDTO,内容如下:

    @Overridepublic Object recognizeImage(BaiduOcrRequestDTO requestDTO) throws IOException {try {// 获取访问令牌String accessToken = getAccessToken();// 构建请求 URL 和 BodyString requestUrl = buildRequestUrl(requestDTO.getType(), accessToken);String bodyContent = buildRequestBody(requestDTO);RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), bodyContent);// 构建请求Request request = new Request.Builder().url(requestUrl).post(body).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Accept", "application/json").build();// 发送请求并获取响应Response response = httpClient.newCall(request).execute();if (!response.isSuccessful()) {log.error("OCR 请求失败,状态码: {}, 响应: {}", response.code(), response.body() != null ? response.body().string() : "null");throw new SysException("OCR 请求失败,状态码: " + response.code());}String result = Objects.requireNonNull(response.body()).string();log.debug("OCR 响应结果: {}", result);// 解析结果return new OcrParser().parseCardInfo(result, requestDTO.getType(), requestDTO.getSide());} catch (Exception e) {log.error("OCR 识别过程中发生错误,请求数据: {}", requestDTO, e);throw new SysException("OCR 识别失败,请重试!", e);}}

3.6 解析结果 

        百度OCR返回的为json字符串,但是其中有很多并不需要的信息,这样返回到前端并不利用阅读和解析,同时占用大量带宽,所以这里使用自定义的OcrParser 工具类对响应的数据进行解析,将其转换为上面提到的请求响应参数格式,内容如下:

package com.uav.common.util;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.uav.common.exception.SysException;
import com.uav.models.BankCardDTO;
import com.uav.models.OcrIdCardDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;/*** OCR 解析工具类,用于解析身份证和银行卡信息。*/
@Slf4j
public class OcrParser {/*** 识别类型枚举*/public enum CardType {IDCARD("idcard"),BANKCARD("bankcard");private final String type;CardType(String type) {this.type = type;}public String getType() {return type;}/*** 根据类型字符串获取枚举值** @param type 类型字符串* @return 对应的枚举值,如果不存在则抛出异常*/public static CardType fromString(String type) {for (CardType cardType : values()) {if (cardType.getType().equalsIgnoreCase(type)) {return cardType;}}throw new IllegalArgumentException("不支持的识别类型: " + type);}}/*** 解析卡片信息** @param cardJson JSON 字符串* @param type     识别类型("idcard" 或 "bankcard")* @param side     仅对身份证有效,"front" 表示正面,其他表示反面* @return 解析后的 DTO 对象* @throws SysException 如果解析失败*/public Object parseCardInfo(String cardJson, String type, String side) {try {JSONObject root = JSON.parseObject(cardJson);CardType cardType = CardType.fromString(type);switch (cardType) {case IDCARD:return parseIdCardInfo(root, side);case BANKCARD:return parseBankCardInfo(root);default:throw new SysException("不支持的识别类型: " + type);}} catch (IllegalArgumentException e) {throw new SysException("不支持的识别类型: " + type, e);} catch (Exception e) {log.error("解析卡片信息失败,JSON: {}, 类型: {}, 方向: {}", cardJson, type, side, e);throw new SysException("识别解析格式错误,请重新尝试!", e);}}/*** 解析身份证信息** @param root JSON 根对象* @param side "front" 表示正面,其他表示反面* @return OcrIdCardDTO 对象* @throws SysException 如果解析失败*/private OcrIdCardDTO parseIdCardInfo(JSONObject root, String side) throws SysException {JSONObject wordsResult = root.getJSONObject("words_result");if (wordsResult == null) {throw new SysException("JSON 中缺少 'words_result' 字段");}OcrIdCardDTO idCardInfo = new OcrIdCardDTO();if (StringUtils.equalsIgnoreCase(side, "front")) {parseFrontSide(wordsResult, idCardInfo);} else {parseBackSide(wordsResult, idCardInfo);}return idCardInfo;}/*** 解析身份证正面信息** @param wordsResult JSON 中的 words_result 对象* @param idCardInfo  目标 DTO 对象* @throws SysException 如果解析失败*/private void parseFrontSide(JSONObject wordsResult, OcrIdCardDTO idCardInfo) throws SysException {try {idCardInfo.setName(getWord(wordsResult, "姓名"));idCardInfo.setNation(getWord(wordsResult, "民族"));idCardInfo.setAddress(getWord(wordsResult, "住址"));idCardInfo.setIdNumber(getWord(wordsResult, "公民身份号码"));idCardInfo.setBirthDate(getWord(wordsResult, "出生"));idCardInfo.setGender(getWord(wordsResult, "性别"));} catch (Exception e) {throw new SysException("解析身份证正面信息失败", e);}}/*** 解析身份证反面信息** @param wordsResult JSON 中的 words_result 对象* @param idCardInfo  目标 DTO 对象* @throws SysException 如果解析失败*/private void parseBackSide(JSONObject wordsResult, OcrIdCardDTO idCardInfo) throws SysException {try {idCardInfo.setExpiryDate(getWord(wordsResult, "失效日期"));idCardInfo.setIssuingAuthority(getWord(wordsResult, "签发机关"));idCardInfo.setIssueDate(getWord(wordsResult, "签发日期"));} catch (Exception e) {throw new SysException("解析身份证反面信息失败", e);}}/*** 安全地从 words_result 中获取指定字段的 words 值** @param wordsResult JSON 中的 words_result 对象* @param fieldName   字段名称* @return 对应的 words 值* @throws SysException 如果字段不存在或解析失败*/private String getWord(JSONObject wordsResult, String fieldName) throws SysException {JSONObject field = wordsResult.getJSONObject(fieldName);if (field == null) {throw new SysException("缺少字段: " + fieldName);}String words = field.getString("words");if (StringUtils.isBlank(words)) {throw new SysException("字段 '" + fieldName + "' 的 words 值为空");}return words;}/*** 解析银行卡信息** @param root JSON 根对象* @return BankCardDTO 对象* @throws SysException 如果解析失败*/private BankCardDTO parseBankCardInfo(JSONObject root) throws SysException {try {JSONObject result = root.getJSONObject("result");if (result == null) {throw new SysException("JSON 中缺少 'result' 字段");}BankCardDTO bankCardDTO = new BankCardDTO();bankCardDTO.setValidDate(result.getString("valid_date"));bankCardDTO.setBankCardNumber(result.getString("bank_card_number"));bankCardDTO.setBankName(result.getString("bank_name"));bankCardDTO.setBankCardType(result.getInteger("bank_card_type"));bankCardDTO.setHolderName(result.getString("holder_name"));// 可选:对银行卡号进行脱敏处理if (StringUtils.isNotBlank(bankCardDTO.getBankCardNumber())) {bankCardDTO.setBankCardNumber(bankCardDTO.getBankCardNumber());}return bankCardDTO;} catch (Exception e) {throw new SysException("解析银行卡信息失败", e);}}/*** 对银行卡号进行脱敏处理** @param cardNumber 原始银行卡号* @return 脱敏后的银行卡号*/private String maskBankCardNumber(String cardNumber) {if (StringUtils.isBlank(cardNumber)) {return cardNumber;}// 假设银行卡号为 16-19 位,保留前4位和后4位,中间用 * 替换int length = cardNumber.length();if (length <= 8) {return "****"; // 如果长度不足,返回固定脱敏}return cardNumber.substring(0, 4) + "****" + cardNumber.substring(length - 4);}
}

3.7 定义Web接口

        定义一个OcrController接口,对前端页面发送的数据进行响应,直接调用已编写好的识别服务,内容如下:

package com.uav.controller.ocr;import com.uav.common.util.Result;
import com.uav.common.validator.ValidatorUtils;
import com.uav.common.validator.group.UpdateGroup;
import com.uav.models.BaiduOcrRequestDTO;
import com.uav.service.OcrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.*;@RequestMapping("/ocr")
@RestController
public class OcrController {@AutowiredOcrService ocrService;@PostMapping(value = "/idcard/recognize")public Result<Object> recognizeImage(@RequestBody BaiduOcrRequestDTO requestDTO) throws IOException {ValidatorUtils.validateEntity(requestDTO, UpdateGroup.class);return new Result<>().ok(ocrService.recognizeImage(requestDTO));}}

四 测试效果

        使用Apifox测试一下接口,效果图如下:

五、总结

        上述内容即为百度OCR:证件识别的全部过程了,虽然百度官方也有API示例代码,但上述代码对数据进行了更好的解析和封装。如果你需要身份证和银行卡信息识别,可以直接拿来使用。希望可以帮到你。

如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链

感谢您的关注和收藏!!!!!!

        

http://www.dtcms.com/wzjs/791615.html

相关文章:

  • 怎么做服务网站宁波房产信息网
  • 杭州网站运营微信平台免费小程序制作
  • 网站顶部布局济南网络电视台
  • me域名网站正规的网站制作在哪里
  • 公司网站建设与维护工作计划新泰网站建设方案
  • 企业网站怎么做seo优化江苏省义务教育标准化建设网站
  • 做市场调查的网站素材网站怎么推广
  • 内蒙古自治区建设厅官方网站wordpress php5.3.5
  • 公司高端网站建网站建设公司的性质
  • 中国建设监理协会网站个人会员系统栏wordpress讨论吧
  • shanxi建设银行网站首页提升网站速度
  • 编写 网站 语言wordpress上传图片后台目录
  • 网站设网页设计wordpress主题位置
  • 做家教网站要多少钱百度问问
  • 桃城区网站制作公司建网站 温州
  • 余姚建设网站公司政务网站建设的方向
  • 提供微信网站建设航达建设集团有限公司网站
  • kkday是哪里做的网站教育机构logo
  • 中国最大的博客网站电商网站开发 参考文献
  • 南京营销型网站泰州seo
  • 如何免费建设一个网站河北石家庄网络公司
  • 农家乐网站模板浙江省品牌建设联合会网站
  • 湖北省建设厅网站证件wordpress 自带模板
  • 深圳营销型网站推广上海建设网站费用
  • 那个网站可以做ppt赚钱wordpress主页分栏
  • 合肥网站优化技术哪些网站做问卷可以赚钱
  • 服务器 无法访问网站宝安网
  • 时尚字体设计网站可信的手机网站建设
  • 云南省建设厅网站舉報WordPress手机上传图片
  • 夜间正能量不良网站沈阳免费做网站