当前位置:网站首页>Custom implementation of Baidu image recognition (instead of aipocr)
Custom implementation of Baidu image recognition (instead of aipocr)
2022-04-23 16:31:00 【Spilled off】
package com.visy.service;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.visy.exception.ErrorEnum;
import com.visy.exception.BusinessException;
import com.visy.config.BaiduConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Baidu image recognition custom implementation ( replace AipOcr)
* @author visy.wang
* @date 2022/1/19 9:24
*/
@Slf4j
@Service
public class AipOcrClient {
private static long expireTime = 0L; //token Expiration time stamp
private static String accessToken = null; //token value
@Autowired
private BaiduConfig baiduConfig; // Baidu authentication information , Configure your own apiKey and secretKey
@Autowired
private RestTemplate restTemplate;
//Url Management enumeration
@Getter
@AllArgsConstructor
enum UrlKey {
ACCESS_TOKEN("https://aip.baidubce.com/oauth/2.0/token", " Certification address "),
DRIVING_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license", " Driver's license identification address "),
VEHICLE_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license", " Driving license identification address ");
private final String url;
private final String desc;
}
/**
* Driver's license identification
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Driver's license identification
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Identification of driving license
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.VEHICLE_LICENSE, options);
}
/**
* Identification of driving license
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.VEHICLE_LICENSE, options);
}
// belt Token Overdue inspection request, Temporarily unnecessary , The expiration time has been calculated and retrieved before expiration
private JSONObject requestWithTokenCheck(UrlKey urlKey, Map<String,String> options){
JSONObject res = request(urlKey, options);
if(res.has("error_code")){
int errCode = res.getInt("error_code");
if(errCode==110 || errCode==111){
accessToken = null; //Token invalid , Clear and retrieve
return request(urlKey, options);
}
}
return res;
}
/**
* request
* @param urlKey url Address enumeration
* @param options The other parameters
* @return Recognition result
*/
private JSONObject request(UrlKey urlKey, Map<String,String> options){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String url = urlKey.getUrl();
MultiValueMap<String, String> queryStr = getQueryStr(urlKey);
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url).queryParams(queryStr);
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
if(Objects.nonNull(options) && !options.isEmpty()){
options.forEach(formData::add);
}
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(formData, headers);
ResponseEntity<String> res = restTemplate.postForEntity(uriBuilder.toUriString(), request, String.class);
if(!HttpStatus.OK.equals(res.getStatusCode())){
throw buzError(" request was aborted :httpStatus=" + res.getStatusCode());
}
String resBody = res.getBody();
if(StringUtils.isBlank(resBody)){
throw buzError(" The response body is empty ");
}
return new JSONObject(resBody);
}
private MultiValueMap<String, String> getQueryStr(UrlKey urlKey){
MultiValueMap<String, String> queryStr = new LinkedMultiValueMap<>();
if(UrlKey.ACCESS_TOKEN.equals(urlKey)){
queryStr.add("grant_type", "client_credentials");
queryStr.add("client_id", baiduConfig.getApiKey());
queryStr.add("client_secret", baiduConfig.getSecretKey());
}else{
queryStr.add("access_token", getAccessToken()); // Add authentication information
}
return queryStr;
}
/**
* obtain AccessToken
* @return AccessToken
*/
private String getAccessToken(){
long now = System.currentTimeMillis();
if(StringUtils.isNotBlank(accessToken) && now<expireTime){
// There is a cache and it is within the validity period , Use it directly
return accessToken;
}
try{
return getAccessToken(now);
}catch (Exception e){
throw buzError("AccessToken Acquisition failure :" + e.getMessage());
}
}
private String getAccessToken(long now){
log.info(" Retrieving AccessToken...");
JSONObject body = request(UrlKey.ACCESS_TOKEN, null);
if(body.has("error")){
throw buzError(body.getString("error_description"));
}
int tokenExpires = body.getInt("expires_in"); // The period of validity , Unit second , Default 30 God
expireTime = now + (tokenExpires-86400L)*1000L; // advance 1 Days out
accessToken = body.getString("access_token"); // cache token
log.info(" Authentication success , Valid until :{}", new Date(expireTime));
return accessToken;
}
/**
* Throw business exception
* @param errMsg error message
* @return Business exceptions
*/
private BusinessException buzError(String errMsg){
//BusinessException: Custom business exception
return new BusinessException(ErrorEnum.BUSINESS_ERR.getCode(), errMsg);
}
}
package com.visy.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author visy.wang
* @date 2022/1/19 9:28
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "baidu")
public class BaiduConfig {
private String appId;
private String apiKey;
private String secretKey;
}
版权声明
本文为[Spilled off]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231403162847.html
边栏推荐
- You need to know about cloud disaster recovery
- 最详细的背包问题!!!
- Solution of garbled code on idea console
- 关于 background-image 渐变gradient()那些事!
- OAK-D树莓派点云项目【附详细代码】
- Using JSON server to create server requests locally
- 阿里研发三面,面试官一套组合拳让我当场懵逼
- Install MySQL on MAC
- 力扣-198.打家劫舍
- Findstr is not an internal or external command workaround
猜你喜欢
RecyclerView advanced use - to realize drag and drop function of imitation Alipay menu edit page
磁盘管理与文件系统
Phpstudy V8, a commonly used software for station construction 1 graphic installation tutorial (Windows version) super detailed
建站常用软件PhpStudy V8.1图文安装教程(Windows版)超详细
451. 根据字符出现频率排序
Install redis and deploy redis high availability cluster
What is the experience of using prophet, an open source research tool?
Ice -- source code analysis
Cartoon: what are IAAs, PAAS, SaaS?
Countdown 1 day ~ 2022 online conference of cloud disaster tolerance products is about to begin
随机推荐
各大框架都在使用的Unsafe类,到底有多神奇?
MySQL的btree索引和hash索引区别
Grbl learning (I)
Win11/10家庭版禁用Edge的inprivate浏览功能
Hypermotion cloud migration completes Alibaba cloud proprietary cloud product ecological integration certification
The first line and the last two lines are frozen when paging
Use if else to judge in sail software - use the title condition to judge
建站常用软件PhpStudy V8.1图文安装教程(Windows版)超详细
捡起MATLAB的第(4)天
ESP32_ Arduino
Interview question 17.10 Main elements
捡起MATLAB的第(7)天
通过Feign在服务之间传递header请求头信息
JMeter setting environment variable supports direct startup by entering JMeter in any terminal directory
5分钟NLP:Text-To-Text Transfer Transformer (T5)统一的文本到文本任务模型
七朋元视界可信元宇宙社交体系满足多元化的消费以及社交需求
Day 9 static abstract class interface
Esxi encapsulated network card driver
Query the data from 2013 to 2021, and only query the data from 2020. The solution to this problem is carried out
Solution to the fourth "intelligence Cup" National College Students' IT skills competition (group B of the final)