是一个小需求,但是用到以前没用过的东西,保存一下
首先分析一下:别人需要使用我们平台的某特定功能,而我们不动平台源码的情况下,流程可拆为如下:
获取(校验)请求参数=>登录平台(获取session)=>调用相关接口=>处理异常=>返回(封装)数据
所以接下来上代码
pom.xml里引入常用的lombok和hutool
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.7</version>
</dependency>
文档里端口为7788,所以要在application.properties里配一下
server.port=7788
logging.file.path=D:/log
忘了贴一下全局代码
接下来配一下实体类,请求类【RequestDTO】,返回类【BaseResponse】,返回异常枚举【ResponseEnum】
package com.yitu.face.verify.model;
import lombok.Data;
/**
* Created by DQ on 2020/6/23/023.
*/
@Data
public class RequestDTO {
private String db_image;
private String db_image_type;
private String query_image1;
private String query_image2;
private String query_image3;
}
package com.yitu.face.verify.model;
import lombok.Data;
/**
* Created by DQ on 2020/6/23/023.
*/
@Data
public class BaseResponse {
// Y 0:比对未通过 1:比对通过,其他:比对失败代码
protected Integer code;
// n 比对失败原因
protected String message;
// Y 人脸比对相似度,取值0-100
protected String similarity;
public BaseResponse() {
this(ResponseEnum.SUCCESS);
}
public BaseResponse(ResponseEnum errorCode) {
this.code = errorCode.getRtn();
this.message = errorCode.getMessage();
}
public BaseResponse(ResponseEnum errorCode, String message) {
this.code = errorCode.getRtn();
this.message = message;
}
public boolean valid() {
return 1 == this.code;
}
}
package com.yitu.face.verify.model;
/**
* 返回状态码枚举类
*
*/
public enum ResponseEnum {
SUCCESS(1, "ok"),
/**
* 服务器异常
*/
SERVER_ERROR(0, "服务器异常,请稍后重试"),
/**
* 前台请求参数错误
*/
BAD_REQUEST_PARAMETER1(-1, "请求参数db_image和db_image_type不能为空!"),
BAD_REQUEST_PARAMETER2(-2, "请求参数query_image1,query_image2,query_image3不能全为空!"),
/**
* 请求错误
*/
BAD_REQUEST(-3, "请求参数不符合规定"),
/**
* 请求的Content-Type错误
*/
MEDIA_TYPE_NOT_SUPPORTED(-4, "请求的Content-Type错误"),
/**
* 请求的方法错误
*/
METHOD_NOT_SUPPORTED(-5, "请求方法不支持"),
HTTP_ERROR(7, "http请求出错"),
;
private Integer rtn;
private String message;
ResponseEnum(Integer rtn, String message) {
this.rtn = rtn;
this.message = message;
}
public Integer getRtn() {
return rtn;
}
public String getMessage() {
return message;
}
}
配一下controller
package com.yitu.face.verify.controller;
import cn.hutool.core.util.StrUtil;
import com.yitu.face.verify.model.BaseResponse;
import com.yitu.face.verify.model.RequestDTO;
import com.yitu.face.verify.model.ResponseEnum;
import com.yitu.face.verify.service.VerifyService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* Created by DQ on 2020/6/23/023.
*/
@RestController
@RequestMapping("/face")
@Api(value = "VerifyMain接口", tags = {"1:1人脸比对接口"})
public class VerifyMain {
@Autowired
VerifyService verifyService;
/*
* @param RequestDTO 比对的json串转为的实体
* @return BaseResponse 比对结果
* */
@PostMapping("/compare")
@ApiOperation(value = "比对两个图片base64相似度")
@ApiResponses(value = { @ApiResponse(code = 1, message = "成功"), @ApiResponse(code = -1, message = "请求参数db_image和db_image_type不能为空!"),
@ApiResponse(code = -2, message = "请求参数query_image1,query_image2,query_image3不能全为空!"), @ApiResponse(code = -3, message = "请求参数不符合规定")})
public BaseResponse login(HttpServletRequest request, @ApiParam("请求json实体") @RequestBody RequestDTO requestDTO) {
if(StrUtil.isBlank(requestDTO.getDb_image()) || StrUtil.isBlank(requestDTO.getDb_image_type())){
return new BaseResponse(ResponseEnum.BAD_REQUEST_PARAMETER1);
}
return verifyService.compare(requestDTO, request);
}
}
controller获取参数,这时候先别急到service里,先处理一下可能出现的异常
package com.yitu.face.verify.global;
import com.yitu.face.verify.model.BaseResponse;
import com.yitu.face.verify.model.ResponseEnum;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Created by DQ on 2020/6/23/023.
*/
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 系统异常捕获处理
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public BaseResponse exception(Exception e) {
System.out.println(e.getMessage());
//请求参数问题
if (e instanceof HttpMessageNotReadableException) {
return new BaseResponse(ResponseEnum.BAD_REQUEST);
}
//请求Content type不支持
if (e instanceof HttpMediaTypeNotSupportedException) {
return new BaseResponse(ResponseEnum.MEDIA_TYPE_NOT_SUPPORTED);
}
//请求方法不支持
if (e instanceof HttpRequestMethodNotSupportedException) {
return new BaseResponse(ResponseEnum.METHOD_NOT_SUPPORTED);
}
return new BaseResponse(ResponseEnum.SERVER_ERROR);
}
}
请求参数到达service,还要经过具体的校验,符合才继续走流程
public BaseResponse compare(RequestDTO requestDTO, HttpServletRequest request){
String query_image;
String query_image1 = requestDTO.getQuery_image1();
String query_image2 = requestDTO.getQuery_image2();
String query_image3 = requestDTO.getQuery_image3();
if(StrUtil.isBlank(query_image1)){
if(StrUtil.isBlank(query_image2)){
if(StrUtil.isBlank(query_image3)){
return new BaseResponse(ResponseEnum.BAD_REQUEST_PARAMETER2);
}else {
query_image = query_image3;
}
}else {
query_image = query_image2;
}
}else {
query_image = query_image1;
}
return compareToPlat(requestDTO.getDb_image(), query_image);
}
接下来开始正式的业务
//校验是否base64,然后走两道接口(抽特征和比对)
private BaseResponse compareToPlat(String query1,String query2){
BaseResponse baseResponse = new BaseResponse();
String cookie = httpUtils.loginFp();
if(!isBase64(query1) || !isBase64(query2)){
return new BaseResponse(ResponseEnum.BAD_REQUEST);
}
String feature_base64_1 = toFeatureBase64(query1, cookie);
String feature_base64_2 = toFeatureBase64(query2, cookie);
String body = JSONUtil.createObj()
.set("feature_base64_1", feature_base64_1)
.set("feature_base64_2", feature_base64_2)
.toString();
String post2 = httpUtils.post2(body, cookie, true);
JSONObject parseObj = JSONUtil.parseObj(post2);
if(parseObj.getInt("rtn") == 0){
String str = parseObj.getStr("similarity");
double similarity = Double.parseDouble(str);
baseResponse.setSimilarity(NumberUtil.decimalFormat("00.00", similarity));
baseResponse.setMessage("ok");
baseResponse.setCode(1);
}else {
baseResponse.setCode(0);
baseResponse.setMessage("比对失败");
baseResponse.setSimilarity(null);
}
return baseResponse;
}
private String toFeatureBase64(String imgBase64, String cookie){
String post = httpUtils.post(imgBase64, cookie, true);
logger.info(post);
if(StrUtil.isNotBlank(post)){
JSONObject parseObj = JSONUtil.parseObj(post);
if(parseObj.getInt("rtn") == 0){
JSONObject result = parseObj.getJSONArray("results").getJSONObject(0);
post = result.getStr("feature_base64");
}
}
return post;
}
private static boolean isBase64(String str) {
String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
return Pattern.matches(base64Pattern, str);
}
大致流程已经走完,其中一些http请求工具和json处理都是用hutool现成的
里面还有个坑我有空再填一下,session的过期问题~
Java老菜鸡一个,记录代码生活,不喜勿喷,欢迎指正错误和提意见~