ePos 是易宝提供的一个接口,可以实现快速网上交易,它和在线支付由很多不同。
最近在做,所以写了些心得,供大家和自己参考。
[b]背景:[/b]
流程 reqInput.jsp --> web.xml -->action -->易宝接口代码-->易宝官方服务器 --> callback.jsp
其中:reqInput.jsp的所有编码格式为 utf-8 ,
web.xml中的编码格式是 utf-8,(我们是配置的spring过滤器CharacterEncodingFilter)
callback.jsp为utf-8 ,注意一定要用外网ip可以访问到的自己的项目中的页面
[b]值的注意的地方:[/b]
1、返回网址的问题,一定要用外网。
2、中文乱码的问题,我在下面有提到
3、返回success的方法
4、p8_URL可以是点do地址,也可以是jsp页面
如何返回success呢
有几种方案,这里我只说两种方案:
1、第一种(适用于 返回地址 为 .do的情况):
try {
response.getWriter().write("success
");
return;
} catch (IOException e) {
e.printStackTrace();
}
说明:这种方式的返回一定要注意,[b]return[/b],并且要写在方法的最后面,因为不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中解压一次,那么如何实现呢,看代码
页面代码:
这个页面的form,我只提供了需要的部分,如下:
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吧。
第二种([b]我自己的终极解决方案(修改了ePos源码)[/b]):
说明: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账单没有问题,
[b]但易宝返回的时候是有问题的[/b]
这是因为易宝返回的时候会调用这个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、[b]或者当提交的时候将i设置为0,回调的时候将i的值设置为1;[/b]
不然会出现乱码,原理如上文咯。
网站有关易宝支付ePos的文章很少,我只是写出自己的想法供后来人分享,谢谢大家!同时欢迎大家讨论!