/**
 * ==========================================================
 * 案例代码入口
 * 【下方为企业详情页接口(企业部分)的代码调用案例。
 * (其他接口调用方式同理,只需要修改 产品编号 和 业务参数 两处的信息】)
 * ==========================================================
 */
public class Demo {
    public static void main(String args[]){
        // TODO
        // ============ 此测试密钥仅有 getDetailsInfo 接口权限 ============
        // ============ 如需更多权限请联系我司工作人员 ============
        String appKey = "app_key";
        String secret = "secret";
       
        // TODO
        // ============ 不同接口 产品编号 对应的 业务参数 也不同 ============
        // 产品编号:企业详情页接口(案例) 
        String name="getDetailsInfo";
        // 业务参数
        Map<String, String> jsonMap = new HashMap<String, String>();
        jsonMap.put("cname", "估**限公司");
        jsonMap.put("model", 1);
        
        
        // ============ 下方代码所有接口均可共用【如若需要优化可自行修改】 ============
        // ============ 下方代码所有接口均可共用【如若需要优化可自行修改】 ============
        String orderNo=""+System.currentTimeMillis();
        EncryptDTO dt = EncryptTool.createEncryptBody(name,appKey,secret,jsonMap,orderNo);
        System.out.println("=====请求数据====="+JSON.toJSON(param));
        String re = HttpUtil.post("https://api.valuemap.cn/api", JSON.toJSONString(dto));
        System.out.println("=====返回数据====="+re);
    }
}
/**
 * ==========================================================
 * valueMap开放接口DTO-【直接复制使用,可以不用改】
 * ==========================================================
 */
public class EncryptDTO {
    /**
     * appKey
     */
    private String app_key;
    /**
     * secret
     */
    private String secret;
    
    /**
     * 产品编号
     */
    private String name;
    /**
     * 业务参数
     */
    private String data;
    /**
     * 签名
     */
    private String sign;
    /**
     * 访问时间
     */
    private String timestamp;
    /**
     * 版本
     */
    private String version;
    /**
     * 订单号:建议传当前时间戳,无业务意义,仅方便对接排查
     */
    private String order_no;
    public String getApp_key() {
        return app_key;
    }
    public void setApp_key(String app_key) {
        this.app_key = app_key;
    }
    public String getSecret() {
        return secret;
    }
    public void setSecret(String secret) {
        this.secret = secret;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
    public String getSign() {
        return sign;
    }
    public void setSign(String sign) {
        this.sign = sign;
    }
    public String getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }
    public String getVersion() {
        return version;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public String getOrder_no() {
        return order_no;
    }
    public void setOrder_no(String order_no) {
        this.order_no = order_no;
    }
}
/**
 * ==========================================================
 * 加密工具类--【直接复制使用,可以不用改】
 * ==========================================================
 */
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONType;
import com.valuemap.encrypt.dto.EncryptDTO;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
public class EncryptTool {
    /**
     * 加密生成请求实体
     * 
     
     * @param name 产品编号
     * @param appKey 由我司业务人员提供 提供
     * @param secret 由我司业务人员提供 提供
     * @param param 业务参数Map
     * @param orderNo 订单号:建议传当前时间戳,无业务意义,仅方便对接排查
     * @return
     */
    public static EncryptDTO createEncryptBody(String name, String appKey, String secret, Map<String, Object>  param, String orderNo){
        try {
            String data = JSON.toJSONString(param);
            data = URLEncoder.encode(data, "utf-8");
            // 系统参数
            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put("app_key", appKey);
            paramMap.put("name", name);
            paramMap.put("data", data);
            paramMap.put("timestamp", getTime());
            paramMap.put("version", "");
            paramMap.put("secret",secret);
            paramMap.put("order_no", orderNo);
            String sign = buildSign(paramMap, secret);
            paramMap.put("sign", sign);
            EncryptDTO encryptDTO = JSONObject.parseObject(JSON.toJSONString(paramMap), EncryptDTO.class);
            return encryptDTO;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
    /**
     * 构建签名
     *
     * @param paramsMap
     *            参数
     * @param secret
     *            密钥
     * @return
     * @throws IOException
     */
    public static String buildSign(Map<String, ?> paramsMap, String secret) throws IOException {
        Set<String> keySet = paramsMap.keySet();
        List<String> paramNames = new ArrayList<String>(keySet);
        Collections.sort(paramNames);
        StringBuilder paramNameValue = new StringBuilder();
        for (String paramName : paramNames) {
            paramNameValue.append(paramName).append(paramsMap.get(paramName));
        }
        String source = secret + paramNameValue.toString() + secret;
        return md5(source);
    }
    /**
     * 生成md5,全部大写
     *
     * @param message
     * @return
     */
    public static String md5(String message) {
        try {
            // 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 2 将消息变成byte数组
            byte[] input = message.getBytes();
            // 3 计算后获得字节数组,这就是那128位了
            byte[] buff = md.digest(input);
            // 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串
            return byte2hex(buff);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 二进制转十六进制字符串
     *
     * @param bytes
     * @return
     */
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }
    public static String getTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}