¡Acostúmbrate a escribir juntos! Este es el día 12 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .
La implementación del servidor que llama a la interfaz de identificación OCR del subprograma WeChat
un entorno de desarrollo
Lenguaje back-end marco de herramienta de tecnología java springboot
Dos para lograr el objetivo.
Esta demostración es adecuada para que el servidor rápido llame a la implementación de la interfaz OCR del subprograma WeChat, tomando como ejemplo la interfaz del permiso de conducir.
incluir
- subir foto
- Llame a la interfaz del subprograma WeChat para realizar el reconocimiento OCR
- Llamadas de integración de Swagger3 para eliminar elementos innecesarios: simple y práctico, consulte la documentación de openapi para obtener más información.
Tres demostraciones están en línea
- Construir nuestro entorno básico
La estructura del directorio es la siguiente
- configuración del archivo pom
<?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>
复制代码
- Integrar swagger3
Descargue swagger del sitio web oficial, coloque el directorio dist en Resource-static y modifique dist a swagger3
Abra index.html en el directorio y modifíquelo para
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
复制代码
El sitio web oficial abre 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": [
复制代码
- Agregue la anotación de llamada Fingir a la clase de inicio de la aplicación
@SpringBootApplication
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
复制代码
- Configure el archivo global application.yml (las propiedades se pueden cambiar a yml)
#服务配置
server:
port: 8890
compression:
enabled: true
max-http-header-size: 10000000
spring:
application:
name: ocr-demo
#外部调用
app:
vehicle: "https://api.weixin.qq.com"
复制代码
Hasta ahora, nuestro entorno básico se ha explicado en detalle y se ha construido el entorno básico completo. ¡Sao Nian, comencemos a codificar! ! ! !
- Retorno genérico dto escribir
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();
}
}
复制代码
- Escritura de la capa del controlador (dividida en 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);
}
复制代码
controlador
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.Implementación del servicio
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. Juego clave: Fingir la implementación de la llamada
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;
}
}
复制代码
¡Finalmente es divertido probarlo! ! ! ! !
Inicie la aplicación y visite la dirección http://localhost:8890/swagger3/index.html
limpio, conciso, claro
Haga clic en la interfaz de carga, pruébelo, seleccione la foto de la licencia de conducir y ejecute