阅读背景:

百度智能云-身份证验证(完整版-直接用)

来源:互联网 
百度云网址:

https://cloud.baidu.com

身份验证的技术文档:

技术代码: 导入依赖: <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.12.13</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.12.13</version> <scope>compile</scope> </dependency> // JSONObject的依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency> // io流的依赖 <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> //hutool <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency> 控制层: /*** * 身份证验证上传图片接口 */ @PostMapping ("identityToken/{param}") public Result identityToken(@PathVariable("param")Integer param , MultipartFile file, HttpServletRequest request) throws IOException { System.out.println("图片=="+file); CereBuyerUser user = (CereBuyerUser) request.getAttribute("user"); return agentUserService.identityToken(user,file,param); } 处理的事物层 Result identityToken(CereBuyerUser user, MultipartFile file,Integer param) throws IOException; package com.example.demo.service.Impl; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONObject; import com.example.demo.service.AgentUserService; import com.example.demo.util.Base64Util; import com.example.demo.util.FileUtil; import com.example.demo.util.HttpUtils; import okhttp3.*; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.UUID; import static com.example.demo.util.IdentityCardUtil.*; @Service public class AgentUserServiceImpl implements AgentUserService { static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build(); @Value("${identity.url}") private String identityUrl; @Value("${identity.apiKey}") private String apiKey; @Value("${identity.secrtetKey}") private String secrtetKey; /** * 身份验证 * @param * @return */ @Override public String identityToken(MultipartFile file, String param) throws IOException { //获得身份验证token MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "&client_id=" + apiKey + "&client_secret=" + secrtetKey); Request request = new Request.Builder() .url(URLREQUEST) .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = HTTP_CLIENT.newCall(request).execute(); JSONObject jsonObject = JSONObject.parseObject(response.body().string()); String accessToken = jsonObject.getString("access_token"); //todo 图片地址 String filename1 = file.getOriginalFilename(); String ext="."+ FilenameUtils.getExtension(filename1); String uuid= UUID.randomUUID().toString().replace("-",""); //图片名称 String filename = uuid + ext; //图片保存的位置 String Path = identityUrl; String filePath=Path+filename; System.out.println("filePath=="+filePath); try { //上传图片的路径 file.transferTo(new File(filePath)); //身份证验证 if(param.equals("1")){ if (identityNationalEmblem(accessToken,filePath)){ return "身份证校验成功"; }else { return "身份证校验失败,请重新上传"; } }else if (param.equals("2")){ return identityVerifyFace(accessToken,filePath); } } catch (IOException e) { //删除文件 new File(filePath).delete(); return "上传失败"; } return null; } /** * 身份证带国徽的一面 * @param accessToken * @param filePath * @return * @throws IOException */ private boolean identityNationalEmblem(String accessToken, String filePath) throws IOException { try { byte[] imgData = FileUtil.readFileByBytes(filePath); String imgStr = Base64Util.encode(imgData); String imgParam = URLEncoder.encode(imgStr, "UTF-8"); //拼接参数 String param = "id_card_side=%s" + "&image=%s" + "&detect_risk=%s"; String format = String.format(param,"back", imgParam,true); System.out.println("拼接参数=="+format); // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。 String result = HttpUtils.post(URLGET, accessToken, format); JSONObject jsonObjects = JSONObject.parseObject(result); String riskType = jsonObjects.getString("risk_type"); if (!NORMALONE.equals(riskType)) { //删除文件 new File(filePath).delete(); System.out.println("请上传有效身份证"); return false; } //身份证信息 // String expiryDate = jsonObjects.getJSONObject("words_result").getJSONObject("失效日期").getString("words"); // String issuingAuthority = jsonObjects.getJSONObject("words_result").getJSONObject("签发机关").getString("words"); // String dateOfIssue = jsonObjects.getJSONObject("words_result").getJSONObject("签发日期").getString("words"); //删除文件 new File(filePath).delete(); return true; } catch (Exception e) { //删除文件 new File(filePath).delete(); return false; } } /** * 核验人脸信息 * @param accessToken * @param filePath * @return * @throws IOException */ private String identityVerifyFace(String accessToken, String filePath) throws IOException { try { byte[] imgData = FileUtil.readFileByBytes(filePath); String imgStr = Base64Util.encode(imgData); String imgParam = URLEncoder.encode(imgStr, "UTF-8"); //拼接参数 String param = "id_card_side=%s" + "&image=%s" + "&detect_risk=%s"; String format = String.format(param,"back", imgParam,true); // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。 String result = HttpUtils.post(URLGET, accessToken, format); JSONObject jsonObjects = JSONObject.parseObject(result); String riskType = jsonObjects.getString("risk_type"); if (!NORMALONE.equals(riskType)) { new File(filePath).delete(); System.out.println("请上传有效身份证"); return "请上传有效身份证"; } //身份证信息 String name = jsonObjects.getJSONObject("words_result").getJSONObject("姓名").getString("words"); String card = jsonObjects.getJSONObject("words_result").getJSONObject("公民身份号码").getString("words"); String nation = jsonObjects.getJSONObject("words_result").getJSONObject("民族").getString("words"); String address = jsonObjects.getJSONObject("words_result").getJSONObject("住址").getString("words"); String birthday = jsonObjects.getJSONObject("words_result").getJSONObject("出生").getString("words"); String sex = jsonObjects.getJSONObject("words_result").getJSONObject("性别").getString("words");; //修改经纪人的表 //保存身份证的基本信息 Map<String, Object> identityCardMap = new HashMap<>(); identityCardMap.put("name",name); identityCardMap.put("card",card); identityCardMap.put("nation",nation); identityCardMap.put("address",address); identityCardMap.put("birthday",birthday); identityCardMap.put("sex",sex); cn.hutool.json.JSONObject identityCardJson = JSONUtil.parseObj(identityCardMap); String identityCardJsons = JSONUtil.toJsonStr(identityCardJson); //传给前端 Map<String, Object> identityCardMessageMap = new HashMap<>(); identityCardMessageMap.put("identityCardJsons",identityCardJsons); identityCardMessageMap.put("name",name); identityCardMessageMap.put("card",card); //删除文件 new File(filePath).delete(); return identityCardMessageMap.toString(); } catch (Exception e) { //删除文件 new File(filePath).delete(); return "身份证上传失败"; } } } 工具类: FileUtil类: package com.shop.cereshop.app.utils; import java.io.*; /** * 文件读取工具类 */ public class FileUtil { /** * 读取文件内容,作为字符串返回 */ public static String readFileAsString(String filePath) throws IOException { File file = new File(filePath); if (!file.exists()) { throw new FileNotFoundException(filePath); } if (file.length() > 1024 * 1024 * 1024) { throw new IOException("File is too large"); } StringBuilder sb = new StringBuilder((int) (file.length())); // 创建字节输入流 FileInputStream fis = new FileInputStream(filePath); // 创建一个长度为10240的Buffer byte[] bbuf = new byte[10240]; // 用于保存实际读取的字节数 int hasRead = 0; while ( (hasRead = fis.read(bbuf)) > 0 ) { sb.append(new String(bbuf, 0, hasRead)); } fis.close(); return sb.toString(); } /** * 根据文件路径读取byte[] 数组 */ public static byte[] readFileByBytes(String filePath) throws IOException { File file = new File(filePath); if (!file.exists()) { throw new FileNotFoundException(filePath); } else { ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); BufferedInputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); short bufSize = 1024; byte[] buffer = new byte[bufSize]; int len1; while (-1 != (len1 = in.read(buffer, 0, bufSize))) { bos.write(buffer, 0, len1); } byte[] var7 = bos.toByteArray(); return var7; } finally { try { if (in != null) { in.close(); } } catch (IOException var14) { var14.printStackTrace(); } bos.close(); } } } } Base64Util类 package com.shop.cereshop.app.utils; /** * Base64 工具类 */ public class Base64Util { private static final char last2byte = (char) Integer.parseInt("00000011", 2); private static final char last4byte = (char) Integer.parseInt("00001111", 2); private static final char last6byte = (char) Integer.parseInt("00111111", 2); private static final char lead6byte = (char) Integer.parseInt("11111100", 2); private static final char lead4byte = (char) Integer.parseInt("11110000", 2); private static final char lead2byte = (char) Integer.parseInt("11000000", 2); private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; public Base64Util() { } public static String encode(byte[] from) { StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); int num = 0; char currentByte = 0; int i; for (i = 0; i < from.length; ++i) { for (num %= 8; num < 8; num += 6) { switch (num) { case 0: currentByte = (char) (from[i] & lead6byte); currentByte = (char) (currentByte >>> 2); case 1: case 3: case 5: default: break; case 2: currentByte = (char) (from[i] & last6byte); break; case 4: currentByte = (char) (from[i] & last4byte); currentByte = (char) (currentByte << 2); if (i + 1 < from.length) { currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); } break; case 6: currentByte = (char) (from[i] & last2byte); currentByte = (char) (currentByte << 4); if (i + 1 < from.length) { currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); } } to.append(encodeTable[currentByte]); } } if (to.length() % 4 != 0) { for (i = 4 - to.length() % 4; i > 0; --i) { to.append("="); } } return to.toString(); } } HttpUtils类 package com.shop.cereshop.app.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Map; /** * http 工具类 */ public class HttpUtils { public static String post(String requestUrl, String accessToken, String params) throws Exception { String contentType = "application/x-www-form-urlencoded"; return HttpUtils.post(requestUrl, accessToken, contentType, params); } public static String post(String requestUrl, String accessToken, String contentType, String params) throws Exception { String encoding = "UTF-8"; if (requestUrl.contains("nlp")) { encoding = "GBK"; } return HttpUtils.post(requestUrl, accessToken, contentType, params, encoding); } public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding) throws Exception { String url = requestUrl + "?access_token=" + accessToken; return HttpUtils.postGeneralUrl(url, contentType, params, encoding); } public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding) throws Exception { URL url = new URL(generalUrl); // 打开和URL之间的连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 设置通用的请求属性 connection.setRequestProperty("Content-Type", contentType); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); // 得到请求的输出流对象 DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.write(params.getBytes(encoding)); out.flush(); out.close(); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> headers = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : headers.keySet()) { System.err.println(key + "--->" + headers.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = null; in = new BufferedReader( new InputStreamReader(connection.getInputStream(), encoding)); String result = ""; String getLine; while ((getLine = in.readLine()) != null) { result += getLine; } in.close(); System.err.println("result:" + result); return result; } } 常量类: package com.shop.cereshop.app.utils; public class IdentityCardUtil { public static final String NORMALONE="normal"; public static final String URLGET="https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"; public static final String URLREQUEST="https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials"; } 配置类: #身份证临时路径 identity: url: D:\img\ apiKey: uLG4ydGWqiBRmwpbf3SozmY6 secrtetKey: cohaqpYa8iZVTCnMcfzFGM5XPOtoDmiQ 技术代码:



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: