一 开发环境
后端语言 java
技术工具框架 springboot
二 实现目的
本demo适用于快速服务端调用微信小程序OCR接口实现,以行驶证接口为例
包括
- 图片上传
- 调用微信小程序接口实现OCR识别
- swagger3 集成调用 去除不必要的 - - 简单实用,详细查看openapi文档
三 Demo上线
- 搭建我们的基础环境
目录结构如下
- pom文件配置
4.0.0 org.springframework.boot spring-boot-starter-parent2.1.7.RELEASE com.example demo0.0.1-SNAPSHOT demo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-thymeleaforg.projectlombok lomboktrue org.springframework.cloud spring-cloud-starter-openfeign2.1.1.RELEASE org.springframework.cloud spring-cloud-starter-netflix-ribbon2.1.1.RELEASE org.springframework.boot spring-boot-starter-testtest com.alibaba fastjson1.2.59 org.springframework.boot spring-boot-maven-plugin
- 集成swagger3
官网下载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目录下,修改内容
{
"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"
}
}
}
}
- application启动类添加Feign调用注解
@SpringBootApplication
@EnableFeignClients
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 配置全局文件 application.yml (properties修改为yml即可)
#服务配置
server:
port: 8890
compression:
enabled: true
max-http-header-size: 10000000
spring:
application:
name: ocr-demo
#外部调用
app:
vehicle: "https://api.weixin.qq.com"
至此,我们的基础环境细致的讲解完毕,且完整基础环境搭建完整,骚年们,开始代码!!!!
- 通用返回dto编写
package com.example.demo.common.dto; import java.io.Serializable; import java.util.linkedList; import java.util.List; import java.util.Objects; public class RestControllerResultimplements Serializable { private static final long serialVersionUID = -3698136820012767666L; private Boolean success; private Integer code; private List infoMsgs = new linkedList<>(); private List 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 getInfoMsgs() { return this.infoMsgs; } public void setInfoMsgs(List infoMsgs) { this.infoMsgs = infoMsgs; } public List getWarningMsgs() { return this.warningMsgs; } public void setWarningMsgs(List 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 RestControllerResult 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层编写(分为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;
@RestController
@RequestMapping("/api/vehicle")
public interface AppVehicleMiniApi {
@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;
@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;
}
}
- service实现
package com.example.demo.service;
import org.springframework.web.multipart.MultipartFile;
public interface AppVehicleService {
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;
@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 map = (Map)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());
}
}
- 重点戏:Feign调用实现
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;
@FeignClient(value = "vehicle", fallbackFactory = AppVehicleFeignFactory.class, url = "${app.vehicle}")
public interface AppVehicleFeign {
@GetMapping("/cgi-bin/token?grant_type=client_credential&appid=[小程序开发id]&secret=[微信密钥]")
Object getWeiXinToken();
@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;
public class AppVehicleFeignFactory implements FallbackFactory {
@Override
public AppVehicleFeign create(Throwable throwable) {
return null;
}
}
终于可以愉快地测试了!!!!!
启动应用,访问地址 http://localhost:8890/swagger3/index.html
干净、简洁、明了
点击上传接口,try it out,选择行驶证照片,执行
老夫手把手教学结束了!!!!
原创不易,小隐出品,转载,请注明作者、出处,谢谢大家不吝赐教!!!!!



