在实际使用中,urlEncoding的处理

问题:实际使用中有个功能需要参数列表以postForm表单的形式给用户(后台通知httppost),还需要将参数列表GETFrom表单的形式给用户(前台跳转httpGET)。其中form参数中有个参数是RSA加密的结果,有特殊字符(比如说“=”号),需要urlEncoding进行转码。

转码后,客户收到请求,前台通知成功验签成功,后台通知验签失败。


问题查找:
写了个callbackAction回显代码

String body= JSON.toJSONString(getRequest().getParameterMap());
getResponse.setContentType("text/html;charset=utf-8");
Writer writer=getResponse.getWriter();
writer.write("QeryString:"+getRequest().getQueryString()+"\n");
writer.write("Body:"+body);
writer.flush();
wirter.close();


参数mac值为: abc==,urlEncode编码后abc%3d%3d。
[b]1、前台跳转时,自己拼接路径callbackurl=url?name1=value1&name2=value2
,跳转到自己的系统的页面,在页面停留几秒,然后跳转到商户的提供的地址上。[/b]

<script type="text/javascript">
var url=${callbackurl};
function callBack(){
if(url && url!=null && ""!=url){
window.location.href=url;
} else {
closeWebPage();
}
}
</script>



[b]GET请求测试:浏览器输入[/b]


http://127.0.0.1:8080/merchant-mock/callback.do?mac=abc%3d%3d

结果:页面上显示

QueryString:mac=abc%3d%3d
Body:["mac":["abc=="]]

说明:GET请求里面参数进行urlEnCode编码后会自动会被Decode回来。

[b][color=red]但是为什么POST参数,解析后验签失败呢?带着问题找答案[/color][/b]

[b]2、代码中POST请求检查[/b]
代码中,将参数value进行urlEncode编码放入map中,然后通过apache的httpClient进行POST请求。

mac=URLEncoder.encode(mac,"UTF-8");
params.put("mac",mac);


httpClient hc=new DefaultHttpClient();
httpPost httpPost=new httpPost(httpUrl);
UrlEncodeFormEntity entity=new UrlEncodeFormEntity(params,encoding);
httpPost.setEntity(entity);
...
HttpResponse response=hc.execute(httpPost);

打开httpClient的源码org.apache.http.client.entity.UrlEncodeFormEntity

public UrlEncodeFormEntity(final List<? extends NameValuePair> parameters,final String charset){

super(URLEncodedUtils.format(parameters,charset,ContentType.create(URLEncodedUtils.ContentType,charset)))
}

httpClient源码类org.apache.http.client.utils.URLEncodeUtils


public Class URLEncodeUtils{
public static final String CONTENT_TYPE="application/x-www-form-urlencoded";
public static final char QP_SEP_A='&';
public static final String NAME_VALUE_SEPARATOR="=";
public static final int RADIX =16;
...

public static String format(List parameters,String charset){
return format(parameters,QP_SEP_A,charset)
}

public static String format(List parameters,char separator,String charset){
final StringBuilder result=new StringBuilder();
for(NameValuePair parameter:parameters){
final String encodedName=encodeFormFields(parameter.getName(),charset);
final String encodedValue=encodeFormFields(parameter.getValue(),charset);
if(result.length()>0){
result.append(separator);
}
result.append(encodedName);
if(encodedValue!=null){
result.append(NAME_VALUE_SEPARATOR);
result.append(encodedValue);
}
}
return result.toString();
}


//encodeFormFormFields进行了urlEncode编码,调用urlEncode方法
public static String urlEncode(String content,Charset charset,BitSet safechars,boolean blankAsPlus){

if(content== null){
return null;
}
StringBuilder buf=new StringBuilder();
ByteBuffer bb=charset.encode(content);
while(bb.hasRemaining()){
final int b = bb.get() & oxff;
if(safechars.get(b)){
buf.append((char) b);
}else if(blankAsPlus && b ==' '){
buf.append('+');
}else{
buf.append("%");
char hex1=Character.toUpperCase(Character.forDigist((b>>4)&0xf,RADIX));
char hex2=Character.toUpperCase(Character.forDigist(b & 0xf,RADIX));
buf.append(hex1);
buf.append(hex2);
}
}
return buf.toString();

}


[b]结果:我们发现对参数做了两次urlEncoding,httpClient的UrlEncodeFormEntity自己自己拼装name1=value1&name2=vlaue2的时候已经对name和value都进行了urlEncode。使用这种方式的时候不需要主动进行urlEncoding。[/b]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值