受理接口流程及常用工具包總結

一、應用場景

上游通過RPC調用我們的系統,我們首先通過API層受理,然後API層調用BIZ層處理業務邏輯。

二、受理接口步驟

1、參數轉換

將Map<String, Object>類型的入參轉爲我們接口文檔定好的對象,通常使用fastJson來處理。

  FridsUserLoginInfoDto dto = JSON.parseObject(JSON.toJSONString(params), FridsUserLoginInfoDto.class);

2、參數校驗

通常使用javax.validation包來校驗入參是否爲空,長度校驗等,在屬性上加上註解,如下所示。

@NotBlank(message = "手機號不能爲空")
    @Length(max = 16, message = "手機號超過最大長度")
    private String phoneNo;

使用javax.validation包

  //參數校驗
validator.validateUserActionOperation(dto);

public void validateUserActionOperation(FridsUserLoginInfoDto dto) {
        LOGGER.debug("validateUserActionOperation start, dto:{}", dto);
        //校驗公共數據
        Set<ConstraintViolation<FridsUserLoginInfoDto>> validate = validator.validate(dto);
        Map<String, String> messageMap = BeanValidators.extractPropertyAndMessage(validate);
        if (MapUtils.isNotEmpty(messageMap)) {
            LOGGER.error("會員號:{},手機號:{},操作類型:{}的操作下發失敗,失敗原因爲{}",
                    dto.getUserNo(), dto.getPhoneNo(), dto.getOperationType(), messageMap.toString());
            throw new AppException(CoreErrorCode.REQUEST_PARAM_VALIDATION_FALIURE, messageMap.toString());
        }
        LOGGER.debug("validateUserActionOperation end");
    }

3、代碼邏輯

校驗完就可以寫代碼邏輯處理業務了。

4、異常處理

針對異常,向上反饋。

try {
            //業務邏輯
            }
        } catch (AppException app) {
            result.fail(app.getErrorCode(), app.getMessage());
            LOGGER.error("fundOperationAccept AppException:{}", app);
        } catch (Exception e) {
            result.fail(ReturnCode.HANDLE_FAILE, ReturnCode.HANDLE_FAILE_CN);
            LOGGER.error("fundOperationAccept Exception:{}", e);
        }

三、代碼實例:

public DecisionResponse fundOperationAccept(Map<String, Object> params) {
        DecisionResponse result = new DecisionResponse();
        //參數轉換
        FridsUserLoginInfoDto dto = JSON.parseObject(JSON.toJSONString(params), FridsUserLoginInfoDto.class);
        LOGGER.info("fundOperationAccept start, dto:{}", dto);
        //參數校驗
        validator.validateUserActionOperation(dto);
        FridsUserLoginInfo dmo = RequestConvert.packageUserLoginInfoDtoToDmo(dto);
        try {
            //業務邏輯
            }
        } catch (AppException app) {
            result.fail(app.getErrorCode(), app.getMessage());
            LOGGER.error("fundOperationAccept AppException:{}", app);
        } catch (Exception e) {
            result.fail(ReturnCode.HANDLE_FAILE, ReturnCode.HANDLE_FAILE_CN);
            LOGGER.error("fundOperationAccept Exception:{}", e);
        }
        return result;
    }

四、Validator工具類:

用於處理校驗結果的類型轉換:

public class BeanValidators {

    /**
     * 調用JSR303的validate方法, 驗證失敗時拋出ConstraintViolationException, 而不是返回constraintViolations.
     */
    public static void validateWithException(Validator validator, Object object, Class<?>... groups)
            throws ConstraintViolationException {
        Set constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            throw new ConstraintViolationException(constraintViolations);
        }
    }

    /**
     * 輔助方法, 轉換ConstraintViolationException中的Set<ConstraintViolations>中爲List<message>.
     */
    public static List<String> extractMessage(ConstraintViolationException e) {
        return extractMessage(e.getConstraintViolations());
    }

    /**
     * 輔助方法, 轉換Set<ConstraintViolation>爲List<message>
     */
    public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
        List<String> errorMessages = new ArrayList<String>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.add(violation.getMessage());
        }
        return errorMessages;
    }

    /**
     * 輔助方法, 轉換ConstraintViolationException中的Set<ConstraintViolations>爲Map<property, message>.
     */
    public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
        return extractPropertyAndMessage(e.getConstraintViolations());
    }

    /**
     * 輔助方法, 轉換Set<ConstraintViolation>爲Map<property, message>.
     */
    public static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
        Map<String, String> errorMessages = new HashMap<String, String>(CommonConstants.INITIAL_CAPACITY);
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
        }
        return errorMessages;
    }

    /**
     * 輔助方法, 轉換ConstraintViolationException中的Set<ConstraintViolations>爲List<propertyPath message>.
     */
    public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
        return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
    }

    /**
     * 輔助方法, 轉換Set<ConstraintViolations>爲List<propertyPath message>.
     */
    public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
        return extractPropertyAndMessageAsList(constraintViolations, " ");
    }

    /**
     * 輔助方法, 轉換ConstraintViolationException中的Set<ConstraintViolations>爲List<propertyPath + separator + message>.
     */
    public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
        return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
    }

    /**
     * 輔助方法, 轉換Set<ConstraintViolation>爲List<propertyPath + separator + message>.
     */
    public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations,
                                                               String separator) {
        List<String> errorMessages = new ArrayList<String>();
        for (ConstraintViolation violation : constraintViolations) {
            errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage());
        }
        return errorMessages;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章