[解决方案]springboot怎么接受encode后的参数(参数通过&=拼接)

springboot怎么接受encode后的参数(拼接&=)

问题出现原因

博主近期对接了一家对安全系数要求很高的银行api,
发送方式:post-application/x-www-form-urlencoded
对方发送过来的报文格式是这样的
(encode前)data=这是一个data&sign=这是一个sign
(encode后)data%3D%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AAdata%26sign%3D%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AAsign
ps: 真实参数data里面也是加密的

encode前的值发送接收是没有一点问题的,encode后的值没有了=与&,这个时候就出现问题了,springboot在接受的时候不会自己解码的。

发送encode后的值在postman里面的情况

发送encode后的值就变成了这样,如下图(因为没有了=与&)
直观点展示
在这里插入图片描述

这个时候该如何接受呢(encode后的值接受)

思路: 用request接受,取表单中的第一个key解码,然后在通过=与&解析成json

controller层的代码


import com.alibaba.fastjson.JSON;
import com.test.util.CRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Set;

@RestController
@Slf4j
public class TestTwoController {



    @RequestMapping(value = "/verify/from",method = RequestMethod.POST)
    public String verifyPostFrom(String data,String sign,HttpServletRequest request){
        log.info("收到报文data:{},sign:{}",data,sign);
        Map<String, String> map = decryptDataTo(request);
        log.info("解析后的param:{}",JSON.toJSONString(map));
        return "Hello !!!";
    }


    public Map<String, String> decryptDataTo(HttpServletRequest request){
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> strings = parameterMap.keySet();
        if (ObjectUtils.isEmpty(strings)){
            return null;
        }
        String param = strings.iterator().next();
        // 有些版本设置了自动解码可以不手动解码
        //String decode = URLDecoder.decode(param);
        //System.out.println(decode);
        String next = "?"+decode;
        Map<String, String> stringStringMap = CRequest.uRLRequest2(next);
        return stringStringMap;
    }
}


用到的工具类CRequest


import java.util.HashMap;
import java.util.Map;



public class CRequest {


    /**
     * 解析出url请求的路径,包括页面
     * @param strURL url地址
     * @return url路径
     */
    public static String UrlPage(String strURL)
    {
        String strPage=null;
        String[] arrSplit=null;
        strURL=strURL.trim().toLowerCase();
        arrSplit=strURL.split("[?]");
        if(strURL.length()>0)
        {
            if(arrSplit.length>1)
            {
                if(arrSplit[0]!=null)
                {
                    strPage=arrSplit[0];
                }
            }
        }
        return strPage;
    }
    /**
     * 去掉url中的路径,留下请求参数部分
     * @param strURL url地址
     * @return url请求参数部分
     */
    private static String TruncateUrlPage(String strURL)
    {
        String strAllParam=null;
        String[] arrSplit=null;
        arrSplit=strURL.split("[?]");
        if(strURL.length()>1)
        {
            if(arrSplit.length>1)
            {
                if(arrSplit[1]!=null)
                {
                    strAllParam=arrSplit[1];
                }
            }
        }
        return strAllParam;
    }
    /**
     * 解析出url参数中的键值对
     * 如 "index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中
     * @param URL url地址
     * @return url请求参数部分
     */
    public static Map<String, String> URLRequest(String URL)
    {
        Map<String, String> mapRequest = new HashMap<String, String>();
        String[] arrSplit=null;
        String strUrlParam=TruncateUrlPage(URL);
        if(strUrlParam==null)
        {
            return mapRequest;
        }
        //每个键值为一组
        arrSplit=strUrlParam.split("[&]");
        for(String strSplit:arrSplit)
        {
            String[] arrSplitEqual=null;
            arrSplitEqual= strSplit.split("[=]");
            //解析出键值
            if(arrSplitEqual.length>1)
            {
            //正确解析
                mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
            }
            else
            {
                if(arrSplitEqual[0]!="")
                {
            //只有参数没有值,不加入
                    mapRequest.put(arrSplitEqual[0], "");
                }
            }
        }
        return mapRequest;
    }


    public static Map<String, String> uRLRequest2(String URL)
    {
        Map<String, String> mapRequest = new HashMap<String, String>();
        String[] arrSplit=null;
        String strUrlParam=TruncateUrlPage(URL);
        if(strUrlParam==null)
        {
            return mapRequest;
        }
        //每个键值为一组
        arrSplit=strUrlParam.split("[&]");
        for(String strSplit:arrSplit)
        {
            String[] arrSplitEqual=null;
            arrSplitEqual= strSplit.split("[=]",2);
            //解析出键值
            if(arrSplitEqual.length>1)
            {
                //正确解析
                mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
            }
            else
            {
                if(arrSplitEqual[0]!="")
                {
                    //只有参数没有值,不加入
                    mapRequest.put(arrSplitEqual[0], "");
                }
            }
        }
        return mapRequest;
    }
}



不合常理的对接,不过从安全方面讲这种加密方式传输又在合理之中/。

希望本文能为你节省时间。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值