come!教你如何搞定易宝 ePos

ePos 是易宝提供的一个接口,可以实现快速网上交易,它和在线支付由很多不同。
最近在做,所以写了些心得,供大家和自己参考。



背景:

流程 reqInput.jsp --> web.xml -->action -->易宝接口代码-->易宝官方服务器 --> callback.jsp
其中:reqInput.jsp的所有编码格式为 utf-8 ,
     web.xml中的编码格式是 utf-8,(我们是配置的spring过滤器CharacterEncodingFilter)
     
callback.jsp为utf-8 ,注意一定要用外网ip可以访问到的自己的项目中的页面


值的注意的地方:


1、返回网址的问题,一定要用外网。
2、中文乱码的问题,我在下面有提到
3、返回success的方法
4、p8_URL可以是点do地址,也可以是jsp页面



如何返回success呢

有几种方案,这里我只说两种方案:

1、第一种(适用于 返回地址 为 .do的情况):
		
try {
response.getWriter().write("success<br>");
return;
} catch (IOException e) {
e.printStackTrace();
}

说明:这种方式的返回一定要注意, return,并且要写在方法的最后面,因为不return的话,系统会持续的发送 success流。


2、第二种(适用于 返回地址 为 jsp等页面的情况):
  就是 callback页面中的 out.println("success"); 

说明一下:第二种方式是易宝的demo用的方式,在callback页面中你可以嵌入自己的代码,等待易宝返回,易宝异步返回的时间大概是2分钟左右
我测试的时间如下:
Wed Oct 13 13:04:53 GMT 2010updateEpos_success
Wed Oct 13 13:06:10 GMT 2010cellCenter epos return.........




中文乱码的问题

相信重构ePos的同志们,都会遇到吧,易宝要求的是 GBK或者GB2312,我这里有几种解决方案,但是在写解决方案之前,我们要理清ePos的一个简单流程:页面-->Action-->ePos源码,这样就很容易测试是哪里的问题了:


1、第一种(这里只提供提示,这种不一定真正解决问题,主要看第二种):
页面中压缩一次(ps:网上有的说可以压缩两次),action中解压一次,那么如何实现呢,看代码
页面代码:
		
<script type="text/javascript">
function verify() {
alert($("#buyName").val());
var url = "userCenter/summitmsg!subDateToYee.do?p5_Pid=" + encodeURI($("#rName").val()) 
+ "&pf_BuyerName=" + encodeURI($("#buyName").val());
}
</script>


这个页面的form,我只提供了需要的部分,如下:

<form id="fom1" onsubmit="verify()"  action="userCenter/summitmsg!subDateToYee.do" method="post">
<input id="rName" type="hidden" name="p5_Pid" value="">
<input id="buyName" type="hidden" name="pf_BuyerName" value="" >


action类中的代码:
URLEncoder.encode(request.getParameter("p5_Pid"), "GBK")



说一下这段代码,
userCenter/summitmsg!subDateToYee.do 这一句是指form中的action所指向的action地址,后面的问号不说了,p5_Pid是商品名称,它是中文的所以需要编码, 在javaScript中先通过id得到需要转码的标签的id,通过id拿到相应的值,然后用encodeURI()方法编码(ps: 关于这个方法大家可以查一下:http://www.w3school.com.cn/js/jsref_encodeURI.asp),关于Action类中的方法,大家查一下 javaAPI吧。


第二种( 我自己的终极解决方案(修改了ePos源码)):
说明:ePos最终会得到一个url串,然后用url ,getConnection的方法提交到易宝去,格式如:www.xxx.action?参数1=值&参数2=值....  值的注意的是ProcessUtil类,这个类是通过key得到值的实现类,易宝首先得到form表单中的所有name值,然后再这个类里面通过形如:request.getParameter("p5_Pid")的方式拿到值。

OK!关键地方来了,在这个类中有一个方法是:
public static Map processParameterMap(HttpServletRequest request, String serverCharsetName, String pageCharsetName)

易宝将这个方法称为:“将HttpServletRequest传入获得所有参数与参数值Map的方法”,这个方法中有一句话(重要,吗的 我试了好多次,才知道是这里,晕,革命尚未成功,同志仍需努力):
value = new String(value.getBytes(serverCharsetName), pageCharsetName);

注意两个参数 serverCharsetName 和 pageCharsetName,在ServerInfo.java类中将这两个参数已经写好了,serverCharsetName 的值是 iso-8859-1 ,pageCharsetName的值是GBK,对了,你没有看错,第二个参数就是易宝最终要的编码格式。问题就出在这句话里面。一般情况下,UTF 转GBK中间是经过一道程序的那就是 UTF--》iso-8859-1---》GBK,但是,我的解决方式如下:
value = new String(value.getBytes(), pageCharsetName);

将第一个参数去掉,在运行程序,易宝账号中查看ePos账单没有问题,


但易宝返回的时候是有问题的


这是因为易宝返回的时候会调用这个processParameterMap()方法,而且易宝默认的会找到 value = new String(value.getBytes(serverCharsetName), pageCharsetName); 这一句话,也就是:value = new String(value.getBytes(iso-8859-1), "gbk");   因为我已经将这句话的第一个参数改为没有参数了,即
value = new String(value.getBytes(), pageCharsetName);
这样的话,易宝找不到它想要的那句话,就返回失败了,所以问题又来了,易宝返回乱码!

我的解决方案是:提交的时候用 value=new String(value.getBytes(), "GBK")
返回的时候 用  value=new String(value.getBytes("iso-8859-1"), "GBK");

看我修改过的易宝Process类的代码(只展示修改的部分)
public class ProcessUtil {
  private static int i = 0;//记录方法调用次数
  
  // 将HttpServletRequest传入获得所有参数与参数值Map的方法
  public static Map processParameterMap(HttpServletRequest request, String serverCharsetName, String pageCharsetName){
    final Map returnMap = new HashMap();
    String key = "";
    String value = "";
    Enumeration names = request.getParameterNames();
    while(names.hasMoreElements()){
      key = (String)names.nextElement();
      value = request.getParameter(key);
      try {
        if(i == 0) {
	      value = new String(value.getBytes(), pageCharsetName);
	      System.out.println("i为1的时候;" + value);
        } else {
	      value = new String(value.getBytes(serverCharsetName),  pageCharsetName);
	      System.out.println("i为"+i+"的时候;" + value);
        }
      } catch (UnsupportedEncodingException uee) {
	uee.printStackTrace();
      }
       returnMap.put(key, value);
	}
    //此处要注意
    i++;
    return returnMap;
 }
}



之后,我们有两种方式来设置i的值(重点看 第二种方式):

1、我们易宝成功返回后我们在action类中可以将 i 值 重新设置为 0,提交失败后也要将 i 值重新设置为0;
2、 或者当提交的时候将i设置为0,回调的时候将i的值设置为1;

不然会出现乱码,原理如上文咯。




网站有关易宝支付ePos的文章很少,我只是写出自己的想法供后来人分享,谢谢大家!同时欢迎大家讨论!



你可能感兴趣的:(JavaScript,spring,jsp,qq,asp)