由于项目要用到实名认证功能,因此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;
}
阿里云开发文档和调试地址:
入参和出参的字段都是有说明的:

然后我用apiFox测试:
