springcloud阿里云OCR(个人证照)识别对接

由于项目要用到实名认证功能,因此OCR识别是前提,我们是用的阿里云的OCR,首先需要在阿里云上面开通OCR功能

开通地址:https://ocr.console.aliyun.com/overview

然后就是写后端接口:

首先是pom依赖:

java 复制代码
 <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>ocr_api20210707</artifactId>
            <version>3.1.3</version>
        </dependency>

接口层:

java 复制代码
    /**
     * ocr识别
     *
     * @param bytes
     * @param originalFilename
     * @return
     */
    AppMemberUserOcrRespVO ocrIdentify(byte[] bytes, String originalFilename);

接口实现:

java 复制代码
    @Value("${aliyun.appId}")
    private String accessKeyId;

    @Value("${aliyun.appSecret}")
    private String accessKeySecret;

    private static final String END_POINT = "ocr-api.cn-hangzhou.aliyuncs.com";
    private static final Integer SUCCESS_CODE = 200;
    // 正面
    private static final String FACE = "face";
    // 背面
    private static final String BACK = "back";


@Override
    public AppMemberUserOcrRespVO ocrIdentify(byte[] bytes, String originalFilename) {
        String url = fileApi.createFile(bytes, originalFilename);
        if (StringUtils.isBlank(url)) {
            throw exception(OCR_FILE_UPLOAD_FAIL);
        }
        com.aliyun.credentials.Client credential = new com.aliyun.credentials.Client();
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret)
                .setCredential(credential);
        config.endpoint = END_POINT;
        com.aliyun.ocr_api20210707.Client client = null;
        try {
            client = new com.aliyun.ocr_api20210707.Client(config);
        } catch (Exception e) {
            log.error("ocr client init fail", e);
            throw exception(OCR_CLIENT_INIT_FAIL);
        }
        com.aliyun.ocr_api20210707.models.RecognizeIdcardRequest recognizeIdcardRequest = new com.aliyun.ocr_api20210707.models.RecognizeIdcardRequest().setUrl(url);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        AppMemberUserOcrRespVO appMemberUserOcrRespVO = new AppMemberUserOcrRespVO();
        try {
            com.aliyun.ocr_api20210707.models.RecognizeIdcardResponse resp = client.recognizeIdcardWithOptions(recognizeIdcardRequest, runtime);
            if (resp == null || !SUCCESS_CODE.equals(resp.getStatusCode())) {
                throw exception(OCR_RESULT_FAIL);
            }
            RecognizeIdcardResponseBody body = resp.getBody();
            String data = body.getData();

            if (StringUtils.isBlank(data)) {
                log.error("OCR response data is empty");
                throw exception(OCR_RESULT_FAIL);
            }
            JSONObject jsonObject = JSON.parseObject(data);
            JSONObject dataObject = jsonObject.getJSONObject("data");
            if (dataObject == null) {
                log.error("OCR response data object is null");
                throw exception(OCR_RESULT_FAIL);
            }

            // 处理身份证正面信息
            processFrontSide(dataObject, appMemberUserOcrRespVO);
            // 处理身份证背面信息
            processBackSide(dataObject, appMemberUserOcrRespVO);
        } catch (TeaException error) {
            log.error("OCR recognition failed - Message: {}, Recommend: {}", error.getMessage(), error.getData().get("Recommend"));
            throw exception(OCR_RESULT_FAIL);
        } catch (Exception _error) {
            log.error("OCR recognition failed unexpectedly - Message: {}", _error.getMessage(), _error);
            throw exception(OCR_RESULT_FAIL);
        }
        return appMemberUserOcrRespVO;
    }

    /**
     * 提取处理身份证正面信息的方法
     *
     * @param dataObject
     * @param respVO
     */
    private void processFrontSide(JSONObject dataObject, AppMemberUserOcrRespVO respVO) {
        if (dataObject.containsKey(FACE)) {
            JSONObject faceData = dataObject.getJSONObject(FACE).getJSONObject("data");
            if (faceData != null) {
                respVO.setAddress(getStringValue(faceData, "address"));
                respVO.setBirthDate(getStringValue(faceData, "birthDate"));
                respVO.setEthnicity(getStringValue(faceData, "ethnicity"));
                respVO.setIdNumber(getStringValue(faceData, "idNumber"));
                respVO.setName(getStringValue(faceData, "name"));
                respVO.setSex(getStringValue(faceData, "sex"));
            }
        }
    }

    /**
     * 提取处理身份证背面信息的方法
     *
     * @param dataObject
     * @param respVO
     */
    private void processBackSide(JSONObject dataObject, AppMemberUserOcrRespVO respVO) {
        if (dataObject.containsKey(BACK)) {
            JSONObject backData = dataObject.getJSONObject(BACK).getJSONObject("data");
            if (backData != null) {
                respVO.setIssueAuthority(getStringValue(backData, "issueAuthority"));
                respVO.setValidPeriod(getStringValue(backData, "validPeriod"));
            }
        }
    }

    /**
     * 安全获取JSON字符串值的辅助方法
     *
     * @param jsonObject
     * @param key
     * @return
     */
    private String getStringValue(JSONObject jsonObject, String key) {
        Object value = jsonObject.get(key);
        return value != null ? value.toString() : null;
    }

接口出参:

java 复制代码
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Schema(description = "用户 APP - OCR信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppMemberUserOcrRespVO {
    /**
     * 正面信息
     */
    @Schema(description = "姓名", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "章三")
    private String name;

    @Schema(description = "性别", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "男")
    private String sex;

    @Schema(description = "民主", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "汉族")
    private String ethnicity;

    @Schema(description = "出生日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String birthDate;

    @Schema(description = "住址", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String address;

    @Schema(description = "身份证好吗", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "330301200001090002")
    private String idNumber;

    /**
     * 反面信息
     */
    @Schema(description = "签发机关", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "北京市公安局")
    private String issueAuthority;

    @Schema(description = "有效期限", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String validPeriod;
}

阿里云开发文档和调试地址:

https://api.aliyun.com/api/ocr-api/2021-07-07/RecognizeIdcard?spm=5176.23043878_1479102120.console-base_help.53.182e1cdcLtXfrz&sdkStyle=dara&RegionId=cn-hangzhou&params={%22body%22:%228ac2446b-7197-4470-95f6-cfd12172f4ad%22}&tab=DOC&lang=JAVA

入参和出参的字段都是有说明的:

然后我用apiFox测试:

相关推荐
OpenClawCSDN10 小时前
2026年怎么集成Hermes Agent/OpenClaw?阿里云搭建及token Plan配置攻略
阿里云·云计算
byoass13 小时前
企业云盘与设计软件深度集成:AutoCAD/Revit/SolidWorks插件开发与API集成实战
服务器·网络·数据库·安全·oracle·云计算
OpenClawCSDN15 小时前
2026年5月阿里云怎么搭建OpenClaw/Hermes Agent?百炼token Plan配置详解教程
阿里云·云计算
snpgroupcn16 小时前
通过退役17套SAP ECC历史系统,降低道达尔能源的SAP数据相关风险
云计算·数据迁移·sap ecc
OpenClawCSDN20 小时前
2026年5月阿里云OpenClaw/Hermes Agent集成攻略+百炼token Plan配置全览教程
阿里云·云计算
谷哥的小弟1 天前
(最新版)腾讯云服务器项目部署教程(4)— 部署项目
linux·运维·服务器·云计算·腾讯云·云服务器·项目部署
云天AI实战派1 天前
Agentic AI 全流程实战:用 OpenAI on AWS 搭一个餐饮补货智能体,从 API 调用到容器化上线
人工智能·云计算·aws
测试狗科研平台1 天前
第一性原理差分电荷密度分析的计算方法与公式-测试GO
云计算·材料工程·空间计算
G31135422732 天前
如何用 QClaw 龙虾做一个规律作息健康助理 Agent
大数据·人工智能·ai·云计算
TG_yunshuguoji2 天前
阿里云代理商:DeepSeek V4 vs GPT 系列 阿里云上的成本与性能新平衡
人工智能·阿里云·云计算·ai智能体·deepseek v4