文章目录

  • 总体设计
    • 数据库设计
    • 项目结构
      • 服务器项目结构
      • 客户端项目结构
      • 项目代码
        • controller代码
          • CitizenIdentityApiContriller.java
        • service层代码
          • MemberServiceImpl.java
          • CitizenIdentityServiceImpl .java
        • dao层
          • CitizenIdentityMapper.java
          • MemberMapper.java
        • 其他一些业务处理的工具类
          • OperationEnum.java
          • InvokerEnum.java
          • CitizenIdentityVO.java
          • ResponseVO.java
          • SystemVO.java
          • ResponseDTO.java
          • CitizenIdentity.java
          • Member.java
          • VerifyUtil.java
        • mapper配置文件
          • CitizenIdentityMapper.xml
          • MemberMapper.xml
          • application.properties
          • logback-spring.xml
    • 客户端
      • APIRequest.java
      • VerifyUtil.java
    • 运行结果

总体设计

数据库设计


项目结构

服务器项目结构

客户端项目结构

项目代码

controller代码

CitizenIdentityApiContriller.java
  1. **** 身份逻辑验证之后,会返回相应的查询结构
  2. /此为本人自己查阅资料的劳动成果,转载请注明链接/
    package com.mp.api.controller;

import com.mp.api.constant.InvokerEnum;
import com.mp.api.constant.OperationEnum;
import com.mp.api.dto.ResponseDTO;
import com.mp.api.entity.CitizenIdentity;
import com.mp.api.entity.Member;
import com.mp.api.service.CitizenIdentityService;
import com.mp.api.service.MemberService;
import com.mp.api.util.VerifyUtil;
import com.mp.api.vo.CitizenIdentityVO;
import com.mp.api.vo.ResponseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Objects;

/**

  • @ Author :MP…

  • @ Date :Created in 18:08 2019/6/28

  • @ Description:公民身份信息控制器

  • @ Modified By:

  • @Version: $
    */
    @RestController
    @RequestMapping("/citizen-identity")
    @Api(value = “CitizenIdentityApiContriller”, tags = {“公民身份信息查询接口”})
    public class CitizenIdentityApiContriller {

    @Autowired
    private MemberService memberService;
    @Autowired
    private CitizenIdentityService citizenIdentityService;

    /**

    • @Description: 根据公民姓名和身份证号查询身份信息
    • @Param: [citizenIdentityVO]
    • @return: ResponseDTO<ResponseVO>
    • @Author: MP.
    • @Date: 2019/6/28
      */
      @RequestMapping(value = “”, method = {RequestMethod.GET, RequestMethod.POST})
      @ApiOperation(value = “查询公民身份信息”, notes = “根据公民姓名和身份证号查询公民身份信息”)
      public ResponseDTO<ResponseVO> getCitizenIdentity(@ApiParam(name = “citizenIdentityVO”, value = “公民身份查询参数对象”, required = true) @Valid CitizenIdentityVO citizenIdentityVO) {
      //查询会员编号是否正确
      Member member = memberService.getMemberByMemberNo(citizenIdentityVO.getMemberNo());
      if (Objects.isNull(member)) {
      return ResponseDTO.fail(InvokerEnum.AUTH_FAIL);
      }
      //检查签名
      if (!VerifyUtil.checkSign(citizenIdentityVO, member.getSecretKey())) {
      return ResponseDTO.fail(InvokerEnum.SIGN_FAIL);
      }
      //查询公民身份信息
      CitizenIdentity citizenIdentity = citizenIdentityService.getCitizenIdentityByIdNo(citizenIdentityVO.getIdNo());
      if (Objects.isNull(citizenIdentity)) {
      return ResponseDTO.success(ResponseVO.fail(OperationEnum.NOT_EXISTS));
      }
      if (!Objects.equals(citizenIdentityVO.getName(), citizenIdentity.getName())) {
      return ResponseDTO.success(ResponseVO.fail(OperationEnum.NOT_MATCH));
      }
      return ResponseDTO.success(ResponseVO.success(citizenIdentity));
      }
      }

service层代码

MemberServiceImpl.java
  1. ****;
  2. package com.mp.api.service.impl;

import com.mp.api.entity.Member;
import com.mp.api.mapper.MemberMapper;
import com.mp.api.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**

  • @ Author :MP…

  • @ Date :Created in 15:03 2019/6/29

  • @ Description:身份信息服务接口

  • @ Modified By:

  • @Version: $
    */
    @Service
    public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    @Override
    public Member getMemberByMemberNo(String memberNo) {
    return memberMapper.getMemberByMemberNo(memberNo);
    }
    }

CitizenIdentityServiceImpl .java

/此为本人自己查阅资料的劳动成果,转载请注明链接/
package com.mp.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mp.api.entity.CitizenIdentity;
import com.mp.api.mapper.CitizenIdentityMapper;
import com.mp.api.service.CitizenIdentityService;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**

  • @ Author :MP…

  • @ Date :Created in 18:55 2019/6/28

  • @ Description:公民身份信息服务实现类

  • @ Modified By:

  • @Version: $
    */
    @Service
    public class CitizenIdentityServiceImpl extends ServiceImpl<CitizenIdentityMapper, CitizenIdentity> implements CitizenIdentityService {
    @Override
    public CitizenIdentity getCitizenIdentityByIdNo(String idNo) {

     return baseMapper.getCitizenIdentityByIdNo(idNo);
    

    }
    }

dao层

CitizenIdentityMapper.java
  1. package com.mp.api.mapper;

import com.mp.api.entity.CitizenIdentity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;

/**

  • @ Author :MP…

  • @ Date :Created in 18:31 2019/6/28

  • @ Description:公民身份信息 Mapper 接口

  • @ Modified By:

  • @Version: $
    */
    public interface CitizenIdentityMapper extends BaseMapper {

    /**

    • 根据身份证号查询身份信息
    • @param idNo
    • @return com.lx.api.entity.CitizenIdentity
    • @author zhuwenbin
    • @since 2019/3/1 14:52
      */
      @Select(“select * from citizen_identity where id_no = #{idNo}”)
      CitizenIdentity getCitizenIdentityByIdNo(String idNo);
      }
MemberMapper.java

package com.mp.api.mapper;

import com.mp.api.entity.Member;
import com.mp.api.entity.Member;
import org.apache.ibatis.annotations.Select;

/**

  • 会员信息访问接口
    */
    public interface MemberMapper {

    /**

    • 根据会员编号查询会员信息
    • @param memberNo
    • @return
      */
      @Select(“select * from member where member_no = #{memberNo}”)
      Member getMemberByMemberNo(String memberNo);

}

其他一些业务处理的工具类

OperationEnum.java
  1. package com.mp.api.constant;

public enum OperationEnum {

SUCCESS("0", ""), NOT_EXISTS("1", "身份信息不存在"),
NOT_MATCH("2", "姓名和身份证号不匹配");//业务处理状态码:0-成功;其他失败private String code;//业务处理错误信息private String msg;private OperationEnum(String code, String msg) {this.code = code;this.msg = msg;
}public String getCode() {return code;
}public void setCode(String code) {this.code = code;
}public String getMsg() {return msg;
}public void setMsg(String msg) {this.msg = msg;
}

}

InvokerEnum.java

package com.mp.api.constant;

public enum InvokerEnum {

SUCCESS("0", ""), SYSTEM_ERROR("1", "系统异常"),
ILLEGAL_ARGUMENT("10", "非法参数"), AUTH_FAIL("11", "会员身份认证失败"),
SIGN_FAIL("12", "签名验证失败");//接口调用状态码:0-成功,其他失败
private String retCode;//接口调用错误信息
private String retMsg;private InvokerEnum(String retCode,String retMsg ){this.retCode = retCode;this.retMsg = retMsg;
}public String getRetCode() {return retCode;
}public void setRetCode(String retCode) {this.retCode = retCode;
}public String getRetMsg() {return retMsg;
}public void setRetMsg(String retMsg) {this.retMsg = retMsg;
}

}

CitizenIdentityVO.java

package com.mp.api.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;

@ApiModel
@Data
public class CitizenIdentityVO extends SystemVO{

@ApiModelProperty(name = "name", value = "姓名", required = true)
@NotEmpty(message = "姓名不能为空")
@Pattern(regexp = "^[\\u4E00-\\u9FA5\\uf900-\\ufa2d·s]{2,20}$", message = "姓名格式不正确")
private String name;@NotEmpty(message = "身份证号码不能为空")
@Pattern(regexp = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)", message = "身份证号码格式不正确")
@ApiModelProperty(name = "idNo", value = "身份证号码", required = true)
private String idNo;public String getName() {return name;
}public void setName(String name) {this.name = name;
}public String getIdNo() {return idNo;
}public void setIdNo(String idNo) {this.idNo = idNo;
}

}

ResponseVO.java

package com.mp.api.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.mp.api.constant.OperationEnum;
import lombok.Data;

import java.io.Serializable;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseVO implements Serializable {

private static final long serialVersionUID = 1L;//业务处理成功与否,0为成功,其他值为失败
private String code;//业务处理失败信息
private String msg;private T content;public ResponseVO() {}public ResponseVO(String code, String msg) {this.code = code;this.msg = msg;
}public ResponseVO(String code, String msg, T content) {this.code = code;this.msg = msg;this.content = content;
}public ResponseVO(OperationEnum operationEnum) {this.code = operationEnum.getCode();this.msg = operationEnum.getMsg();
}/*** 业务处理成功** @param content* @return com.lx.api.vo.ResponseVO*/
public static <T extends Serializable> ResponseVO success(T content) {return new ResponseVO(OperationEnum.SUCCESS.getCode(), OperationEnum.SUCCESS.getMsg(), content);
}/*** 业务处理失败** @param operationEnum* @return com.lx.api.vo.ResponseVO*/
public static <T extends Serializable> ResponseVO fail(OperationEnum operationEnum) {return new ResponseVO(operationEnum.getCode(), operationEnum.getMsg());
}

}

SystemVO.java

/此为本人自己查阅资料的劳动成果,转载请注明链接/
package com.mp.api.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;

/**

  • @ Author :MP…

  • @ Date :Created in 19:16 2019/6/28

  • @ Description:系统参数类

  • @ Modified By:

  • @Version: $
    */
    @ApiModel
    @Data
    public class SystemVO {

    @ApiModelProperty(name = “memberNo”, value = “会员编号”, required = true)
    @NotEmpty(message = “会员编号不能为空”)
    @Pattern(regexp = “\w{9}”, message = “会员格式不正确”)
    private String memberNo;

    @NotEmpty(message = “签名不能为空”)
    @Pattern(regexp = “[a-z0-9]{32}”, message = “签名格式不正确”)
    @ApiModelProperty(name = “sign”, value = “签名”, required = true)
    private String sign;

    public String getMemberNo() {
    return memberNo;
    }

    public void setMemberNo(String memberNo) {
    this.memberNo = memberNo;
    }

    public String getSign() {
    return sign;
    }

    public void setSign(String sign) {
    this.sign = sign;
    }
    }

ResponseDTO.java
  1. package com.mp.api.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.mp.api.constant.InvokerEnum;
import lombok.Data;

import java.io.Serializable;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseDTO {

//调用接口成功与否,0为成功,其他值为失败
private String retCode;//调用接口失败信息
private String retMsg;//调用接口成功后返回内容
private T body;public ResponseDTO() {}public ResponseDTO(String retCode, String retMsg) {this.retCode = retCode;this.retMsg = retMsg;
}public ResponseDTO(String retCode, String retMsg, T body) {this.retCode = retCode;this.retMsg = retMsg;this.body = body;
}public ResponseDTO(InvokerEnum invokerEnum) {this.retCode = invokerEnum.getRetCode();this.retMsg = invokerEnum.getRetMsg();
}/*** 调用接口成功** @param body* @return com.lx.api.dto.ResponseDTO*/
public static <T extends Serializable> ResponseDTO success(T body) {return new ResponseDTO(InvokerEnum.SUCCESS.getRetCode(), InvokerEnum.SUCCESS.getRetMsg(), body);
}/*** 调用接口失败** @param invokerEnum* @return com.lx.api.dto.ResponseDTO*/
public static <T extends Serializable> ResponseDTO fail(InvokerEnum invokerEnum) {return new ResponseDTO(invokerEnum.getRetCode(), invokerEnum.getRetMsg());
}

}

CitizenIdentity.java
  1. package com.mp.api.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(“citizen_identity”)
public class CitizenIdentity implements Serializable {

private static final long serialVersionUID = 1L;/*** 主键*/
@TableId(value = "id", type = IdType.AUTO)
@JsonIgnore
private Integer id;/*** 姓名*/
private String name;/*** 身份证号码*/
private String idNo;/*** 年龄*/
private Integer age;/*** 性别*/
private Integer sex;/*** 住址*/
private String address;/*** 电话号码*/
private String phoneNo;/*** 邮箱*/
private String email;public static long getSerialVersionUID() {return serialVersionUID;
}public Integer getId() {return id;
}public void setId(Integer id) {this.id = id;
}public String getName() {return name;
}public void setName(String name) {this.name = name;
}public String getIdNo() {return idNo;
}public void setIdNo(String idNo) {this.idNo = idNo;
}public Integer getAge() {return age;
}public void setAge(Integer age) {this.age = age;
}public Integer getSex() {return sex;
}public void setSex(Integer sex) {this.sex = sex;
}public String getAddress() {return address;
}public void setAddress(String address) {this.address = address;
}public String getPhoneNo() {return phoneNo;
}public void setPhoneNo(String phoneNo) {this.phoneNo = phoneNo;
}public String getEmail() {return email;
}public void setEmail(String email) {this.email = email;
}

}

Member.java

package com.mp.api.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.Date;

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName(“member”)
public class Member implements Serializable {

private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)
private int id;private String memberName;@JsonIgnore
private String password;@JsonIgnore
private String memberNo;@JsonIgnore
private String secretKey;private Date createDate;private Date updateDate;public static long getSerialVersionUID() {return serialVersionUID;
}public int getId() {return id;
}public void setId(int id) {this.id = id;
}public String getMemberName() {return memberName;
}public void setMemberName(String memberName) {this.memberName = memberName;
}public String getPassword() {return password;
}public void setPassword(String password) {this.password = password;
}public String getMemberNo() {return memberNo;
}public void setMemberNo(String memberNo) {this.memberNo = memberNo;
}public String getSecretKey() {return secretKey;
}public void setSecretKey(String secretKey) {this.secretKey = secretKey;
}public Date getCreateDate() {return createDate;
}public void setCreateDate(Date createDate) {this.createDate = createDate;
}public Date getUpdateDate() {return updateDate;
}public void setUpdateDate(Date updateDate) {this.updateDate = updateDate;
}

}

VerifyUtil.java
  1. package com.mp.api.util;

import cn.hutool.core.lang.Filter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**

  • 验证工具

*/
public class VerifyUtil {

/*** 检查签名** @param paramVO* @param secretKey* @return boolean*/
public static boolean checkSign(Object paramVO, String secretKey) {//获取需要签名的参数集合Map<String, Object> paramMap = getParamMap(paramVO);//获取签名String sign = getSign(paramMap, secretKey);//比较return sign.equals(paramMap.get("sign"));
}/*** 获取参数集合** @param paramVO* @return java.util.Map<java.lang.String, java.lang.Object>*/
public static Map<String, Object> getParamMap(Object paramVO) {//bean转mapMap<String, Object> paramMap = convertObjToMap(paramVO);return paramMap;
}/*** 过滤并排序** @param paramMap* @return java.util.Map<java.lang.String,java.lang.Object>*/
public static Map<String, Object> filterAndSortMap(Map<String, Object> paramMap){//过滤值为null的字段paramMap = MapUtil.filter(paramMap, (Filter<Map.Entry<String, Object>>) stringObjectEntry -> !stringObjectEntry.getKey().equals("sign"));//对上述参数key进行排序按照字典序(a-z),请注意byte[]类型的参数不参与排序和计算签名,// 比如上传的文件;空值的参数也不参与排序和计算签名paramMap = MapUtil.sort(paramMap, (str, str2) -> {char[] chars = str.toCharArray();char[] chars2 = str2.toCharArray();int i = 0;while (i < chars.length && i < chars2.length) {if (chars[i] > chars2[i]) {return 1;} else if (chars[i] < chars2[i]) {return -1;} else {i++;}}if (i == chars.length) {  //str到头return -1;}if (i == chars2.length) { //str2到头return 1;}return 0;});return paramMap;
}/*** 获取签名** */
public static String getSign(Map<String, Object> paramMap, String secretKey) {//过滤并排序paramMap = filterAndSortMap(paramMap);//以key+value方式拼装字符串String paramStr = MapUtil.joinIgnoreNull(paramMap, "", "");//加密String sign = SecureUtil.md5(paramStr + secretKey);return sign;
}public static String getSign(Object paramVO, String secretKey) {//获取参数集合Map<String, Object> paramMap = getParamMap(paramVO);return getSign(paramMap, secretKey);
}/*** JavaBean对象转换为Map(包括父类属性)** @param obj* @return java.util.Map<java.lang.String,java.lang.Object>*/
public static Map<String, Object> convertObjToMap(Object obj){Map<String,Object> reMap = new HashMap<String,Object>();if (obj == null)return null;try {Class<?> objClass = obj.getClass();while(objClass != null){Field[] fields = objClass.getDeclaredFields();for(int i=0;i<fields.length;i++){try {Field f = objClass.getDeclaredField(fields[i].getName());f.setAccessible(true);Object o = f.get(obj);reMap.put(fields[i].getName(), o);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}objClass = objClass.getSuperclass();}} catch (SecurityException e) {e.printStackTrace();}return reMap;
}

}

mapper配置文件

CitizenIdentityMapper.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.mp.api.entity.CitizenIdentity"><id column="id" property="id" /><result column="name" property="name" /><result column="id_no" property="idNo" /><result column="age" property="age" /><result column="sex" property="sex" /><result column="address" property="address" /><result column="phone_no" property="phoneNo" /><result column="email" property="email" />
</resultMap><!-- 通用查询结果列 -->
<sql id="Base_Column_List">id, name, id_no, age, sex, address, phone_no, email
</sql>
MemberMapper.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.mp.api.entity.Member"><id column="id" property="id" /><result column="member_name" property="memberName" /><result column="password" property="password" /><result column="member_no" property="memberNo" /><result column="secret_key" property="secretKey" /><result column="create_date" property="createDate" /><result column="update_date" property="updateDate" />
</resultMap><!-- 通用查询结果列 -->
<sql id="Base_Column_List">id, member_name, password, member_no, secret_key, create_date, update_date
</sql>
application.properties

#\u6FC0\u6D3B\u5F00\u53D1\u73AF\u5883
spring.profiles.active=dev

#\u6570\u636E\u6E90
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/study?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

#mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.mp.api.entity
mybatis.configuration.map-underscore-to-camel-case=true

#json
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 文件输出格式 -->
<property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level

[%thread] %c [%L] -| %msg%n" />

<!-- test文件路径 -->
<property name="TEST_FILE_PATH" value="d:/logs" />
<!-- pro文件路径 -->
<property name="PROD_FILE_PATH" value="/opt/logs" /><!-- 开发环境 -->
<springProfile name="dev"><!--控制台输出--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${PATTERN}</pattern></encoder></appender><logger name="com.lx.api" level="debug" /><root level="info"><appender-ref ref="CONSOLE" /></root>
</springProfile><!-- 测试环境 -->
<springProfile name="test"><!--控制台输出--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${PATTERN}</pattern></encoder></appender><!-- 每天产生一个文件 --><appender name="TEST-FILE"class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 文件路径 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 文件名称 --><fileNamePattern>${TEST_FILE_PATH}/info.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 文件最大保存历史数量 --><MaxHistory>100</MaxHistory></rollingPolicy><layout class="ch.qos.logback.classic.PatternLayout"><pattern>${PATTERN}</pattern></layout></appender><root level="info"><appender-ref ref="CONSOLE" /><appender-ref ref="TEST-FILE" /></root>
</springProfile><!-- 生产环境 -->
<springProfile name="prod"><appender name="PROD_FILE"class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${PROD_FILE_PATH}/warn.%d{yyyy-MM-dd}.log</fileNamePattern><MaxHistory>100</MaxHistory></rollingPolicy><layout class="ch.qos.logback.classic.PatternLayout"><pattern>${PATTERN}</pattern></layout></appender><root level="warn"><appender-ref ref="PROD_FILE" /></root>
</springProfile>

客户端

APIRequest.java

package com.mp.apiclient.client;

import cn.hutool.http.HttpRequest;
import com.mp.apiclient.util.VerifyUtil;

import java.util.HashMap;
import java.util.Map;

/**

  • api请求

  • @author zhuwenbin

  • @since 2019/3/2 12:20
    */
    public class APIRequest {

    public static void main(String[] args) {
    //请求参数
    Map<String, Object> paramMap = new HashMap<>();
    paramMap.put(“name”, “张三”);
    paramMap.put(“idNo”, “238207237436119856”);
    paramMap.put(“memberNo”, “sb_000002”);

     //签名String sign = VerifyUtil.getSign(paramMap, "b0e65b8ca8d815d510487063ff76362d");paramMap.put("sign", sign);//请求String body = HttpRequest.post("http://localhost:8080/citizen-identity").form(paramMap).execute().body();System.out.println(body);
    

    }
    }

VerifyUtil.java

package com.mp.apiclient.util;

import cn.hutool.core.lang.Filter;
import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**

  • 验证工具

*/
public class VerifyUtil {

/*** 检查签名** @param paramVO* @param secretKey* @return boolean*/
public static boolean checkSign(Object paramVO, String secretKey) {//获取需要签名的参数集合Map<String, Object> paramMap = getParamMap(paramVO);//获取签名String sign = getSign(paramMap, secretKey);//比较return sign.equals(paramMap.get("sign"));
}/*** 获取参数集合** @param paramVO* @return java.util.Map<java.lang.String, java.lang.Object>*/
public static Map<String, Object> getParamMap(Object paramVO) {//bean转mapMap<String, Object> paramMap = convertObjToMap(paramVO);return paramMap;
}/*** 过滤并排序** @param paramMap* @return java.util.Map<java.lang.String,java.lang.Object>*/
public static Map<String, Object> filterAndSortMap(Map<String, Object> paramMap){//过滤值为null的字段paramMap = MapUtil.filter(paramMap, (Filter<Map.Entry<String, Object>>) stringObjectEntry -> !stringObjectEntry.getKey().equals("sign"));//对上述参数key进行排序按照字典序(a-z),请注意byte[]类型的参数不参与排序和计算签名,// 比如上传的文件;空值的参数也不参与排序和计算签名paramMap = MapUtil.sort(paramMap, (str, str2) -> {char[] chars = str.toCharArray();char[] chars2 = str2.toCharArray();int i = 0;while (i < chars.length && i < chars2.length) {if (chars[i] > chars2[i]) {return 1;} else if (chars[i] < chars2[i]) {return -1;} else {i++;}}if (i == chars.length) {  //str到头return -1;}if (i == chars2.length) { //str2到头return 1;}return 0;});return paramMap;
}/*** 获取签名** @param paramMap* @param secretKey* @return java.lang.String*/
public static String getSign(Map<String, Object> paramMap, String secretKey) {//过滤并排序paramMap = filterAndSortMap(paramMap);//以key+value方式拼装字符串String paramStr = MapUtil.joinIgnoreNull(paramMap, "", "");//加密String sign = SecureUtil.md5(paramStr + secretKey);return sign;
}/*** 获取签名** @param paramVO* @param secretKey* @return java.lang.String*/
public static String getSign(Object paramVO, String secretKey) {//获取参数集合Map<String, Object> paramMap = getParamMap(paramVO);return getSign(paramMap, secretKey);
}/*** JavaBean对象转换为Map** @param obj* @return java.util.Map<java.lang.String,java.lang.Object>*/
public static Map<String, Object> convertObjToMap(Object obj){Map<String,Object> reMap = new HashMap<String,Object>();if (obj == null)return null;try {Class<?> objClass = obj.getClass();while(objClass != null){Field[] fields = objClass.getDeclaredFields();for(int i=0;i<fields.length;i++){try {Field f = objClass.getDeclaredField(fields[i].getName());f.setAccessible(true);Object o = f.get(obj);reMap.put(fields[i].getName(), o);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}objClass = objClass.getSuperclass();}} catch (SecurityException e) {e.printStackTrace();}return reMap;
}

}

运行结果

启动时需先启动服务端,再运行客户端的代码,结果如下

完毕,如有侵权,请联系本人删除

简单公民身份信息API开发相关推荐

  1. php身份证注册判断重名,同名同姓测试,全国公民身份信息系统库查重名

    同名同姓测试,全国公民身份信息系统库查重名 时间:2020-05-21 13:30:01 大部分爸爸妈妈在给宝宝取姓名的时候,会好奇在全国范围内有多少人名字相同,希望孩子的名字不会跟太多人重合.或者有 ...

  2. Fabric链码实战(二)公民身份信息

    title: Fabric链码实战(二)公民身份信息 tags: Hyperledger, fabric ,区块链,chaincode 功能简述 使用链码可以添加和查询公民信息 功能实现 1.导入包 ...

  3. PHP获取美国邮政USPS、EMS运单物流跟踪信息 API 开发

    安装USPS接口安装包:https://github.com/VinceG/USPS-php-api composer require vinceg/usps-php-api /*** 获取迅蜂物流跟 ...

  4. 原来中国人民银行和公安部的联网核查公民身份信息系统存在bug的原因可能是身份证信息被基层派出所复制

    今天看到这样一则新闻: 男子身份证被"错制" 天降三千万债务成老赖维权难 才明白, 中国人民银行和公安部的"联网核查公民身份信息系统"存在bug 的原因, 可能 ...

  5. 为什么银行查不到你的身份信息?

    原文来自http://blog.csdn.net/rossini23/article/details/6882970 很多人应该有这样的经历:去银行开户或者办理其它业务,结果被告知系统里查不到你的个人 ...

  6. uniapp同步获取用户信息_微信小程序云开发教程微信小程序的API入门获取用户身份信息系列API...

    同学们大家好,我是小伊同学,上一节我们介绍了一些常用API,今天我们接着来学习一组API,那就是获取用户身份信息的API. 在微信小程序中,我们往往需要获取用户的身份信息,比如昵称.头像.性别.地区等 ...

  7. jwt token 附加用户信息_JWT的正确使用方法,API开发为什么使用JWT

    API开发越来越成为主流,需要各自Access Token做登录状态. 甚至目前web端mvvm应用,如angular.vue.react都使用了jwt方式,也就是不再使用cookie和session ...

  8. 启动服务错误5拒绝访问_【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器...

    启动一个最简单的 RESTful API 服务器 本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本 ...

  9. 【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器

    本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本小节源码下载路径:demo01 可先下载源码到本地 ...

最新文章

  1. intel 82579v驱动下载_最新INTEL和AMD平台轻松安装WIN7,集成M.2和USB3.0驱动
  2. uniapp中easycom组件的封装
  3. UnityVS(Visual Studio Tools For Unity)的安装与使用
  4. 企业如何确保精益生产管理真正落地?
  5. 什么叫做石英表_石英表和机械表的区别是什么
  6. AtCoder Regular Contest 061 E - Snuke‘s Subway Trip(建图 + dijkstra最短路 / 0/1bfs / 并查集)
  7. redio中插入php脚本,Jquery操作radio的简单实例
  8. Tomcat执行start文件后有乱码
  9. 可蠕虫 DarkRadiation 勒索软件瞄准 Linux 和 Docker 实例
  10. jQuery Mobile 所有class选项,开发全解+完美注释
  11. Activiti7讲义
  12. 游戏渠道SDK是什么
  13. Java为图片加水印
  14. 用Axure创建一个知乎登录注册界面
  15. win7系统怎么调计算机,分辨率,教您Win7如何调电脑的分辨率
  16. 解决:Unknown column ‘字段名‘ in ‘field list‘报错
  17. 文本相似度的几种计算方式
  18. Linux 系统licence,Linux系统中软件简单License的实现
  19. 模拟CMOS集成电路设计入门学习(16)
  20. 项目33-教师兼干部类

热门文章

  1. python k线顶分型_顶分型和底分型的确认及K线包含处理
  2. Android 来电监听
  3. 使用微软自带输入法输入英文之间间距突然变大
  4. 软件工程-课后讨论题
  5. 智慧数字经营小程序有什么好处
  6. 超级签名 免签封装 安卓打包 企业签名 超级签名MDM 企业签名MDM 自助分发多合一系统 搭建说明
  7. 利用Nginx反向代理解决80端口复用(内网域名转发)问题
  8. R7F0C901B2DNP-C#HA016位元RL78内核
  9. 关于八码数问题有解与无解的证明
  10. 换脸方法之FaceShifter