JAVA项目实战-微信小程序服务端开发(二)
本节继续分享微信小程序端,实现小程序服务端图片识别功能,包括:识别身份证,营业执照,行驶证,驾驶证,文本信息等(具体文档参考:https://developers.weixin.qq.com/miniprogram/dev/framework/)
======================================================
图片识别工具类
======================================================
package com.sf.vsolution.hb.sfce.util.wechat.discern; import com.alibaba.fastjson.JSON; import com.sf.vsolution.hb.sfce.config.execption.MyRuntimeException; import com.sf.vsolution.hb.sfce.util.FuntionUtils; import com.sf.vsolution.hb.sfce.util.wechat.appletService.AppletServiceConstants; import com.sf.vsolution.hb.sfce.util.wechat.discern.param.*; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @description: 图像识别工具类 * @author: zhucj * @date: 2019-10-17 9:18 */ @Slf4j @Component public class DiscernImgUtil { @Value("${applet.appId}") private String appId; @Value("${applet.secret}") private String secret; @Value("${applet.secret.discern.imgPath}") private String discernPath; @Autowired private StringRedisTemplate redis; /** * 小程序端图片识别 * @param discernRequest * 1:识别 * @return */ @ApiOperation(value = "小程序服务端-图片识别") @ApiImplicitParams({ @ApiImplicitParam(value = "discernType",name = "识别类型(1:银行卡 2:营业执照 3:驾驶证 4:身份证 5:通用印刷体 6:行驶证)" ,required = true,dataType = "Integer"), @ApiImplicitParam(value = "msg",name = "图片的MultipartFile对象(暂时只支持传照片,未写照片连接情况)",required = true,dataType = "MultipartFile"), @ApiImplicitParam(value = "imgType",name = "图片识别模式 1:photo(拍照模式) 2:scan(扫描模式)",required = true,dataType = "Integer") }) public R appletDiscern(DiscernRequest discernRequest){ switch (discernRequest.getImgType()){ case 1: discernRequest.setType("photo"); break; case 2: discernRequest.setType("scan"); break; default: throw new DisCernImgException(SystemConstants.PARAM_INCORRECT_CODE,AppletDiscernConstant.IMG_TYPE_ERROR); } //封装图片数据 Map mapImg = new HashMap(); //封装参数 Map mapParam = new HashMap<>(); mapParam.put("type",discernRequest.getType()); mapParam.put("access_token",getToken()); MultipartFile msg = discernRequest.getMsg(); mapImg.put("img",uploadFile(discernPath+ genRandomName()+".jpg",msg)); String url = null; Class object = null; switch (discernRequest.getDiscernType()){ case 1: url = DisCernImgApi.ORC_BANKCARD.getServerName(); object = BankCard.class; break; case 2: url = DisCernImgApi.ORC_BIZLICENSE.getServerName(); object = Bizlicense.class; break; case 3: url = DisCernImgApi.ORC_DRIVINGLICENSE.getServerName(); object = DriverLicense.class; break; case 4: url = DisCernImgApi.ORC_IDCARD.getServerName(); object = IDCard.class; break; case 5: url = DisCernImgApi.ORC_COMM.getServerName(); object = PrintedText.class; break; case 6: url = DisCernImgApi.ORC_DRIVING.getServerName(); break; default: throw new DisCernImgException(SystemConstants.PARAM_INCORRECT_CODE,AppletDiscernConstant.DIECERN_TYPE_ERROR); } String result = HttpClientUtil.postFormData(url, mapParam, mapImg, "image/png"); log.info("响应信息内容:{}",result); DiscernCommonResponse discernCommonResponse = JSON.parseObject(result, DiscernCommonResponse.class); if (Objects.equals(AppletDiscernConstant.SUCCESS, discernCommonResponse.getErrcode())){ return R.ok(JSON.parseObject(result,object)); }else { log.error("获取照片信息失败:{}", discernCommonResponse.getErrcode()); return R.ok(discernCommonResponse.getErrmsg()); } } /** * 小程序授权 * @return accessToken * @throws DisCernImgException */ public String getToken(){ //先从缓存中判断是否存在 String redisString = redis.opsForValue().get(AppletDiscernConstant.ACCESS_TOKEN); if (Objects.nonNull(redisString)){ return redisString; } String reqUrl = AppletServiceConstants.ACCESS_TOKEN_API; Map map = new HashMap(); map.put("grant_type","client_credential"); map.put("appid",appId); map.put("secret",secret); String result = HttpClientUtil.doGet(reqUrl, map); AuthAccessTokenResponse auth = JSON.parseObject(result, AuthAccessTokenResponse.class); //判断errcode ==0 即请求成功 if (Objects.equals(auth.getErrcode(),AppletServiceConstants.SUCCESS_CODE)){ log.info("获取的accessToken值:{}",auth.getAccess_token()); //将accessToken存入到redis 设置过期时间 redis.opsForValue().set(AppletServiceConstants.ACCESS_TOKEN,auth.getAccess_token(),AppletServiceConstants.EXPIRES_IN, TimeUnit.SECONDS); return auth.getAccess_token(); }else { log.error("小程序授权失败返回错误码:{},错误信息:{}",auth.getErrcode(),auth.getErrmsg()); throw new DisCernImgException(SystemConstants.SERVER_ERROR_CODE,AppletDiscernConstant.ACCESS_TOKRN_ERROR); } } /** * 上传文件到本地服务器磁盘 * @param fileName 上传文件路径名称 * 例如: /static/upload/121321321.jpg * E:/upload/img/12013212.jpg * @param file * @return */ public static String uploadFile(String fileName, MultipartFile file){ //服务器端保存的文件对象 File serverFile= new File(fileName); try { //判断文件是否已经存在 if (serverFile.exists()) { throw new DisCernImgException(SystemConstants.PARAM_INCORRECT_CODE,"文件已存在"); } //判断文件父目录是否存在 if (!serverFile.getParentFile().exists()) { serverFile.getParentFile().mkdir(); } //将上传的文件写入到服务器端文件内 file.transferTo(serverFile); } catch (IOException e) { e.printStackTrace(); return null; } return fileName; }
public static String genRandomName() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//加上三位随机数
Random random = new Random();
int end3 = random.nextInt(999);
//如果不足三位前面补0
String str = millis + String.format("%03d", end3);
return str;
}
}
=================================================
封装类,常量类,异常类
=================================================
package com.sf.vsolution.hb.sfce.util.wechat.discern; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import javax.activation.MimetypesFileTypeMap; import java.io.*; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.util.Iterator; import java.util.Map; /** * @description: get/post请求工具类 * @author: zhucj * @date: 2019-04-26 10:10 */ @Slf4j public class HttpClientUtil { /** * 发送get请求 * @param url * @param param * @return */ public static String doGet(String url, Map<String, String> param) { log.info("GET请求地址:{},请求参数内容:{}",url, JSON.toJSON(param)); // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpGet httpGet = new HttpGet(uri); // 执行请求 response = httpclient.execute(httpGet); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); log.error("网络出现异常:{}",e.getMessage()); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); log.error("IO出现异常:{}",e.getMessage()); } } log.info("GET响应参数:{}",resultString); return resultString; } /** * 发送post请求 * @param url * @param param * @return */ public static String doPostParam(String url, Map<String, String> param) { log.info("GET请求地址:{},请求参数内容:{}",url, JSON.toJSON(param)); // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { // 创建uri URIBuilder builder = new URIBuilder(url); if (param != null) { for (String key : param.keySet()) { builder.addParameter(key, param.get(key)); } } URI uri = builder.build(); // 创建http GET请求 HttpPost httpPost = new HttpPost(uri); // 执行请求 response = httpclient.execute(httpPost); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { resultString = EntityUtils.toString(response.getEntity(), "UTF-8"); } } catch (Exception e) { e.printStackTrace(); log.error("网络出现异常:{}",e.getMessage()); } finally { try { if (response != null) { response.close(); } httpclient.close(); } catch (IOException e) { e.printStackTrace(); log.error("IO出现异常:{}",e.getMessage()); } } log.info("GET响应参数:{}",resultString); return resultString; } /** * 发post请求 传入xml/json字符串 * @param url * @param json * @return */ public static String doPostJson(String url, String json) { log.info("POST请求地址:{},请求参数内容:{}",url,json); // 创建Httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String resultString = ""; try { // 创建Http Post请求 HttpPost httpPost = new HttpPost(url); // 创建请求内容 StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); httpPost.setEntity(entity); // 执行http请求 response = httpClient.execute(httpPost); resultString = EntityUtils.toString(response.getEntity(), "utf-8"); } catch (Exception e) { e.printStackTrace(); log.error("网络出现异常:{}",e.getMessage()); } finally { try { response.close(); } catch (IOException e) { e.printStackTrace(); log.error("IO出现异常:{}",e.getMessage()); } } log.info("POST响应参数:{}",resultString); return resultString; } /** * 发送文件和参数 * @param urlStr * @param textMap * @param fileMap * @param contentType 没有传入文件类型默认采用application/octet-stream * contentType非空采用filename匹配默认的图片类型 * @return 返回response数据 */ @SuppressWarnings("rawtypes") public static String postFormData(String urlStr, Map<String, String> textMap, Map<String, String> fileMap,String contentType) { String res = ""; HttpURLConnection conn = null; // boundary就是request头和上传文件内容的分隔符 String BOUNDARY = "---------------------------123821742118716"; try { URL url = new URL(urlStr); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(30000); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Connection", "Keep-Alive"); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); OutputStream out = new DataOutputStream(conn.getOutputStream()); // text if (textMap != null) { StringBuffer strBuf = new StringBuffer(); Iterator iter = textMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); String inputName = (String) entry.getKey(); String inputValue = (String) entry.getValue(); if (inputValue == null) { continue; } strBuf.append("\r\n").append("--").append(BOUNDARY) .append("\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n"); strBuf.append(inputValue); } out.write(strBuf.toString().getBytes()); } // file if (fileMap != null) { Iterator iter = fileMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); String inputName = (String) entry.getKey(); String inputValue = (String) entry.getValue(); if (inputValue == null) { continue; } File file = new File(inputValue); String filename = file.getName(); //没有传入文件类型,同时根据文件获取不到类型,默认采用application/octet-stream contentType = new MimetypesFileTypeMap().getContentType(file); //contentType非空采用filename匹配默认的图片类型 if(!"".equals(contentType)){ if (filename.endsWith(".png")) { contentType = "image/png"; }else if (filename.endsWith(".jpg") || filename.endsWith(".jpeg") || filename.endsWith(".jpe")) { contentType = "image/jpeg"; }else if (filename.endsWith(".gif")) { contentType = "image/gif"; }else if (filename.endsWith(".ico")) { contentType = "image/image/x-icon"; } } if (contentType == null || "".equals(contentType)) { contentType = "application/octet-stream"; } StringBuffer strBuf = new StringBuffer(); strBuf.append("\r\n").append("--").append(BOUNDARY) .append("\r\n"); strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename + "\"\r\n"); strBuf.append("Content-Type:" + contentType + "\r\n\r\n"); out.write(strBuf.toString().getBytes()); DataInputStream in = new DataInputStream( new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while ((bytes = in.read(bufferOut)) != -1) { out.write(bufferOut, 0, bytes); } in.close(); } } byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); out.write(endData); out.flush(); out.close(); // 读取返回数据 StringBuffer strBuf = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader( conn.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { strBuf.append(line).append("\n"); } res = strBuf.toString(); reader.close(); reader = null; } catch (Exception e) { System.out.println("发送POST请求出错。" + urlStr); e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); conn = null; } } return res; } }
package com.sf.vsolution.hb.sfce.util.wechat.discern; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.ToString; import java.io.Serializable; /** * 返回类型 * @author choleece * @date 2018/9/27 */ @ApiModel @ToString public class R<T> implements Serializable { private static final long serialVersionUID = -6287952131441663819L; /** * 编码 */ @ApiModelProperty(value = "响应码", example = "200") private int code = 200; /** * 成功标志 */ @ApiModelProperty(value = "成功标志", example = "true") private Boolean success; /** * 返回消息 */ @ApiModelProperty(value = "返回消息说明", example = "操作成功") private String msg="操作成功"; /** * 返回数据 */ @ApiModelProperty(value = "返回数据") private T data; /** * 创建实例 * @return */ public static R instance() { return new R(); } public int getCode() { return code; } public R setCode(int code) { this.code = code; return this; } public Boolean getSuccess() { return success; } public R setSuccess(Boolean success) { this.success = success; return this; } public String getMsg() { return msg; } public R setMsg(String msg) { this.msg = msg; return this; } public T getData() { return data; } public R setData(T data) { this.data = data; return this; } public static R ok() { return R.instance().setSuccess(true); } public static R ok(Object data) { return ok().setData(data); } public static R ok(Object data, String msg) { return ok(data).setMsg(msg); } public static R error() { return R.instance().setSuccess(false); } public static R error(String msg) { return error().setMsg(msg); } /** * 无参 */ public R() { } public R(int code, String msg) { this.code = code; this.msg = msg; } public R(int code, T data){ this.code = code; this.data = data; } /** * 有全参 * @param code * @param msg * @param data * @param success */ public R(int code, String msg, T data, Boolean success) { this.code = code; this.msg = msg; this.data = data; this.success = success; } /** * 有参 * @param code * @param msg * @param data */ public R(int code, String msg, T data) { this.code = code; this.msg = msg; this.data = data; } }
package com.sf.vsolution.hb.sfce.util.wechat.discern; /** * @description: 图片识别异常 * @author: zhucj * @date: 2019-10-17 10:16 */ public class DisCernImgException extends RuntimeException { private Integer errcode; private String errmsg; public DisCernImgException(Integer errcode, String errmsg) { this.errcode = errcode; this.errmsg = errmsg; } public Integer getErrcode() { return errcode; } public void setErrcode(Integer errcode) { this.errcode = errcode; } public String getErrmsg() { return errmsg; } public void setErrmsg(String errmsg) { this.errmsg = errmsg; } }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; /** * @description: 小程序API常量 * @author: zhucj * @date: 2019-09-17 18:25 */ public class AppletDiscernConstant { /** * 小程序登录API */ public static final String AUTH_CODE_API = "https://api.weixin.qq.com/sns/jscode2session"; /** * accessToken授权API */ public static final String ACCESS_TOKEN_API = "https://api.weixin.qq.com/cgi-bin/token"; /** * 客服消息API */ public static final String MESSAGE_SEND_API = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; /** * accessToken缓存key */ public static final String ACCESS_TOKEN = "ACCESS_TOKEN"; public static final Integer EXPIRES_IN = 7000; //TODO: 异常信息状态 public static final String ACCESS_TOKRN_ERROR = "小程序授权获取accessToken失败"; public static final String DIECERN_TYPE_ERROR = "diecernType传参格式不支持"; public static final String IMG_TYPE_ERROR = "imgType传参格式不支持"; public static final String SUCCESS = "0"; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import com.sf.vsolution.hb.sfce.util.wechat.appletService.param.CommonResponse; import lombok.*; /** * @description: 小程序获取AccessToken返回参数 * @author: zhucj * @date: 2019-11-14 16:43 */ @Data @Builder @NoArgsConstructor @AllArgsConstructor @ToString public class AuthAccessTokenResponse extends CommonResponse { /** * 获取到的凭证 */ private String access_token; /** * 凭证有效时间,单位:秒。目前是7200秒之内的值。 */ private Integer expires_in; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Data; /** * @description: 识别银行卡号返回参数 * @author: zhucj * @date: 2019-10-17 12:55 */ @Data public class BankCard extends DiscernCommonResponse { /** * 银行卡号 */ private String number; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Data; /** * @description: 识别营业执照返回参数 * @author: zhucj * @date: 2019-10-17 12:57 */ @Data public class Bizlicense extends DiscernCommonResponse { /** * 注册号 */ private String reg_num; /** * 编号 */ private String serial; /** * 法定代表人姓名 */ private String legal_representative; /** * 企业名称 */ private String enterprise_name; /** * 组成形式 */ private String type_of_organization; /** * 经营场所/企业住所 */ private String address; /** * 公司类型 */ private String type_of_enterprise; /** * 经营范围 */ private String business_scope; /** * 注册资本 */ private String registered_capital; /** * 实收资本 */ private String paid_in_capital; /** * 营业期限 */ private String valid_period; /** * 注册日期/成立日期 */ private String registered_date; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.*; /** * @description: 通用返回参数 * @author:zhucj * @date: 2019-10-17 9:25 */ @Data @AllArgsConstructor @NoArgsConstructor @Builder @ToString public class DiscernCommonResponse { /** * 响应编码 */ private String errcode; /** * 响应消息 */ private String errmsg; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; /** * @description: 图片识别常量 * @author: zhucj * @date: 2019-10-17 9:48 */ public class DisCernConstant { /** * 共用接口 */ public static final String WX_DISCERN_SERVER_API = "https://api.weixin.qq.com"; /** * 小程序的银行卡 OCR 识别 */ public static final String WX_BANKCARD_DISCERN_SERVER_NAME = "/cv/ocr/bankcard"; /** * 小程序的营业执照 OCR 识别 */ public static final String WX_BUCINESS_DISCERN_SERVER_NAME = "/cv/ocr/bizlicense"; /** * 小程序的驾驶证 OCR 识别 */ public static final String WX_DRIVER_DISCERN_SERVER_NAME = "/cv/ocr/drivinglicense"; /** * 小程序的身份证 OCR 识别 */ public static final String WX_IDCARD_DISCERN_SERVER_NAME = "/cv/ocr/idcard"; /** * 小程序的通用印刷体 OCR 识别 */ public static final String WX_PRINTED_DISCERN_SERVER_NAME = "/cv/ocr/comm"; /** * 小程序的行驶证 OCR 识别 */ public static final String WX_DRIVING_DISCERN_SERVER_NAME = "/cv/ocr/driving"; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import com.sf.vsolution.hb.sfce.util.wechat.discern.param.DisCernConstant; /** * @description: 图片识别API * @author: zhucj * @date: 2019-10-17 9:44 */ public enum DisCernImgApi { /** * 小程序端识别 */ ORC_BANKCARD(1, DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_BANKCARD_DISCERN_SERVER_NAME), ORC_BIZLICENSE(2,DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_BUCINESS_DISCERN_SERVER_NAME), ORC_DRIVINGLICENSE(3,DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_DRIVER_DISCERN_SERVER_NAME), ORC_IDCARD(4,DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_IDCARD_DISCERN_SERVER_NAME), ORC_COMM(5,DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_PRINTED_DISCERN_SERVER_NAME), ORC_DRIVING(6,DisCernConstant.WX_DISCERN_SERVER_API+DisCernConstant.WX_DRIVING_DISCERN_SERVER_NAME) ; private int discernType; private String serverName; DisCernImgApi(int discernType, String serverName) { this.discernType = discernType; this.serverName = serverName; } public int getDiscernType() { return discernType; } public void setDiscernType(int discernType) { this.discernType = discernType; } public String getServerName() { return serverName; } public void setServerName(String serverName) { this.serverName = serverName; } }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Builder; import lombok.Data; import org.springframework.web.multipart.MultipartFile; /** * @description: 识别请求信息 * @author: zhucj * @date: 2019-10-17 9:31 */ @Data @Builder public class DiscernRequest { /** * 识别类型 * 1:银行卡 2:营业执照 3:驾驶证 4:身份证 5:通用印刷体 6:行驶证 */ private Integer discernType; /** * 图片识别模式 1:photo(拍照模式) 2:scan(扫描模式) */ private Integer imgType; /** * form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传 img_url */ private MultipartFile msg; private String type; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Data; /** * @description: 识别驾驶证返回参数 * @author: zhucj * @date: 2019-11-15 13:51 */ @Data public class DriverLicense extends DiscernCommonResponse { /** * 证号 */ private String id_num; /** * 姓名 */ private String name; /** *性别 */ private String sex; /** * address */ private String address; /** * 出生日期 */ private String birth_date; /** * 初次领证日期 */ private String issue_date; /** * 准驾车型 */ private String car_class; /** * 有效期限起始日 */ private String valid_from; /** * 有效期限终止日 */ private String valid_to; /** * 印章文构 */ private String official_seal; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Data; /** * @description: 身份证识别返回参数 * @author: zhucj * @date: 2019-11-15 14:02 */ @Data public class IDCard extends DiscernCommonResponse { /** * 姓名 */ private String name; /** * 身份证号 */ private String id; /** * 地址 */ private String addr; /** * 性别 */ private String gender; /** * 民族 */ private String nationality; /** * 正面或背面,Front / Back */ private String type; /** * 有效期(type = back 才有) */ private String validDate; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; import lombok.Data; /** * @description: * @author:zhucj * @date: 2019-10-17 15:22 */ @Data public class PrintedText extends DiscernCommonResponse { private String items; private String img_size; }
package com.sf.vsolution.hb.sfce.util.wechat.discern.param; /** * @ClassName SystemConstants * @Description 常量字段 * @Author zhucj * @Date 2019/5/7 11:13 * @Version 1.0 **/ public class SystemConstants { /** 传参不规范,code:400*/ public static final Integer PARAM_INCORRECT_CODE = 400; /** 成功,code:200*/ public static final Integer SUCCESS_CODE = 200; /** 服务内部调用失败,code:500*/ public static final Integer SERVER_ERROR_CODE = 500; /** 登录失效,code:401*/ public static final Integer AUTH_FAIL_CODE = 401; /** 无对应接口权限,code:402*/ public static final Integer HAVE_NOT_PERMISSION_CODE = 402; /** 操作无记录,code:403*/ public static final Integer NO_RECORD_OPERATION = 403; }
#小程序参数 applet: appId: ***** secret: ***** discern: #识别图片保存地址 imgPath: E:/upload/img/
<!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> <scope>provided</scope> </dependency> <!--htttpclient依赖--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.5</version> </dependency> <!-- swagger API --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.0</version> </dependency>