背景:
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)); } }
用着挺顺滑的:)