Implementation of OCR Recognition Interface for Calling Wechat Widget Program on Server

Posted by jhl84 on Wed, 21 Aug 2019 05:29:14 +0200

A Development Environment

Back-end language java
Technical Tool Framework springboot

II. Achieving the Purpose

This demo is suitable for the implementation of calling the OCR interface of the wechat widget program on the fast server, taking the driver's license interface as an example.

Include

  1. Picture upload
  2. OCR Recognition by Calling Wechat Widget Program Interface
  3. swagger3 integration call eliminates unnecessary - - simple and practical, see openapi documentation in detail

Three Demo s on Line

  1. Build our basic environment

The directory structure is as follows

  • 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>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
      <version>2.1.1.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-ribbon -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
      <version>2.1.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <!-- fastjson -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.59</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>
  • Integrated swagger 3

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

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

Open the official website https://petstore.swagger.io/v... Template json, save it in the swagger3 directory, modify the content

{
  "swagger": "2.0",
  "info": {
    "title": "Small Program Server demo",
    "description": "This document is a description document of the widget server interface. swagger page",
    "version": "1.0.0"
  },
  "tags": [
    {
      "name": "Small Program Backend Service",
      "description": "Business implementation of this service provider widget accessing back-end system."
    }
  ],
  "schemes": [
    "http"
  ],
  "paths": {
    "/api/vehicle/upload-vehicle": {
      "post": {
        "tags": [
          "Small Program Backend Service"
        ],
        "summary": "Driving license photo upload interface",
        "description": "Driving license photo upload interface",
        "operationId": "uploadFile",
        "consumes": [
          "multipart/form-data"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "file",
            "in": "formData",
            "description": "Driving permit photos",
            "required": true,
            "type": "file"
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "$ref": "#/definitions/RestControllerResult"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "RestControllerResult": {
      "type": "object",
      "properties": {
        "success": {
          "type": "boolean",
          "description": "Success or not",
          "default": false
        },
        "code": {
          "type": "integer",
          "description": "Response Code",
          "format": "int64"
        },
        "infoMsgs": {
          "type": "array",
          "xml": {
            "name": "infoMsgs",
            "wrapped": true
          },
          "items": {
            "type": "string",
            "description": "information"
          }
        },
        "warningMsgs": {
          "type": "array",
          "xml": {
            "name": "warningMsgs",
            "wrapped": true
          },
          "items": {
            "type": "string",
            "description": "Warning information"
          }
        },
        "errorMsg": {
          "type": "string",
          "description": "error message"
        },
        "data": {
          "type": "object"
        }
      },
      "xml": {
        "name": "RestControllerResult"
      }
    }
  }
}
  • application startup class adds annotations for Feign calls
@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)
#Service configuration
server:
  port: 8890
  compression:
    enabled: true
  max-http-header-size: 10000000

spring:
  application:
    name: ocr-demo

#External call
app:
  vehicle: "https://api.weixin.qq.com"

So far, our detailed explanation of the basic environment has been completed, and the complete basic environment has been built. Sao years, start the code!!!!

  1. General Return dto Writing
package com.example.demo.common.dto;

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

/**
 * Common interface returns results.
 *
 * @author : Small hidden
 * @since : 2019/8/21 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;

/**
 * The applet requests the back-end system Api.
 *
 * @author : Small hidden
 * @since : 2019/8/15 15:37
 */
@RestController
@RequestMapping("/api/vehicle")
public interface AppVehicleMiniApi {

  /**
   * Upload driving license photos.
   *
   * @param img picture
   * @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;

/**
 1. The applet requests the back-end system to complete the function Controller.
 2.  3. @author : Small hidden
 4. @since : 2019/8/21
 */
@RestController
public class AppVehicleMiniApiController implements AppVehicleMiniApi {

  private static final Logger logger = LoggerFactory.getLogger(AppVehicleMiniApiController.class);
  private static final String IMG_EMPTY = "Upload photos empty";

  @Resource
  private AppVehicleService appVehicleService;


  @Override
  public RestControllerResult uploadVehicle(MultipartFile img) {
    logger.info("=======>Upload of Driving License<=======");
    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;
  }
}
  1. service Implementation
package com.example.demo.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * Driving license picture upload service interface.
 *
 * @author : Small hidden
 * @since : 2019/8/19 15:50
 */
public interface AppVehicleService {

  /**
   * Identify the driving license.
   *
   * @param img Upload pictures
   * @return Recognition results
   */
  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;

/**
 * Driving license photo service.
 *
 * @author : Small hidden
 * @since : 2019/8/19 18:11
 */
@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("Final token by" + map.get("access_token"));
      token = map.get("access_token");
    } else {
      //Return failed results
      logger.error("Wechat Interface Service Acquisition token Error, error code " + map.get("errcode"));
      logger.error("Wechat Interface Service Acquisition token Error, error message " + map.get("errmsg"));
    }
    return appVehicleFeign.ocrVehicle(img,token.toString());
  }
}
  1. Key Play: Implementation of Feign Call
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;

/**
 * Driving license processing feign.
 *
 * @author : Small hidden
 * @since : 2019/8/20 17:03
 */
@FeignClient(value = "vehicle", fallbackFactory = AppVehicleFeignFactory.class, url = "${app.vehicle}")
public interface AppVehicleFeign {

  /**
   * Get Wechat token.
   *
   * @return token
   */
  @GetMapping("/cgi-bin/token?grant_type=client_credential&appid=[Small Program Development id]&secret=[Wechat Key]")
  Object getWeiXinToken();

  /**
   * Identify the driving license.
   *
   * @param img Photo
   * @param token token
   * @return Recognition results
   */
  @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;

/**
 * Driving permit feign factory.
 *
 * @author : Small hidden
 * @since : 2019/8/20 17:10
 */
public class AppVehicleFeignFactory implements FallbackFactory<AppVehicleFeign> {

  @Override
  public AppVehicleFeign create(Throwable throwable) {
    return null;
  }
}

Finally, we can test it happily!!!!!

Start the application, access the address http://localhost:8890/swagger3/index.html

Clean, concise and clear

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

The old man's hand-to-hand teaching is over!!!

Originality is not easy, small hidden products, reprinted, please indicate the author, origin, thank you for your generous advice!!!!

Micro signal huc_lele, welcome to disturb!

Topics: Java Spring Maven xml