背景:
PHP實現的系統要跟Java系統通訊,通訊中要求驗簽,驗簽中需要使用PHP 的 http_build_query
一開始找下Java輪子:
/** * Java實現PHP中的http_build_query()效果 * @param array * key=value形式的二位數組 * @return */ public String http_build_query(Map<String ,String> array){ String reString = null; //遍歷數組形成akey=avalue&bkey=bvalue&ckey=cvalue形式的的字符串 Iterator it = array.entrySet().iterator(); while (it.hasNext()){ Map.Entry<String,String> entry =(Map.Entry) it.next(); String key = entry.getKey(); String value = entry.getValue(); reString += key+"="+value+"&"; } reString = reString.substring(0, reString.length()-1); //將得到的字符串進行處理得到目標格式的字符串 try { reString = java.net.URLEncoder.encode(reString,"utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } reString = reString.replace("%3D", "=").replace("%26", "&"); return reString; }
這個簡單的處理只能應用在GET請求和POST form表單,對稍微正常復雜點的POST json無能為力,而Java 的Springboot 的封裝又使Json的封裝很普遍,表現在接口上就是Post Json
來看下http_build_query的官方定義:
普通的字符串拼接已經完全處理不了下面這種很常見的post json請求
通過觀察這一層層的拼接,這就是幾棵樹嘛,只能祭出大招:遞歸
以下是java實現
package com.jds.util; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.util.*; @SuppressWarnings("AlibabaCollectionInitShouldAssignCapacity") @Slf4j public class PHPUtil { /** * Java實現PHP中的http_build_query()效果 * @return */ public static String http_build_query(Map<String,Object> array,boolean sort) throws Exception { String reString = ""; //遍歷數組形成akey=avalue&bkey=bvalue&ckey=cvalue形式的的字符串 reString=rescBuild(array,"",true,sort); reString = StringUtils.removeEnd(reString,"&"); //reString = reString.substring(0, reString.length()-1); //將得到的字符串進行處理得到目標格式的字符串:utf8處理中文出錯 reString = java.net.URLEncoder.encode(reString,"utf-8"); reString = reString.replace("%3D", "=").replace("%26", "&"); return reString; } static String rescBuild(Object object,String parentStr,boolean first,boolean sort) throws Exception { String r=""; if(object instanceof Map){ List<Map.Entry<String,Object>> list = new ArrayList<Map.Entry<String,Object>>(((Map<String, Object>)object).entrySet()); //按照map的key排序
if(sort){ Collections.sort(list,new Comparator<Map.Entry<String,Object>>() { //升序排序 public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) { return o1.getKey().compareTo(o2.getKey()); } }); } for(Map.Entry<String,Object> mapping:list){ String key = mapping.getKey(); Object value = mapping.getValue(); if(first){ r+= rescBuild(value,key,false,sort); }else{ r+= rescBuild(value,parentStr+"["+key+"]",false,sort); } } }else if(object instanceof List){ for (int i = 0; i <((List)object).size() ; i++) { r+= rescBuild(((List)object).get(i),parentStr+"["+i+"]",false,sort); }
//葉節點是String或者Number }else if(object instanceof String){ r+= parentStr+"="+ object.toString()+"&"; }else if(object instanceof Number){ r+= parentStr+"="+ ((Number)object).toString()+"&"; } return r; } public static void main(String[] args) throws Exception { // Map<String,Object> array = new HashMap<>();// Map<String,Object> user = new HashMap<>(); // user.put("name","Bob Smith"); // user.put("age",47); // user.put("sex","M"); // user.put("dob","5/12/1956"); // // array.put("user",user); // // array.put("pastimes",Arrays.asList("golf","opera","poker","rap")); // // Map<String,Object> bobby = new HashMap<>(); // bobby.put("age",12); // bobby.put("sex","M"); // Map<String,Object> sally = new HashMap<>(); // sally.put("age",8); // sally.put("sex","F"); // // Map<String,Object> children = new HashMap<>(); // // children.put("bobby",bobby); // children.put("sally",sally); // // array.put("children",children); // System.out.println(http_build_query(array)); // System.out.println(http_build_query(array)); // System.out.println(array); // System.out.println(JSON.toJSONString(array)); // String x=""; // x=rescBuild(array,"",true); // System.out.println(x); Map<String,Object> upmap=new HashMap(); upmap.put("versionname","9.2"); upmap.put("channels",Arrays.asList(1,2)); upmap.put("aspace","space"); System.out.println(http_build_query(upmap,true)); } }
用着挺順滑的:)