zoukankan      html  css  js  c++  java
  • 发布一个HTTP接口

    1.签名验证的工具类:

      签名规则:

    1. 将所有请求参数转成JSON字符串。
    2. 将请求密钥分别添加到上述JSON字符串的头部和尾部,格式如下:

          secret请求参数JSON字符串secret

      3. 对该字符串进行MD5(签名)运算,得到一个二进制数组。

      4. 将该二进制数组转换为一个十六进制的字符串,该字符串是这些请求参数的签名。

      1 /**
      2  * 请求参数签名工具类
      3  *
      4  */
      5 public class ParamSignUtils {
      6 
      7     public static void main(String[] args) {
      8         HashMap<String, String> signMap = new HashMap<String, String>();
      9         String secret = "ywwXMYoWoS63u26fB1r4U";
     10         HashMap SignHashMap = ParamSignUtils.sign(signMap, secret);
     11         System.out.println("SignHashMap:" + SignHashMap);
     12         List<String> ignoreParamNames = new ArrayList<String>();
     13         ignoreParamNames.add("a");
     14         HashMap SignHashMap2 = ParamSignUtils.sign(signMap, ignoreParamNames, secret);
     15         System.out.println("SignHashMap2:" + SignHashMap2);
     16     }
     17 
     18     public static HashMap<String, String> sign(Map<String, String> paramValues, String secret) {
     19         return sign(paramValues, null, secret);
     20     }
     21 
     22     /**
     23      * @param paramValues
     24      * @param ignoreParamNames
     25      * @param secret
     26      * @return
     27      */
     28     public static HashMap<String, String> sign(Map<String, String> paramValues, List<String> ignoreParamNames,
     29             String secret) {
     30         try {
     31             HashMap<String, String> signMap = new HashMap<String, String>();
     32             StringBuilder sb = new StringBuilder();
     33             List<String> paramNames = new ArrayList<String>(paramValues.size());
     34             paramNames.addAll(paramValues.keySet());
     35             if (ignoreParamNames != null && ignoreParamNames.size() > 0) {
     36                 for (String ignoreParamName : ignoreParamNames) {
     37                     paramNames.remove(ignoreParamName);
     38                 }
     39             }
     40             Collections.sort(paramNames);
     41             sb.append(secret);
     42             for (String paramName : paramNames) {
     43                 sb.append(paramName).append(paramValues.get(paramName));
     44             }
     45             sb.append(secret);
     46             byte[] md5Digest = getMD5Digest(sb.toString());
     47             String sign = byte2hex(md5Digest);
     48             signMap.put("appParam", sb.toString());
     49             signMap.put("appSign", sign);
     50             return signMap;
     51         } catch (IOException e) {
     52             throw new RuntimeException("加密签名计算错误", e);
     53         }
     54 
     55     }
     56 
     57     /**
     58      * @param paramValues
     59      * @param ignoreParamNames
     60      * @param secret
     61      * @return
     62      */
     63     public static HashMap<String, String> sign(String paramValues, String secret) {
     64         try {
     65             HashMap<String, String> signMap = new HashMap<String, String>();
     66             StringBuilder sb = new StringBuilder(secret);
     67             if(!StringUtils.isBlank(paramValues)){
     68                 sb.append(paramValues);
     69             }
     70             sb.append(secret);
     71             byte[] md5Digest = getMD5Digest(sb.toString());
     72             String sign = byte2hex(md5Digest);
     73             signMap.put("appParam", sb.toString());
     74             signMap.put("appSign", sign);
     75             return signMap;
     76         } catch (IOException e) {
     77             throw new RuntimeException("加密签名计算错误", e);
     78         }
     79 
     80     }
     81 
     82     public static String utf8Encoding(String value, String sourceCharsetName) {
     83         try {
     84             return new String(value.getBytes(sourceCharsetName), "UTF-8");
     85         } catch (UnsupportedEncodingException e) {
     86             throw new IllegalArgumentException(e);
     87         }
     88     }
     89 
     90     private static byte[] getSHA1Digest(String data) throws IOException {
     91         byte[] bytes = null;
     92         try {
     93             MessageDigest md = MessageDigest.getInstance("SHA-1");
     94             bytes = md.digest(data.getBytes("UTF-8"));
     95         } catch (GeneralSecurityException gse) {
     96             throw new IOException(gse);
     97         }
     98         return bytes;
     99     }
    100 
    101     private static byte[] getMD5Digest(String data) throws IOException {
    102         byte[] bytes = null;
    103         try {
    104             MessageDigest md = MessageDigest.getInstance("MD5");
    105             bytes = md.digest(data.getBytes("UTF-8"));
    106         } catch (GeneralSecurityException gse) {
    107             throw new IOException(gse);
    108         }
    109         return bytes;
    110     }
    111 
    112     private static String byte2hex(byte[] bytes) {
    113         StringBuilder sign = new StringBuilder();
    114         for (int i = 0; i < bytes.length; i++) {
    115             String hex = Integer.toHexString(bytes[i] & 0xFF);
    116             if (hex.length() == 1) {
    117                 sign.append("0");
    118             }
    119             sign.append(hex.toUpperCase());
    120         }
    121         return sign.toString();
    122     }
    123 
    124 }
    View Code

    2.获取HttpServletRequest的原生JSON参数

     1 //获取请求JSON字符串
     2     private String getParams(HttpServletRequest req) {
     3         String result = null;
     4         try {
     5             // 包装request的输入流
     6             BufferedReader br = new BufferedReader(
     7             new InputStreamReader((ServletInputStream) req.getInputStream(), "utf-8"));
     8             // 缓冲字符
     9             StringBuffer sb = new StringBuffer("");
    10             String line;
    11             while ((line = br.readLine()) != null) {
    12                 sb.append(line);
    13             }
    14             br.close();// 关闭缓冲流
    15             result = sb.toString();// 转换成字符
    16             System.out.println("result = " + result);
    17         } catch (Exception e) {
    18             e.printStackTrace();
    19         }
    20         return result;
    21     }
    View Code

    3.接口的具体实现

     1 @RequestMapping(value = "/getNoticeStockOutHeader", method = RequestMethod.POST)
     2     @ResponseBody
     3     public ResponseIntf getNoticeStockOutHeader(HttpServletRequest request, HttpServletResponse response) {
     4         response.setHeader("Access-Control-Allow-Origin", "*");// 跨域访问
     5         response.setCharacterEncoding("utf-8");
     6         ResponseIntf res = new ResponseIntf();
     7         try {
     8             request.setCharacterEncoding("utf-8");
     9             String json = this.getParams(request).replaceAll("\s*", "");//去掉所有空格
    10             String sign = request.getHeader("sign");
    11             if(StringUtils.isBlank(sign)){
    12                 throw new SecurityException("接口签名不能为空!");
    13             }
    14             if(!validateSign(json,sign)){
    15                 throw new SecurityException("签名验证不通过!");
    16             }
    17             Gson gson = new Gson();
    18             RequestIntf req = gson.fromJson(json, RequestIntf.class);
    19             res.setResult(noticeStockOutService.getNoticeStockOutHeaderList(req));
    20             res.setSuccess(true);
    21             res.setMessage("调用成功");
    22         } catch (IllegalArgumentException e) {
    23             e.printStackTrace();
    24             logger.error(StringUtils.getStackTrace(e));
    25             res.setSuccess(false);
    26             res.setMessage("参数不合法!错误信息:" + e.getMessage());
    27         } catch (SecurityException e) {
    28             e.printStackTrace();
    29             logger.error(StringUtils.getStackTrace(e));
    30             res.setSuccess(false);
    31             res.setMessage("安全异常:" + e.getMessage());
    32         } catch (AppException e) {
    33             res.setSuccess(false);
    34             res.setMessage(e.getMessage());
    35         } catch (Exception e) {
    36             e.printStackTrace();
    37             logger.error(StringUtils.getStackTrace(e));
    38             res.setSuccess(false);
    39             res.setMessage("其它异常:" + e.getMessage());
    40         }
    41         return res;
    42     }
    View Code

    4.接口采用MD5加密,直接获取原生的JSON字符串近行加密,与存放在request的header中的sign进行比对,相等,则验证成功。

    岁月本长而忙者自促;天地本宽而卑者自隘;风花雪月本闲,而劳忧者自冗;天行健,君子以自强不息;地势坤,君子以厚德载物;宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒.不妄取,不妄予,不妄想,不妄求,与人方便,随遇而安
  • 相关阅读:
    整型数字转utf8
    cmake构建时指定编译器架构(x86 or x64)
    tcp echo server libuv
    VS2015编译boost1.62
    android rom开发
    游戏昵称
    乐观锁和悲观锁
    数据库锁机制
    MySQL事务实现原理
    MySQL事务
  • 原文地址:https://www.cnblogs.com/vvning/p/7526847.html
Copyright © 2011-2022 走看看