public static void main(String[] args) {
   Calendar startCal = Calendar.getInstance();
   startCal.set(Calendar.YEAR, 1999);
   startCal.set(Calendar.MONTH, 2);
   startCal.set(Calendar.DAY_OF_MONTH, 1);
   System.out.println(DateOperator.getYearDiff(startCal.getTime(), new Date()));
 }
  /**
   * 订单支付成功确认
   *
   * @param orderCode
   * @param memberPin
   * @param payChannel
   * @param payCode
   * @param payTime
   * @return
   */
  @RequestMapping(value = "/update/orderPaySuccessConfirm", method = RequestMethod.POST)
  @ResponseBody
  public RestResultDTO orderPaySuccessConfirm(
      String memberPin,
      String orderCode,
      Integer payMoney,
      Integer payChannel,
      String payCode,
      String payTime) {
    RestResultDTO restResultDTO = new RestResultDTO();
    try {
      CommonValidateUtil.notEmpty(memberPin, "会员不能为空");
      if (!CommonValidateUtil.validateFixedLengthDigital(orderCode, 20)) {
        throw new IllegalArgumentException("请输入正确的订单号");
      }

      Validate.notNull(payMoney, "支付金额不能为空");

      if (payMoney <= 0) {
        throw new IllegalArgumentException("请输入正确的支付金额");
      }

      Validate.notNull(payChannel, "支付渠道不能为空");
      Validate.notNull(OrderPayChannelEnum.get(payChannel), "支付渠道不能为空");

      if (!CommonValidateUtil.validateRangeLengthStr(payCode, 1, 50)) {
        throw new IllegalArgumentException("支付编码不能为空");
      }
      CommonValidateUtil.notEmpty(payTime, "支付时间不能为空");

      restResultDTO =
          orderCreateAndPayService.orderPaySuccessConfirm(
              memberPin,
              orderCode,
              payMoney,
              payChannel,
              payCode,
              DateOperator.parse(payTime, "yyyyMMddHHmmss"));

      /*----- 校验订单上的产品副本是否已和保险公司对接成功 -----*/
      Order order = orderRelatedQueryService.getByOrderCode(orderCode);

      if (order != null && order.getId() != null) {
        if (!order.getProductDocked())
          restResultDTO.setBody(CustomCode.NO_CALL_AUTOMATIC_INS_ACCEPT_INTER);
      }

    } catch (Exception e) {
      exceptionDeal(restResultDTO, e, "orderPaySuccessConfirm", "订单支付成功确认失败");
    }

    return restResultDTO;
  }
 /**
  * 因此款产品的特殊性,需要重写通用的投保人信息校验 <br>
  * 投保人年龄放宽到十六周岁以上即可
  *
  * @param holder
  */
 @Override
 public void commonInsHolderValidator(InsHolder holder) {
   commonStackholderValidator(
       INS_HOLDER,
       holder.getHolderName(),
       holder.getHolderPaperCat(),
       holder.getHolderPaperNo(),
       holder.getHolderBirthday(),
       holder.getHolderSex());
   Date holderBirth = holder.getHolderBirthday();
   int age = DateOperator.getYearDiff(holderBirth, new Date());
   if (age < 16) {
     throw new IllegalArgumentException("投保人年龄不在投保范围之内");
   }
   stackholderMobileValidator(INS_HOLDER, holder.getHolderMobile());
   stackholderEmailValidator(INS_HOLDER, holder.getHolderEmail());
 }
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

    RestResultDTO restResultDTO = new RestResultDTO();

    // 获得请求时间字符串
    String requestTimeStr = request.getParameter(REQ_TIME_NAME);

    try {
      Date reqTime = DateOperator.parse(requestTimeStr, TIME_FORMAT);
      if (reqTime == null) {
        renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证失败", "请求时间无效");
        ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
        return false;
      } else {
        // 获取服务器时间和请求时间之间相差的分钟数
        long minuteDiff = Math.abs(DateOperator.getMinuteDiff(reqTime, new Date()));

        // 防止REPLAY攻击,提交的时间与我方服务器时间相差超过2分钟,则请求将失败.
        if (minuteDiff > 2L) {
          renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证失败", "请求时间过期,请和服务器保持时间同步");
          ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
          return false;
        }
      }
    } catch (Exception e) {
      if (e instanceof IllegalArgumentException) {
        renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证失败", "请求时间无效");
        ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
        return false;
      }
    }

    // 获取请求方的联盟ID
    String allianceId = request.getParameter(ALLIANCE_ID_NAME);

    if (StringUtils.isEmpty(allianceId)) {
      renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证失败", "联盟ID无效");
      ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
      return false;
    }

    AllianceMember entity = null;
    try {
      AllianceMemberService allianceMemberService =
          SpringContextHolder.getBean("allianceMemberService");
      entity = allianceMemberService.getByAlliacnePin(allianceId);
    } catch (Exception e) {
      looger.error("preHandle -> " + e.getMessage());
      renderRest(restResultDTO, StatusCode.INTERNAL_SERVER_ERROR, "系统错误", "请求内部接口出错");
      ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
      return false;
    }

    if (entity == null || entity.getStatus() == 2) {
      renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证失败", "联盟ID无效");
      ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
      return false;
    }

    /*
     * example:http://127.0.0.1:80/jhj-hyb-openapi/member/save/register
     * 这是最简单的URL,长度最小不能少于7也是由此得来
     */
    // 获取请求地址
    String requestUrl = request.getRequestURL().toString();
    String[] reqUrlStrArr = requestUrl.split("/");

    // 判断请求地址是否满足OPEN API的标准
    int length;
    if (reqUrlStrArr == null || (length = reqUrlStrArr.length) < 7) {
      renderRest(restResultDTO, StatusCode.NOT_FOUND, "", "");
      ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
      return false;
    }

    // 根据规则计算签名
    String signInServer =
        getPlaintext4Encript(
            reqUrlStrArr[length - 3],
            reqUrlStrArr[length - 2],
            reqUrlStrArr[length - 1],
            entity.getAlliancePin(),
            entity.getPassword(),
            requestTimeStr);

    // mobileShortMsg.save.generateValidateCode-1&eef8d26eedcae2303035be2fbf2d5a17&2016-02-16
    // 16:50:01.812
    // System.out.println(request.getParameter(DIGITAL_SIGN_NAME));

    // 签名匹配
    if (!signInServer.equals(request.getParameter(DIGITAL_SIGN_NAME))) {
      renderRest(restResultDTO, StatusCode.UNAUTHORIZED, "账户认证信息无效", "签名无效");
      ServletUtils.renderJson(response, JSON.toJSONString(restResultDTO));
      return false;
    }

    return super.preHandle(request, response, handler);
  }
  /**
   * 通用的保险干系人数据校验
   *
   * @param stackholderCat 干系人类型
   * @param name 姓名
   * @param paperCat 证件类型
   * @param paperNo 证件号码
   * @param birthday 生日
   * @param sex 性别
   * @throws Exception
   */
  public static void commonStackholderValidator(
      String stackholderCat,
      String name,
      Byte paperCat,
      String paperNo,
      Date birthday,
      String sex) {

    // 姓名
    /*
    CommonValidateUtil.notEmpty(name, stackholderCat + "姓名不能为空");
    if (name.length() > 20) {
    	throw new IllegalArgumentException(stackholderCat + "姓名的长度不能大于20");
    }
    */
    stackholderNameValidator(stackholderCat, name);

    // 证件类型
    // Validate.notNull(paperCat, stackholderCat + "证件类型不能为空");
    // Validate.notNull(PaperCatEnum.get(String.valueOf(paperCat.intValue())), stackholderCat +
    // "证件类型不能为空");
    stackholderPaperCatValidator(stackholderCat, paperCat);

    // 证件号码
    /*
    CommonValidateUtil.notEmpty(paperNo, stackholderCat + "证件号码不能为空");
    if (PaperCatEnum.IDENTITY_CARD.getValue().equals(String.valueOf(paperCat.intValue()))) {
    	if (!CommonValidateUtil.validateIdentityCardNum(paperNo)){
    		throw new IllegalArgumentException("请输入" + stackholderCat + "正确的身份证号码");
    	}
    } else if (PaperCatEnum.OFFICIAL_CARD.getValue().equals(String.valueOf(paperCat.intValue()))) {
    	if (!CommonValidateUtil.validateDigital(paperNo)){
    		throw new IllegalArgumentException("请输入" + stackholderCat + "正确的军人证号码");
    	}
    }
    */
    stackholderPaperNoValidator(stackholderCat, paperCat, paperNo);

    // 出生日期
    // Validate.notNull(birthday, stackholderCat + "出生日期不能为空");
    stackholderBirthValidator(stackholderCat, birthday);
    // 出生日期的附加校验
    if (PaperCatEnum.IDENTITY_CARD.getValue().equals(String.valueOf(paperCat.intValue()))) {
      String birthdayStr = paperNo.substring(6, 14);
      Date birthFromIdCard = DateOperator.parse(birthdayStr, "yyyyMMdd");
      if (birthFromIdCard.compareTo(birthday) != 0) {
        throw new IllegalArgumentException("手工填写的出生日期与身份证上的出生日期不匹配[" + stackholderCat + "]");
      }
    }

    // 性别
    // Validate.notNull(SexEnum.get(sex), "请输入" + stackholderCat + "正确的性别");
    stackholderSexValidator(stackholderCat, sex);
    // 性别的附加校验
    if (PaperCatEnum.IDENTITY_CARD.getValue().equals(String.valueOf(paperCat.intValue()))) {
      String sexStr = "M";
      Integer sexNumFromIdCard = Integer.valueOf(paperNo.substring(16, 17)); // 第17位为性别位
      if (sexNumFromIdCard % 2 == 0) { // 偶数为女
        sexStr = "F";
      }

      if (!sexStr.equals(sex)) {
        throw new IllegalArgumentException("手工填写的性别与身份证上的性别不匹配[" + stackholderCat + "]");
      }
    }
  }