Java HTTP POST请求,接口参数加签,验签的操作方法

1.业务背景

  因为公司做的系统跟淘宝有很大一部分的联系,所以涉及电商类的接口比较多,今天在对接礼品公司,对方的接口需要使用加签的方式。像这些接口,双方为了保证数据参数在传输过程中未经过篡改,一般都会需要对接口数据进行加签(不知道为什么像大淘客之类的却没有做这一块,可能是为了使用方便吧),然后在接口服务器端对接口参数进行验签,确保两个签名是一样的,验签通过之后再进行业务逻辑的处理。这里说一下我的处理思路。签名算法网上有很多,这里不做过多的介绍,我这里使用的是MD5算法加密。

2、处理思路

  双方约定好,需要进行加签的规则,比如ASCII算法进行排序后加签再转换大小写,如:http://XXX.api.XXX.cn/API/XXX?appKey=yourAppKey&AppSecret=yourAppSecret&timestamp=time&product=XXXX&sign=XXXXX,这里的参数是timestamp=time&product=XXXX,我这里只需要把参数拼接起来就可以了,即参数timestamp+product就可以了,然后再调用md5加签一次,再把这个值放到sign里,发给接口方,接口方接受到之后就会根据sign进行解析

3.实例练习

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Demo {
    static String appKey = "yourAppKey";
    static String AppSecret = "youreAppSecret";
    static String URL = "http://XXX.api.XXX.cn/API/XXX?appKey=yourAppKey&AppSecret=yourAppSecret&timestamp=time&product=XXXX&sign=XXXXX";
    public static void main(String[] args) throws Exception {

        Map<String, Object> MDParams = new HashMap();
        String timestamp =DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
        MDParams.put("timestamp",timestamp);
        String sign = createSign(MDParams,AppSecret);
        Map map = new HashMap();
        map.put("timestamp",timestamp);
        map.put("sign",sign);
        String params = mapToString(map);
        String result = HttpUtil.postGeneralUrl(URL,"application/x-www-form-urlencoded;charset=UTF-8",
                params, "UTF-8");
        System.out.println(result);
    }


    private static String createSign(Map<String, Object> params, String accessSecret) throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuilder temp = new StringBuilder();
        boolean first = true;
        for (Object key : keys) {
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = String.valueOf(value);
            }
            temp.append(valueString);
        }
        temp.append(accessSecret);
        StringBuilder temp2 = new StringBuilder();
        temp2.append(accessSecret);
        temp2.append(temp);
        return MD5Util.md5Encrypt32Upper(temp2.toString()).toUpperCase();
    }

    private static String mapToString(Map<String, Object> params){
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuilder temp = new StringBuilder();
        boolean first = true;
        for (Object key : keys) {
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = String.valueOf(value);
            }
            temp.append(valueString);
        }
       return temp.toString();
    }
}
DateUtils.java

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期处理
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);

    private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH",
            "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH", "yyyy.MM", "yyyy年MM月dd日",
            "yyyy年MM月dd日 HH时mm分ss秒", "yyyy年MM月dd日 HH时mm分", "yyyy年MM月dd日 HH时", "yyyy年MM月", "yyyy" };

    /**
     * 获取
     * 从今天往前beforeDay天到明天凌晨的时间范围,集合范围: [开始时间, 结束时间)
     * @return
     */
    public static Date[] getTodayDateRange(int beforeDay) {
        Date startDate = DateUtils.truncate(new Date(), Calendar.DATE);
        Date endDate = DateUtils.addDays(startDate, 1);
        
        if (beforeDay > 0) {
            startDate = DateUtils.addDays(startDate, -beforeDay);
        }
        
        return new Date[] {startDate, endDate};
    }
    
    /**
     * 获取
     * 从今天往前beforeDay天到明天凌晨的时间范围,集合范围: [开始时间, 结束时间)
     * @return
     */
    public static String[] getTodayDateRangeStr(int beforeDay) {
        Date startDate = DateUtils.truncate(new Date(), Calendar.DATE);
        Date endDate = DateUtils.addDays(startDate, 1);
        
        if (beforeDay > 0) {
            startDate = DateUtils.addDays(startDate, -beforeDay);
        }
        
        String startDateStr = formatDate(startDate, parsePatterns[1]);
        String endDateStr = formatDate(endDate, parsePatterns[1]);
        
        return new String[] {startDateStr, endDateStr};
    }
    
    /**
     * 获取
     * 从今天往前beforeDay天到明天凌晨的时间范围,集合范围: [开始时间, 结束时间)
     * @return
     */
    public static String[] getTodayDateRangeStr0(int beforeDay) {
        
        Date[] dates = getTodayDateRange(beforeDay);
        String startDateStr = formatDate(dates[0], parsePatterns[0]);
        String endDateStr = formatDate(dates[1], parsePatterns[0]);
        
        return new String[] {startDateStr, endDateStr};
    }
    
    /**
     * 得到日期字符串 ,转换格式(yyyy-MM-dd)
     */
    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    /**
     * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(long dateTime, String pattern) {
        return formatDate(new Date(dateTime), pattern);
    }

    /**
     * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, String pattern) {
        String formatDate = null;
        if (date != null) {
//                if (StringUtils.isNotBlank(pattern)) {
//                    formatDate = DateFormatUtils.format(date, pattern);
//                } else {
//                    formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
//                }
            if (StringUtils.isBlank(pattern)) {
                pattern = "yyyy-MM-dd";
            }
            formatDate = FastDateFormat.getInstance(pattern).format(date);
        }
        return formatDate;
    }

    /**
     * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd)
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
//            return DateFormatUtils.format(new Date(), pattern);
        return FastDateFormat.getInstance(pattern).format(new Date());
    }

    /**
     * 得到当前日期前后多少天,月,年的日期字符串
     * 
     * @param pattern 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     * @param amont   数量,前为负数,后为正数
     * @param type    类型,可参考Calendar的常量(如:Calendar.HOUR、Calendar.MINUTE、Calendar.SECOND)
     * @return
     */
    public static String getDate(String pattern, int amont, int type) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(type, amont);
//            return DateFormatUtils.format(calendar.getTime(), pattern);
        return FastDateFormat.getInstance(pattern).format(calendar.getTime());
    }
    
    /**
     * by hzw
     * 得到传递时间前后 多少小时,天,月的日期   
     * @param time   外部传入的日期时间
     * @param amont  数量,前为负数,后为正数
     * @param type   类型,可参考Calendar的常量(如:Calendar.HOUR、Calendar.MINUTE、Calendar.SECOND)
     * @return
     */
    public static Date getDate(Date time ,int amont, int type) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(type, amont);
        return calendar.getTime(); 
    }

    /**
     * 得到当前时间字符串 格式(HH:mm:ss)
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式(yyyy)
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式(MM)
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式(dd)
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式(E)星期几
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式 see to DateUtils#parsePatterns
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     * 
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     * 
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     * 
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 获取两个日期之间的天数
     * 
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 获取某月有几天
     * 
     * @param date 日期
     * @return 天数
     */
    public static int getMonthHasDays(Date date) {
//            String yyyyMM = new SimpleDateFormat("yyyyMM").format(date);
        String yyyyMM = FastDateFormat.getInstance("yyyyMM").format(date);
        String year = yyyyMM.substring(0, 4);
        String month = yyyyMM.substring(4, 6);
        String day31 = ",01,03,05,07,08,10,12,";
        String day30 = "04,06,09,11";
        int day = 0;
        if (day31.contains(month)) {
            day = 31;
        } else if (day30.contains(month)) {
            day = 30;
        } else {
            int y = Integer.parseInt(year);
            if ((y % 4 == 0 && (y % 100 != 0)) || y % 400 == 0) {
                day = 29;
            } else {
                day = 28;
            }
        }
        return day;
    }

    /**
     * 获取日期是当年的第几周
     * 
     * @param date
     * @return
     */
    public static int getWeekOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取一天的开始时间(如:2015-11-3 00:00:00.000)
     * 
     * @param date 日期
     * @return
     */
    public static Date getOfDayFirst(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取一天的最后时间(如:2015-11-3 23:59:59.999)
     * 
     * @param date 日期
     * @return
     */
    public static Date getOfDayLast(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取服务器启动时间
     * 
     * @param date
     * @return
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 格式化为日期范围字符串
     * 
     * @param beginDate 2018-01-01
     * @param endDate   2018-01-31
     * @return 2018-01-01 ~ 2018-01-31
     * @author ThinkGem
     */
    public static String formatDateBetweenString(Date beginDate, Date endDate) {
        String begin = DateUtils.formatDate(beginDate);
        String end = DateUtils.formatDate(endDate);
        if (StringUtils.isNoneBlank(begin, end)) {
            return begin + " ~ " + end;
        }
        return null;
    }

    /**
     * 解析日期范围字符串为日期对象
     * 
     * @param dateString 2018-01-01 ~ 2018-01-31
     * @return new Date[]{2018-01-01, 2018-01-31}
     * @author ThinkGem
     */
    public static Date[] parseDateBetweenString(String dateString) {
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(dateString)) {
            String[] ss = StringUtils.split(dateString, "~");
            if (ss != null && ss.length == 2) {
                String begin = StringUtils.trim(ss[0]);
                String end = StringUtils.trim(ss[1]);
                if (StringUtils.isNoneBlank(begin, end)) {
                    beginDate = DateUtils.parseDate(begin);
                    endDate = DateUtils.parseDate(end);
                }
            }
        }
        return new Date[] { beginDate, endDate };
    }

    public static String getToDay() {
        Date toDay = truncate(new Date(), Calendar.DATE);
        return formatDate(toDay);
    }

    public static String getTomorrow() {
        Date toDay = truncate(new Date(), Calendar.DATE);
        return formatDate( addDays(toDay, 1));
    }

    /**
     * 获取
     * 从今天往前beforeDay天到明天凌晨的时间范围,集合范围: [开始时间, 结束时间)
     * @return
     */
    public static String[] getTodayDateRangeStrByTJY(int beforeDay) {

        Date[] dates = getTodayDateRange(beforeDay);
        String startDateStr = formatDate(dates[0], parsePatterns[1]);
        String endDateStr = formatDate(dates[1], parsePatterns[1]);

        return new String[] {startDateStr, endDateStr};
    }

    public static Date strToDate(String strDate) {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        ParsePosition pos = new ParsePosition(0);

        Date strtodate = formatter.parse(strDate, pos);

        return strtodate;

    }

}
View Code

HttpUtil.java

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * http 工具类
 */
public class HttpUtil {

    public static String post(String requestUrl, String accessToken, String params)
            throws Exception {
        String contentType = "application/x-www-form-urlencoded";
        return HttpUtil.post(requestUrl, accessToken, contentType, params);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params)
            throws Exception {
        String encoding = "UTF-8";
        if (requestUrl.contains("nlp")) {
            encoding = "GBK";
        }
        return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
    }

    public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
            throws Exception {
        String url = requestUrl + "?access_token=" + accessToken;
        return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
    }

    public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
            throws Exception {
        URL url = new URL(generalUrl);
        // 打开和URL之间的连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        // 设置通用的请求属性
        connection.setRequestProperty("Content-Type", contentType);
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setUseCaches(false);
        connection.setDoOutput(true);
        connection.setDoInput(true);

        // 得到请求的输出流对象
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(params.getBytes(encoding));
        out.flush();
        out.close();

        // 建立实际的连接
        connection.connect();
        // 获取所有响应头字段
        Map<String, List<String>> headers = connection.getHeaderFields();
        // 遍历所有的响应头字段
        for (String key : headers.keySet()) {
            System.err.println(key + "--->" + headers.get(key));
        }
        // 定义 BufferedReader输入流来读取URL的响应
        BufferedReader in = null;
        in = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), encoding));
        String result = "";
        String getLine;
        while ((getLine = in.readLine()) != null) {
            result += getLine;
        }
        in.close();
        System.err.println("result:" + result);
        return result;
    }
}
View Code
原文地址:https://www.cnblogs.com/shisanye/p/13523016.html