业务处理-用户登录
代码抽取,
抽取代码
步骤: ①、用户登录界面,输入好用户信息 ②、点击登录按钮 ③、生成用户登录 UserLoginElement请求的xml文件 ④、发送请求xml给服务器 ⑥、服务器响应一个xml ⑦、手机端对服务器响应的xml进行第一个校验 进行md5值校验: timestamp(时间戳)+子代理商的密码(本地存储)+<body>......</body>(完整body内容) ⑧、将生成的md5和服务器返回的xml中的digest进行比对, ⑨、如果一样,那么就是发送给自己的,现在就进行body中内容的解析 |
1、未抽取前的用户登录模块:
|
二、进行抽取 将不变的抽取到一个抽象类中 具体的业务实现只需要继承该类,然后实现某个业务特有的方法 ①抽象类BasicService.java package cn.zengfansheng.lottery.engine;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.codec.digest.DigestUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.Xml;
import cn.zengfansheng.lottery.ConstantValue;
import cn.zengfansheng.lottery.domain.User;
import cn.zengfansheng.lottery.net.protocol.Element;
import cn.zengfansheng.lottery.net.protocol.HttpClientAdapter;
import cn.zengfansheng.lottery.net.protocol.Message;
import cn.zengfansheng.lottery.util.DES;
public abstract class BasicService {
/**
* TODO 返回Md5验证通过后的结果 (汇总)
* @param user 用户
* @param element 请求类型
* @return md5验证通过后的Message
*/
public Message getResult(User user, Element element) {
//获取xml文件
String xml = getXml(user, element);
//建立与服务连接的工具连接服务器传递当前的xml
InputStream in = sendRequest(xml);
//第一次解析,为验证md5做准备
if (in!=null) {
Message message = firstParser(in);
if (message != null) {
// 进行md5校验
if (checkMd5(message)) {
return message;
}
}
}
return null;
}
// 3、生成xml文件
/**
* 生成xml文件
* @param user 用户名
* @param element 请求的类型
* @return 返回生成用于和服务器进行通信的xml文件
*/
protected String getXml(User user, Element element) {
Message message = new Message();
if (user != null) {
message.getHeader().getUsername().setTagValue(user.getUsername());
}
return message.getXml(element);
}
// 4、建立与服务连接的工具连接服务器传递当前的xml
/**
* 和服务器通讯,并获得服务器返回的结果
* @param xml 和服务通讯的xml文件
* @return InputStream
*/
protected InputStream sendRequest(String xml) {
HttpClientAdapter clientAdapter = new HttpClientAdapter();
InputStream in = clientAdapter.sendPost(ConstantValue.URL_LOTTERY,xml);
return in;
}
/**
* 5、第一次解析,为验证md5做准备
* @param in 服务器返回的xml流对象
* @return
*/
protected Message firstParser(InputStream in) {
Message msg = new Message();// 用来保存第一次解析中的信息
if (in!=null) {//服务器返回的xml流
//TODO : 5、解析服务器回复数据(第一次解析)目的:解析出timestamp、body 和digest为下面的md5校验做准备
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(in, "utf-8");
int eventType = parser.getEventType();
while (XmlPullParser.END_DOCUMENT != eventType) {
String name = "";
switch (eventType) {
case XmlPullParser.START_TAG:
name = parser.getName();
if ("timestamp".equalsIgnoreCase(name)) {// 时间戳
String timestamp = parser.nextText();
msg.getHeader().getTimestamp().setTagValue(timestamp);
}else if ("body".equalsIgnoreCase(name)) {//body中的内容
String body = parser.nextText();
msg.getBody().setFirstDecodeBodyInfo(body);
}else if ("digest".equalsIgnoreCase(name)) {//md5加密后的
String digest = parser.nextText();
msg.getHeader().getDigest().setTagValue(digest);
}
break;
case XmlPullParser.END_TAG:
break;
}
eventType = parser.next();
}
return msg;
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
// 验证MD5信息 (timestamp+子代理商的密钥+解密后全部body信息)
/**
* 6、进行md5校验
* @param msg 要校验的信息封装的message
* @return 通过为true,反之没有通过
*/
protected boolean checkMd5(Message msg) {
DES des = new DES();//des.authcode("d8fPhfd9JkW99p8aqhtVIA==","ENCODE","0102030405060708")
// 经过第一次解析后且经过des解密的body全部的内容(使用des的密码解密)
String wholeBodyInfo = "<body>"+des.authcode(msg.getBody().getFirstDecodeBodyInfo(),"ENCODE",ConstantValue.DES_PASSWORD)+"</body>";
// 待加密md5值的字符串(服务器的时间戳+子代理商的密码+完全的body未加密信息)(使用子代理商的密码)
String md5Info = msg.getHeader().getTimestamp().getTagValue().trim()+ ConstantValue.AGENTER_PASSWORD + wholeBodyInfo.trim();
String md5Hex = DigestUtils.md5Hex(md5Info).trim();
if (msg.getHeader().getDigest().getTagValue().trim().equals(md5Hex)) {
msg.getBody().setEncodeBodyInfo(wholeBodyInfo);
return true;
}
return false;
}
} ②如用户登录具体实现业务类 UserService.java
|
|
问题: 相同的字符串,使用md5加密 windows下和android下加密后的结果不一致? |