This article solves the implementation of the WeChat applet OCR identification API interface call

Get into the habit of writing together! This is the 12th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

The implementation of the server calling the WeChat applet OCR identification interface

a development environment

Back- end language java
technology tool framework springboot

Two to achieve the purpose

This demo is suitable for the quick server to call the WeChat applet OCR interface implementation, taking the driving license interface as an example

include

  1. upload picture
  2. Call WeChat applet interface to realize OCR recognition
  3. Swagger3 integration calls to remove unnecessary -- simple and practical, see openapi documentation for details

Three Demos are online

  1. Build our basic environment

The directory structure is as follows

image.png

  • pom file configuration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>demo</name>
  <description>Demo project for Spring Boot</description>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
复制代码
  • Integrate swagger3

Download swagger from the official website, put the dist directory under Resource-static, and modify the dist to swagger3

Open index.html in the directory and modify it to

 const ui = SwaggerUIBundle({
        url: "swagger.json",
        dom_id: '#swagger-ui',
        deepLinking: true,
        presets: [
          SwaggerUIBundle.presets.apis,
          SwaggerUIStandalonePreset
        ],
        plugins: [
          SwaggerUIBundle.plugins.DownloadUrl
        ],
        layout: "StandaloneLayout"
      })
      // End Swagger UI call region

      window.ui = ui
复制代码

The official website opens petstore.swagger.io/v..., template json...

{
  "swagger": "2.0",
  "info": {
    "title": "小程序服务端demo",
    "description": "本文档为,小程序服务端接口描述文档swagger页面",
    "version": "1.0.0"
  },
  "tags": [
    {
      "name": "小程序后端服务",
      "description": "此服务提供小程序访问后端系统的业务实现."
    }
  ],
  "schemes": [
    "http"
  ],
  "paths": {
    "/api/vehicle/upload-vehicle": {
      "post": {
        "tags": [
          "小程序后端服务"
        ],
        "summary": "行驶证照片上传接口",
        "description": "行驶证照片上传接口",
        "operationId": "uploadFile",
        "consumes": [
复制代码
  • Add Feign call annotation to application startup class
@SpringBootApplication
@EnableFeignClients
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

}
复制代码
  • Configure the global file application.yml (properties can be changed to yml)
#服务配置
server:
  port: 8890
  compression:
    enabled: true
  max-http-header-size: 10000000

spring:
  application:
    name: ocr-demo

#外部调用
app:
  vehicle: "https://api.weixin.qq.com"
复制代码

So far, our basic environment has been explained in detail, and the complete basic environment has been built. Sao Nian, let's start coding! ! ! !

  1. Generic return dto write
package com.example.demo.common.dto;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * 通用接口返回结果.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:44
 */
public class RestControllerResult<T> implements Serializable {

  private static final long serialVersionUID = -3698136820012767666L;
  private Boolean success;
  private Integer code;
  private List<String> infoMsgs = new LinkedList<>();
  private List<String> warningMsgs = new LinkedList<>();
  private String errorMsg;
  private T data;

  public RestControllerResult() {
  }

  public RestControllerResult(T t) {
    this.data = t;
  }

  public Boolean getSuccess() {
    return this.success;
  }

  public void setSuccess(Boolean success) {
    this.success = success;
  }

  public Integer getCode() {
    return this.code;
  }

  public void setCode(int code) {
    this.code = code;
  }

  public List<String> getInfoMsgs() {
    return this.infoMsgs;
  }

  public void setInfoMsgs(List<String> infoMsgs) {
    this.infoMsgs = infoMsgs;
  }

  public List<String> getWarningMsgs() {
    return this.warningMsgs;
  }

  public void setWarningMsgs(List<String> warningMsgs) {
    this.warningMsgs = warningMsgs;
  }

  public String getErrorMsg() {
    return this.errorMsg;
  }

  public void setErrorMsg(String errorMsg) {
    this.errorMsg = errorMsg;
  }

  public T getData() {
    return this.data;
  }

  public void setData(T data) {
    this.data = data;
  }

  public static <T> RestControllerResult<T> success(T data) {
    RestControllerResult result = new RestControllerResult(data);
    result.setSuccess(true);
    return result;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    } else if (o != null && this.getClass() == o.getClass()) {
      RestControllerResult<?> that = (RestControllerResult) o;
      return this.code.equals(that.code) && Objects.equals(this.success, that.success) && Objects
          .equals(this.infoMsgs, that.infoMsgs) && Objects
          .equals(this.warningMsgs, that.warningMsgs) && Objects
          .equals(this.errorMsg, that.errorMsg) && Objects.equals(this.data, that.data);
    } else {
      return false;
    }
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        new Object[]{this.success, this.code, this.infoMsgs, this.warningMsgs, this.errorMsg,
            this.data});
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("RestControllerResult{");
    sb.append("success=").append(this.success);
    sb.append(", code=").append(this.code);
    sb.append(", infoMsgs=").append(this.infoMsgs);
    sb.append(", warningMsgs=").append(this.warningMsgs);
    sb.append(", errorMsg='").append(this.errorMsg).append(''');
    sb.append(", data=").append(this.data);
    sb.append('}');
    return sb.toString();
  }
}
复制代码
  1. Controller layer writing (divided into api-controller)

api

package com.example.demo.api;

import com.example.demo.common.dto.RestControllerResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 小程序请求后端系统Api.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:50
 */
@RestController
@RequestMapping("/api/vehicle")
public interface AppVehicleMiniApi {

  /**
   * 上传行驶证照片.
   *
   * @param img 图片
   * @return result
   */
  @PostMapping("upload-vehicle")
  RestControllerResult uploadVehicle(@RequestParam("file") MultipartFile img);

}
复制代码

controller

package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.api.AppVehicleMiniApi;
import com.example.demo.common.dto.RestControllerResult;
import com.example.demo.service.AppVehicleService;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 小程序请求后端系统完成功能Controller.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:44
 */
@RestController
public class AppVehicleMiniApiController implements AppVehicleMiniApi {

  private static final Logger logger = LoggerFactory.getLogger(AppVehicleMiniApiController.class);
  private static final String IMG_EMPTY = "上传照片为空";

  @Resource
  private AppVehicleService appVehicleService;


  @Override
  public RestControllerResult uploadVehicle(MultipartFile img) {
    logger.info("=======>行驶证上传<=======");
    RestControllerResult resultsDtoRestControllerResult = new RestControllerResult<>();
    if (img.isEmpty()) {
      logger.error(IMG_EMPTY);
      resultsDtoRestControllerResult.setSuccess(false);
      resultsDtoRestControllerResult.setCode(400);
      resultsDtoRestControllerResult.setErrorMsg(IMG_EMPTY);
      return resultsDtoRestControllerResult;
    }
    System.out.println(JSONObject.toJSONString(appVehicleService.ocrVehilce(img)));
    resultsDtoRestControllerResult.setSuccess(true);
    resultsDtoRestControllerResult.setCode(200);
    resultsDtoRestControllerResult.setData(appVehicleService.ocrVehilce(img));
    return resultsDtoRestControllerResult;
  }
}
复制代码

3.Service implementation

package com.example.demo.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * 行驶证图片上传服务接口.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:50
 */
public interface AppVehicleService {

  /**
   * 识别行驶证.
   *
   * @param img 上传图片
   * @return 识别结果
   */
  Object ocrVehilce(MultipartFile img);

}
复制代码
package com.example.demo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.feign.AppVehicleFeign;
import com.example.demo.service.AppVehicleService;
import java.util.Map;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 行驶证照片服务.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:50
 */
@Service
public class AppVehicleServiceImpl implements AppVehicleService {

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

  @Resource
  private AppVehicleFeign appVehicleFeign;

  @Override
  public Object ocrVehilce(MultipartFile img) {
    Object value = appVehicleFeign.getWeiXinToken();
    String s = JSONObject.toJSONString(value);
    Map<String, Object> map = (Map<String, Object>)JSONObject.parse(s);
    Object token = "";
    if (map.get("access_token") != null) {
      logger.info("最终token为" + map.get("access_token"));
      token = map.get("access_token");
    } else {
      //返回失败结果
      logger.error("微信接口服务获取token发生错误,错误代码 " + map.get("errcode"));
      logger.error("微信接口服务获取token发生错误,错误信息 " + map.get("errmsg"));
    }
    return appVehicleFeign.ocrVehicle(img,token.toString());
  }
}
复制代码

4. Key play: Feign call implementation

package com.example.demo.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

/**
 * 行驶证处理feign.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:50
 */
@FeignClient(value = "vehicle", fallbackFactory = AppVehicleFeignFactory.class, url = "${app.vehicle}")
public interface AppVehicleFeign {

  /**
   * 获取微信token.
   *
   * @return token
   */
  @GetMapping("/cgi-bin/token?grant_type=client_credential&appid=[小程序开发id]&secret=[微信密钥]")
  Object getWeiXinToken();

  /**
   * 识别行驶证.
   *
   * @param img 照片
   * @param token token
   * @return 识别结果
   */
  @PostMapping(value = "/cv/ocr/driving?type=photo&access_token={token}",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  Object ocrVehicle(@RequestPart(value = "file") MultipartFile img,
      @PathVariable(name = "token") String token);

}
复制代码
package com.example.demo.feign;

import feign.hystrix.FallbackFactory;

/**
 * 行驶证feign工厂.
 *
 * @author : 小隐乐乐
 * @since : 2022/4/11 9:50
 */
public class AppVehicleFeignFactory implements FallbackFactory<AppVehicleFeign> {

  @Override
  public AppVehicleFeign create(Throwable throwable) {
    return null;
  }
}
复制代码

It's finally fun to test! ! ! ! !

Start the application and visit the address  http://localhost:8890/swagger3/index.html

图片

clean, concise, clear

Click the upload interface, try it out, select the photo of the driving license, and execute

图片

Guess you like

Origin juejin.im/post/7085149627619967007