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
- Picture upload
- OCR Recognition by Calling Wechat Widget Program Interface
- swagger3 integration call eliminates unnecessary - - simple and practical, see openapi documentation in detail
Three Demo s on Line
- 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!!!!
- 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(); } }
- 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; } }
- 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()); } }
- 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!