Java实现PHP中的http_build_query()

背景:

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的官方定义:

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)); } }

 用着挺顺滑的:)

 
原文地址:https://www.cnblogs.com/timseng/p/13280722.html