of an open platform developed by imitating JD.COM platform framework includes requirements server codes and SDK codes

  • 2021-09-20 20:34:37
  • OfStack

Directory 1 Open Platform Requirements 1.1 Call Parameter 1.2 Signature Algorithm 2 Server Code, Java Example 2.1 Interface Entry Code 2.2 Business Logic Layer 2.3 Basic Tool Class 3. SDK Code, Java Example 4. Integration SDK, Code Example 5. Summary

1 Open Platform Requirements

Users need to assemble a correct URL according to the protocol specification of the open platform, and request to the open platform through Https to obtain the required data. The main process includes: filling in parameters, generating signatures, assembling HTTPS requests, initiating requests, obtaining response results, and parsing results.

1.1 Call parameters

参数名称

参数类型

是否必传

参数描述

method

String

API接口名称

access_token

String

采用OAuth授权方式是必填参数

app_key

String

应用的app_key

sign

String

详见下文“5.签名算法”描述

timestamp

String

时间戳,格式为yyyy-MM-dd HH:mm:ss,例如:2019-05-01 00:00:00。API服务端允许客户端请求时间误差为10分钟

format

String

暂时只支持json

v

String

API协议版本,参考接口文档版本

360buy_param_json

String

需要将应用级参数作为1个整体对象以json的形式拼接传递

Application-level parameters (refer to interface documentation for more API application parameters)

1.2 Signature algorithm

In order to prevent API from being intercepted and tampered by malicious people during the calling process, it is necessary to pass in signature parameters when calling API, and the open platform server will verify the signature according to the request parameters to judge whether the request parameters are legal or not. The process of open platform signature rules is as follows:

Arrange all request parameters in alphabetical order, such as access_token, app_key, method, timestamp, v, 360buy_param_json,

The order is 360buy_param_json, access_token, app_key, method, timestamp, v

Splice all parameter names and values, for example: 360buy_param_jsonxxxaccess_tokenxxxapp_keyxxxmethodxxxxxxtimestampxxxxxxvx

Clamp appSecret at both ends of a string (spliced string in the previous step), for example: appSecret+XXXX+appSecret

Encrypt with MD5 and convert to uppercase.

2 server code, Java example

The server is written based on SpringBoot framework, the entry is placed in Controller, and the business logic is written in Service. Considering security and convenience of troubleshooting, input checksum access log will be added.

2.1 Interface entry code

The interface has only one entry, that is, the Controller code is as follows:


@Controller
public class RouterController {
    @Resource
    private RouterService routerService;
    @Resource
    private OpenApiLogService openApiLogService;
    /**
     * API Interface router, interface entry 
     *
     * @param request
     * @param zrsc_param_json
     * @return
     */
    @RequestMapping(value = "routerjson", method = RequestMethod.POST)
    @ResponseBody
    public String routerjson(HttpServletRequest request, String zrsc_param_json) {
        if (zrsc_param_json==null||"".equals(zrsc_param_json)) {
            return JsonUtils.objToJson(APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum
                    .FAIL_PARA_LOSE.getName()));
        }
        APIMessageVo aPIMessageVo=openApiLogService.secrityCheck(request);
        if(aPIMessageVo.isSuccess()){// Safety inspection is successful 
            aPIMessageVo=routerService.router(request, zrsc_param_json);
            openApiLogService.insert(request,aPIMessageVo);
        }
        return JsonUtils.objToJson(aPIMessageVo);
    }
}

2.2 Business Logic Layer

Business logic layer, simple examples, different businesses are different.


    public APIMessageVo router(HttpServletRequest request, String zrsc_param_json) {
        String access_token = request.getParameter("access_token");
        String app_key = request.getParameter("app_key");
        String method = request.getParameter("method");
        String sign = request.getParameter("sign");
        APIMessageVo checkResult=this.routerParaCheck(request, zrsc_param_json,access_token,app_key,method,sign);
        if(!checkResult.isSuccess()){// Entry detection failed 
            return checkResult;
        }
        if (APPInterfaceNameEnum.API_ADDRESS_ADDRESS2PROVICECITY_GET.getName().equals(method)) {// Get provincial and municipal streets 
            return this.address2provincecity(zrsc_param_json);
        } else {// Interface does not exist 
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getCode(), APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getName());
        }
    }
    private APIMessageVo routerParaCheck(HttpServletRequest request, String zrsc_param_json, String access_token,
                                         String app_key, String method, String sign){
        //*************** Parameter check ***************
        if (StringUtils.isBlank(access_token) || StringUtils.isBlank(app_key) || StringUtils.isBlank(method) ||
                StringUtils.isBlank(sign)) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum.FAIL_PARA_LOSE.getName());
        }
        if(!APP_KEY.equals(app_key)){
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getCode(), APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getName());
        }
        //***************sign Calibration ***************
        try {
            // Get request Parameters in 
            Map<String, String> sysParams = getSysParams(request, zrsc_param_json);
            //SDK Parameter encryption 
            String signNew = SDKSignUtils.sign(sysParams, APP_SECRET);
            // Determine whether the parameter has been changed 
            if (!sign.equals(signNew)) {
                return APIMessageVo.fail(APIErrorEnum.FAIL_ERR_APP_SECRET.getCode(), APIErrorEnum.FAIL_ERR_APP_SECRET.getName());
            }
        } catch (Exception e) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_EXCEPTION.getCode(), APIErrorEnum.FAIL_EXCEPTION.getName());
        }
        return APIMessageVo.success();
    }

2.3 Basic tool classes


APIErrorEnum

public enum APIErrorEnum {
    FAIL_NOTAUTH(201," No authorization "),
    FAIL_TOKEN_EXPIRE(202,"Token Expired "),
    FAIL_PARA_LOSE(203," Missing parameter "),
    FAIL_NOT_REALAUTH(204," No real-name authentication passed "),
    FAIL_NOT_METHOD(205," Do not have permission to access this interface "),
    FAIL_PARA_ERR(206," Incorrect value of parameter "),
    FAIL_NOT_EXIST_ACCOUNT(207," User account does not exist "),
    FAIL_NOT_FOUND_APPLY(208," Application does not exist "),
    FAIL_NOT_PASS_APPROVAL_APPLY(209," Application approval failed "),
    FAIL_NOT_EXIST_APP_ID(210,"APP_ID Nonexistent "),
    FAIL_NOT_FOUND_INTERFACE(211," Interface does not exist "),
    FAIL_ERR_APP_SECRET(212,"appSecret Errors "),
    FAIL_CALL_FREQUENTLY(214," Calls too frequently "),
    FAIL_EXCEPTION(290," Unknown error ");
    private int code;
    private String name;
    APIErrorEnum(int code,String name) {
        this.code = code;
        this.name = name;
    }
    public int getCode() {
        return code;
    }
    public String getName() {
        return name;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public void setName(String name) {
        this.name = name;
    }
}

APIMessageVo

public class APIMessageVo {
    public static final Integer SUCCESS = 100;// Success 
    private boolean success;//  Whether the processing was successful 
    private Integer code = SUCCESS;// Status code 
    private String message = " Success ";//  Attached message ,  Such as the reason why the processing result failed, etc. 
    private Object data="";//  You can return the 1 Some result data 
    public APIMessageVo() {
        //default
    }
    public APIMessageVo(boolean success, Integer code) {
        this(success, code, " Success ", null);
    }
    public APIMessageVo(boolean success, Integer code, String message) {
        this(success, code, message, null);
    }
    public APIMessageVo(boolean success, String message, Object data) {
        this.success = success;
        this.message = message;
        this.data = data;
    }
    public APIMessageVo(boolean success, Integer code, String message, Object data) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }
    public APIMessageVo(boolean success, Object data) {
        this.success = success;
        this.data = data;
    }
    public static APIMessageVo fail(Integer code) {
        return new APIMessageVo(false, code);
    }
    public static APIMessageVo fail(Integer code,String message) {
        return new APIMessageVo(false,code, message);
    }
    public static APIMessageVo fail(Integer code,String message, Object data) {
        return new APIMessageVo(false,code, message, data);
    }
    public static APIMessageVo success() {
        return new APIMessageVo(true, SUCCESS);
    }
    public static APIMessageVo success(String message) {
        return new APIMessageVo(true, message);
    }
    public static APIMessageVo success(String message, Object data) {
        return new APIMessageVo(true, SUCCESS, message, data);
    }
    public static APIMessageVo success(Object data) {
        return new APIMessageVo(true, " Success ", data);
    }
}

JsonUtils

public class JsonUtils {
    //  Definition jackson Object 
     private static final ObjectMapper MAPPER = new ObjectMapper();
    /**
     *  Object conversion Json
     *
     * @param obj  Object 
     * @return json String 
     */
    public static String objToJson(Object obj) {
        try {
            return MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("Json Conversion exception: {}", e);
        }
        return "Json Conversion exception ";
    }
    /**
     * json Turn object 
     * @param jsonData json String 
     * @param beanType  Object 
     * @return  Object 
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T obj = MAPPER.readValue(jsonData, beanType);
            return obj;
        } catch (Exception e) {
            log.error("Json Conversion exception: {}", e);
        }
        return null;
    }
}

3. SDK code, Java example


DefaultZrscClient

public class DefaultZrscClient implements ZrscClient {
    private String serverUrl;
    private String accessToken;
    private int connectTimeout;
    private int readTimeout;
    private String appKey;
    private String fuzz;
    private String appSecret;
    public DefaultZrscClient(String serverUrl, String accessToken, String appKey, String appSecret) {
        this.connectTimeout = 8000;
        this.readTimeout = 8000;
        this.serverUrl = serverUrl;
        this.accessToken = accessToken;
        this.appKey = appKey;
        this.appSecret = appSecret;
    }
    public <T extends AbstractResponse> T execute(ZrscRequest<T> request) throws ZrscException {
        try {
            String url = this.buildUrl(request);
            Map<String, String> params = new HashMap();
            String json = request.getAppJsonParams();
            params.put("zrsc_param_json", json);
            if (request.getOtherParams() != null) {
                params.put("other", request.getOtherParams());
            }
            String rsp = HttpUtil.doPost(url, params, this.connectTimeout, this.readTimeout,this.accessToken);
            T resp = this.parse(rsp, request.getResponseClass());
            StringBuffer sb = new StringBuffer();
            sb.append(url).append("&").append("zrsc_param_json").append("=").append(json);
            resp.setUrl(sb.toString());
            return resp;
        } catch (Exception var8) {
            var8.printStackTrace();
            throw new ZrscException(" Exception occurred, please try again ");
        }
    }
    private <T extends AbstractResponse> String buildUrl(ZrscRequest<T> request) throws Exception {
        Map<String, String> sysParams = request.getSysParams();
        Map<String, String> pmap = new TreeMap();
        pmap.put("zrsc_param_json", request.getAppJsonParams());
        sysParams.put("method", request.getApiMethod());
        sysParams.put("access_token", this.accessToken);
        sysParams.put("app_key", this.appKey);
        pmap.putAll(sysParams);
        String sign = this.sign(pmap, this.appSecret);
        sysParams.put("sign", sign);
        StringBuilder sb = new StringBuilder(this.serverUrl);
        sb.append("?");
        sb.append(HttpUtil.buildQuery(sysParams, "UTF-8"));
        return sb.toString();
    }
    private <T extends AbstractResponse> T parse(String rsp, Class<T> responseClass) throws ZrscException {
        Parser parser;
        if (this.serverUrl.endsWith("json")) {
            parser = ParserFactory.getJsonParser();
        } else {
            parser = ParserFactory.getXmlParser();
        }
        return parser.parse(rsp, responseClass);
    }
    private String sign(Map<String, String> pmap, String appSecret) throws Exception {
        StringBuilder sb = new StringBuilder(appSecret);
        Iterator i$ = pmap.entrySet().iterator();
        while(i$.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry)i$.next();
            String name = (String)entry.getKey();
            String value = (String)entry.getValue();
            if (StringUtil.areNotEmpty(new String[]{name, value})) {
                sb.append(name).append(value);
            }
        }
        sb.append(appSecret);
        String result = CodecUtil.md5(sb.toString());
        return result;
    }
}

    public APIMessageVo router(HttpServletRequest request, String zrsc_param_json) {
        String access_token = request.getParameter("access_token");
        String app_key = request.getParameter("app_key");
        String method = request.getParameter("method");
        String sign = request.getParameter("sign");
        APIMessageVo checkResult=this.routerParaCheck(request, zrsc_param_json,access_token,app_key,method,sign);
        if(!checkResult.isSuccess()){// Entry detection failed 
            return checkResult;
        }
        if (APPInterfaceNameEnum.API_ADDRESS_ADDRESS2PROVICECITY_GET.getName().equals(method)) {// Get provincial and municipal streets 
            return this.address2provincecity(zrsc_param_json);
        } else {// Interface does not exist 
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getCode(), APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getName());
        }
    }
    private APIMessageVo routerParaCheck(HttpServletRequest request, String zrsc_param_json, String access_token,
                                         String app_key, String method, String sign){
        //*************** Parameter check ***************
        if (StringUtils.isBlank(access_token) || StringUtils.isBlank(app_key) || StringUtils.isBlank(method) ||
                StringUtils.isBlank(sign)) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum.FAIL_PARA_LOSE.getName());
        }
        if(!APP_KEY.equals(app_key)){
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getCode(), APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getName());
        }
        //***************sign Calibration ***************
        try {
            // Get request Parameters in 
            Map<String, String> sysParams = getSysParams(request, zrsc_param_json);
            //SDK Parameter encryption 
            String signNew = SDKSignUtils.sign(sysParams, APP_SECRET);
            // Determine whether the parameter has been changed 
            if (!sign.equals(signNew)) {
                return APIMessageVo.fail(APIErrorEnum.FAIL_ERR_APP_SECRET.getCode(), APIErrorEnum.FAIL_ERR_APP_SECRET.getName());
            }
        } catch (Exception e) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_EXCEPTION.getCode(), APIErrorEnum.FAIL_EXCEPTION.getName());
        }
        return APIMessageVo.success();
    }
0

    public APIMessageVo router(HttpServletRequest request, String zrsc_param_json) {
        String access_token = request.getParameter("access_token");
        String app_key = request.getParameter("app_key");
        String method = request.getParameter("method");
        String sign = request.getParameter("sign");
        APIMessageVo checkResult=this.routerParaCheck(request, zrsc_param_json,access_token,app_key,method,sign);
        if(!checkResult.isSuccess()){// Entry detection failed 
            return checkResult;
        }
        if (APPInterfaceNameEnum.API_ADDRESS_ADDRESS2PROVICECITY_GET.getName().equals(method)) {// Get provincial and municipal streets 
            return this.address2provincecity(zrsc_param_json);
        } else {// Interface does not exist 
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getCode(), APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getName());
        }
    }
    private APIMessageVo routerParaCheck(HttpServletRequest request, String zrsc_param_json, String access_token,
                                         String app_key, String method, String sign){
        //*************** Parameter check ***************
        if (StringUtils.isBlank(access_token) || StringUtils.isBlank(app_key) || StringUtils.isBlank(method) ||
                StringUtils.isBlank(sign)) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum.FAIL_PARA_LOSE.getName());
        }
        if(!APP_KEY.equals(app_key)){
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getCode(), APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getName());
        }
        //***************sign Calibration ***************
        try {
            // Get request Parameters in 
            Map<String, String> sysParams = getSysParams(request, zrsc_param_json);
            //SDK Parameter encryption 
            String signNew = SDKSignUtils.sign(sysParams, APP_SECRET);
            // Determine whether the parameter has been changed 
            if (!sign.equals(signNew)) {
                return APIMessageVo.fail(APIErrorEnum.FAIL_ERR_APP_SECRET.getCode(), APIErrorEnum.FAIL_ERR_APP_SECRET.getName());
            }
        } catch (Exception e) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_EXCEPTION.getCode(), APIErrorEnum.FAIL_EXCEPTION.getName());
        }
        return APIMessageVo.success();
    }
1

4. Integrate SDK, code example


    public APIMessageVo router(HttpServletRequest request, String zrsc_param_json) {
        String access_token = request.getParameter("access_token");
        String app_key = request.getParameter("app_key");
        String method = request.getParameter("method");
        String sign = request.getParameter("sign");
        APIMessageVo checkResult=this.routerParaCheck(request, zrsc_param_json,access_token,app_key,method,sign);
        if(!checkResult.isSuccess()){// Entry detection failed 
            return checkResult;
        }
        if (APPInterfaceNameEnum.API_ADDRESS_ADDRESS2PROVICECITY_GET.getName().equals(method)) {// Get provincial and municipal streets 
            return this.address2provincecity(zrsc_param_json);
        } else {// Interface does not exist 
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getCode(), APIErrorEnum.FAIL_NOT_FOUND_INTERFACE.getName());
        }
    }
    private APIMessageVo routerParaCheck(HttpServletRequest request, String zrsc_param_json, String access_token,
                                         String app_key, String method, String sign){
        //*************** Parameter check ***************
        if (StringUtils.isBlank(access_token) || StringUtils.isBlank(app_key) || StringUtils.isBlank(method) ||
                StringUtils.isBlank(sign)) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_PARA_LOSE.getCode(), APIErrorEnum.FAIL_PARA_LOSE.getName());
        }
        if(!APP_KEY.equals(app_key)){
            return APIMessageVo.fail(APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getCode(), APIErrorEnum.FAIL_NOT_EXIST_APP_ID.getName());
        }
        //***************sign Calibration ***************
        try {
            // Get request Parameters in 
            Map<String, String> sysParams = getSysParams(request, zrsc_param_json);
            //SDK Parameter encryption 
            String signNew = SDKSignUtils.sign(sysParams, APP_SECRET);
            // Determine whether the parameter has been changed 
            if (!sign.equals(signNew)) {
                return APIMessageVo.fail(APIErrorEnum.FAIL_ERR_APP_SECRET.getCode(), APIErrorEnum.FAIL_ERR_APP_SECRET.getName());
            }
        } catch (Exception e) {
            return APIMessageVo.fail(APIErrorEnum.FAIL_EXCEPTION.getCode(), APIErrorEnum.FAIL_EXCEPTION.getName());
        }
        return APIMessageVo.success();
    }
2

Run results:

data = {"source": "Ejiao Street Dongshou Road North", "province": "Shandong Province", "city": "Liaocheng City", "area": "Dong'e County", "street": "Xincheng Street", "addressInfo": "Ejiao Street Dongshou Road North"}

STEP 5 Summarize

JD.COM open platform in the transmission of reference and signature algorithm is more representative, this blog, just to share the main components of the open platform, I hope you can pay more attention to other content of this site!


Related articles: