主题
今天的主题是使用springboot starter
和阿里云的AI识别sdk构建一个身份证识别应用。
主要依赖项
-
spring-boot-starter-web
-
页面模板
spring-boot-starter-thymeleaf
-
阿里云识别组件与json组件
-
<dependency> <groupId>com.aliyun</groupId> <artifactId>ocr</artifactId> <version>1.0.3</version> </dependency>
-
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.67</version> </dependency>
-
主要逻辑
用户在web端上传身份证的正反面的照片,然后传递到springboot
,然后由后端将图像传递到阿里云的识别服务,等待识别服务响应识别结果,最后将结果渲染到thymeleaf
模板中返还给用户实现完整逻辑。
代码实现分析解读
Controller层上传文件部分
@PostMapping("/upload")
public String uploadFile(@RequestParam("face") MultipartFile face, @RequestParam("back") MultipartFile back,
RedirectAttributes attributes) {
// 判断是否上传了空文件
if (face.isEmpty() || back.isEmpty()) {
// 显示报错信息
attributes.addFlashAttribute("message", "Please select a file to upload.");
// 路由跳转
return "redirect:/";
}
// 初始化错误信息
String errorMessage = null;
try {
// 根据相对路径获取上传目录的绝对路径
Path dir = Paths.get(uploadDirectory);
// 检测路径的存在性,避免因为路径不存在而报错
if (!Files.exists(dir)) {
Files.createDirectories(dir);
}
// 个人感觉下面两部分的空检测是不必要的,上面已经检测过一遍了
if (!face.isEmpty()) {
// 将文本流保存到本地,并获取对应的文件名。文件名是随机ID
String filename = saveFile(face);
// 调用OCR服务,获取识别人脸面的识别信息
Map<String, String> res = ocrService.RecognizeIdCard(uploadDirectory + filename, "face");
// 在缓存中加入识别成功的文件
faceImages.add("/images/" + filename);
// 在缓存中加入识别结果
faceResults.add(res);
}
// 背部的识别同上
if (!back.isEmpty()) {
String filename = saveFile(back);
Map<String, String> res = ocrService.RecognizeIdCard(uploadDirectory + filename, "back");
backImages.add("/images/" + filename);
backResults.add(res);
}
} catch (TeaException e) {
// 错误捕捉
e.printStackTrace();
errorMessage = JSON.toJSONString(e.getData());
} catch (Exception e) {
e.printStackTrace();
errorMessage = e.getMessage();
}
// 判断是否有错误报出
if (StringUtils.isNotBlank(errorMessage)) {
attributes.addFlashAttribute("message", errorMessage);
}
// 路由跳转
return "redirect:/";
}
OCR服务
/**
* 身份证识别
* @param filePath 文件路径
* @param side 身份证的面
* @return 识别结果
* @throws Exception
*/
public Map<String, String> RecognizeIdCard(String filePath, String side) throws Exception {
// 实例化请求
RecognizeIdentityCardAdvanceRequest request = new RecognizeIdentityCardAdvanceRequest();
// 加载需要识别的图像流
request.imageURLObject = Files.newInputStream(Paths.get(filePath));
// 加载对应的面:人像面或者是国徽面
request.side = side;
// 发送请求并获取响应
RecognizeIdentityCardResponse response = ocrClient.recognizeIdentityCardAdvance(request, runtime);
if ("face".equals(side)) {
return JSON.parseObject(JSON.toJSONString(response.data.frontResult), new TypeReference<Map<String, String>>() {});
} else {
return JSON.parseObject(JSON.toJSONString(response.data.backResult), new TypeReference<Map<String, String>>() {});
}
}