一 開發環境html
後端語言 java
技術工具框架 springbootjava
二 實現目的web
本demo適用於快速服務端調用微信小程序OCR接口實現,以行駛證接口爲例spring
包括apache
三 Demo上線json
目錄結構以下小程序
<?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>
官網下載swagger,將dist目錄放入Resource-static下,修改dist爲swagger3後端
打開目錄下index.html,修改成微信小程序
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
官網打開https://petstore.swagger.io/v...,模板json,保存放到swagger3目錄下,修改內容api
{ "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": [ "multipart/form-data" ], "produces": [ "application/json" ], "parameters": [ { "name": "file", "in": "formData", "description": "行駛證照片", "required": true, "type": "file" } ], "responses": { "200": { "description": "successful operation", "schema": { "$ref": "#/definitions/RestControllerResult" } } } } } }, "definitions": { "RestControllerResult": { "type": "object", "properties": { "success": { "type": "boolean", "description": "成功與否", "default": false }, "code": { "type": "integer", "description": "響應碼", "format": "int64" }, "infoMsgs": { "type": "array", "xml": { "name": "infoMsgs", "wrapped": true }, "items": { "type": "string", "description": "信息" } }, "warningMsgs": { "type": "array", "xml": { "name": "warningMsgs", "wrapped": true }, "items": { "type": "string", "description": "警告信息" } }, "errorMsg": { "type": "string", "description": "錯誤信息" }, "data": { "type": "object" } }, "xml": { "name": "RestControllerResult" } } } }
@SpringBootApplication @EnableFeignClients public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
#服務配置 server: port: 8890 compression: enabled: true max-http-header-size: 10000000 spring: application: name: ocr-demo #外部調用 app: vehicle: "https://api.weixin.qq.com"
至此,咱們的基礎環境細緻的講解完畢,且完整基礎環境搭建完整,騷年們,開始代碼!!!!
package com.example.demo.common.dto; import java.io.Serializable; import java.util.LinkedList; import java.util.List; import java.util.Objects; /** * 通用接口返回結果. * * @author : 小隱 * @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(); } }
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 : 2019/8/15 15:37 */ @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; /** 1. 小程序請求後端系統完成功能Controller. 2. 3. @author : 小隱 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 = "上傳照片爲空"; @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; } }
package com.example.demo.service; import org.springframework.web.multipart.MultipartFile; /** * 行駛證圖片上傳服務接口. * * @author : 小隱 * @since : 2019/8/19 15: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 : 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("最終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()); } }
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 : 2019/8/20 17:03 */ @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 : 2019/8/20 17:10 */ public class AppVehicleFeignFactory implements FallbackFactory<AppVehicleFeign> { @Override public AppVehicleFeign create(Throwable throwable) { return null; } }
終於能夠愉快地測試了!!!!!
啓動應用,訪問地址 http://localhost:8890/swagger3/index.html
乾淨、簡潔、明瞭
點擊上傳接口,try it out,選擇行駛證照片,執行
老夫手把手教學結束了!!!!
原創不易,小隱出品,轉載,請註明做者、出處,謝謝你們不吝賜教!!!!!
微信號huc_lele,歡迎來擾!