说实话 听着这个视频 ,黑马的彩票视频 我看了五遍 关于协议的封装 我自己觉得很难懂 不过搞懂以后 我自己学到了很多。
关于封装,也是因为项目 需要,不过确实对代码,结构优化了很多。 我自己在认真的总结。
前一篇 已经把一个节点已经生成完了,
再看 body这个节点 有着element这个子节点 然后 不会将所有的请求用到的叶子放到Element中 Element将作为所有请求的代表,Element所有请求的公共部分
公共部分:
①每个请求都需要序列化自己
这 个element需要抽象或者作为一个接口 约束自己的孩子
element
package com.xiaoxin.CaiPiao.net.protocal;
import org.xmlpull.v1.XmlSerializer;
/**
* 请求数据的封装
*
* @author Administrator
* 可以使用抽象或者接口约束自己的孩子
*/
public abstract class Element {
// 不会将所有的请求用到的叶子放到Element中
// Element将作为所有请求的代表,Element所有请求的公共部分
// 公共部分:
// ①每个请求都需要序列化自己
/**
* 每个请求都需要序列化自己
* @param serializer
*/
public abstract void serializerElement(XmlSerializer serializer);
// ②每个请求都有自己的标示
/**
* 每个请求都有自己的标示
* @return
*/
public abstract String getTransactionType();
// 包含内容
// 序列化
// 特有:请求标示
// <lotteryid>118</lotteryid>
// private Leaf lotteryid = new Leaf("lotteryid");
// <issues>1</issues>
// private Leaf issues = new Leaf("issues", "1");
// public Leaf getLotteryid() {
// return lotteryid;
// }
// /**
// * 序列化请求
// */
// public void serializerElement(XmlSerializer serializer) {
// try {
// serializer.startTag(null, "element");
// lotteryid.serializerLeaf(serializer);
// issues.serializerLeaf(serializer);
// serializer.endTag(null, "element");
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// /**
// * 获取请求的标示
// */
// public String getTransactionType() {
// return "12002";
// }
}
其实这么做很方便 以后代码的维护 和更新 因为在子孩子里面只需要继承element 子孩子要求如下
①必须继承Element
如:获取当前销售期请求
public class CurrentIssueElement extends Element
②处理Element的两个方法
需要结合接口文档,获取当前销售期请求
// <lotteryid>118</lotteryid>
private Leaf lotteryid = new Leaf("lotteryid");
// <issues>1</issues>
private Leaf issues = new Leaf("issues", "1");
@Override
public void serializerElement(XmlSerializer serializer) {
try {
serializer.startTag(null, "element");
lotteryid.serializerLeaf(serializer);
issues.serializerLeaf(serializer);
serializer.endTag(null, "element");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String getTransactionType() {
return "12002";
}
然后再看下子孩子CurrentIssueElement .java
package com.xiaoxin.CaiPiao.net.protocal.element;
import org.xmlpull.v1.XmlSerializer;
import com.xiaoxin.CaiPiao.net.protocal.Element;
import com.xiaoxin.CaiPiao.net.protocal.Leaf;
public class CurrentIssueElement extends Element{
// <lotteryid>118</lotteryid>
private Leaf lotteryid = new Leaf("lotteryid");
// <issues>1</issues>
private Leaf issues = new Leaf("issues", "1");
@Override
public void serializerElement(XmlSerializer serializer) {
try {
serializer.startTag(null, "element");
lotteryid.serializerLeaf(serializer);
issues.serializerLeaf(serializer);
serializer.endTag(null, "element");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String getTransactionType() {
return "12002";
}
public Leaf getLotteryid() {
return lotteryid;
}
}
可以看的出来 子孩子制作了 包含内容 以及序列化 这样子 便于以后协议的修改和添加
看了这里 我们需要看看body 内容 因为 因为body 要把element子节点 封装进去 序列化
/**
* <body>
<elements>
<element>
<lotteryid>118</lotteryid>
<issues>1</issues>
</element>
</elements>
</body>
*/
package com.xiaoxin.CaiPiao.net.protocal;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
import com.xiaoxin.CaiPiao.ConstantValue;
import com.xiaoxin.CaiPiao.utils.DES;
/**
* 消息体结点封装
* @author Administrator
*
*/
public class Body {
//因为不止一个elements内容 所以 需要一个集合来接受
private List<Element> elements=new ArrayList<Element>();
/*********************处理服务器回复*************************/
private String serviceBodyInsideDESInfo;//服务器端回复的body中的DES加密的信息
private Oelement oelement=new Oelement();
public Oelement getOelement() {
return oelement;
}
public String getServiceBodyInsideDESInfo() {
return serviceBodyInsideDESInfo;
}
public void setServiceBodyInsideDESInfo(String serviceBodyInsideDESInfo) {
this.serviceBodyInsideDESInfo = serviceBodyInsideDESInfo;
}
/*********************处理服务器回复*************************/
public List<Element> getElements() {
return elements;
}
/**
* 序列化请求
*/
public void serializerBody(XmlSerializer serializer) {
/**
* <body>
<elements>
<element>
<lotteryid>118</lotteryid>
<issues>1</issues>
</element>
</elements>
</body>
*/
try {
serializer.startTag(null, "body");
serializer.startTag(null, "elements");
for(Element item:elements){
item.serializerElement(serializer);
}
serializer.endTag(null, "elements");
serializer.endTag(null, "body");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取到完整的body
* @return
*/
public String getWholeBody()
{
StringWriter writer=new StringWriter();
XmlSerializer temp=Xml.newSerializer();
try {
temp.setOutput(writer);
this.serializerBody(temp);
// output will be flushed
temp.flush();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取body里面的DES加密数据
* @return
*/
public String getBodyInsideDESInfo()
{
// 加密数据
String wholeBody = getWholeBody();
String orgDesInfo=StringUtils.substringBetween(wholeBody, "<body>", "</body>");
// 加密
// 加密调试——2天
// ①加密算法实现不同
// ②加密的原始数据不同
DES des=new DES();
return des.authcode(orgDesInfo, "DECODE", ConstantValue.DES_PASSWORD);
}
}
message.xml 终结点 有一个attribute属性
package com.xiaoxin.CaiPiao.net.protocal;
import java.io.StringWriter;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
import com.xiaoxin.CaiPiao.ConstantValue;
/**
* 协议封装
*
* @author Administrator
*
*/
public class Message {
private Header header = new Header();
private Body body = new Body();
public Header getHeader() {
return header;
}
public Body getBody() {
return body;
}
/**
* 序列化协议
*/
public void serializerMessage(XmlSerializer serializer) {
try {
// <message version="1.0">
serializer.startTag(null, "message");
// MUST follow a call to startTag() immediately
serializer.attribute(null, "version", "1.0");
header.serializerHeader(serializer, body.getWholeBody());// 获取完整的body
// body.serializerBody(serializer);
serializer.startTag(null, "body");
serializer.text(body.getBodyInsideDESInfo());
serializer.endTag(null, "body");
serializer.endTag(null, "message");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取请求的xml文件
*
* @return
*/
public String getXml(Element element) {
if (element == null) {
throw new IllegalArgumentException("element is null");
}
// 请求标示需要设置,请求内容需要设置
header.getTransactiontype().setTagValue(element.getTransactionType());
body.getElements().add(element);
// 序列化
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
// This method can only be called just after setOutput
try {
serializer.setOutput(writer);
serializer.startDocument(ConstantValue.ENCONDING, null);
this.serializerMessage(serializer);
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 需要处理的问题:
// ①MD5处理时需要完整的明文body
// ②请求标示需要设置,请求内容需要设置
// ③加密body里面的数据
// ④Element通用
}
生成xml的代码就简单了
package com.xiaoxin.CaiPiao.test;
import java.io.StringWriter;
import org.xmlpull.v1.XmlSerializer;
import com.xiaoxin.CaiPiao.ConstantValue;
import com.xiaoxin.CaiPiao.net.protocal.Message;
import com.xiaoxin.CaiPiao.net.protocal.element.CurrentIssueElement;
import com.xiaoxin.CaiPiao.utils.BeanFactory;
import android.test.AndroidTestCase;
import android.util.Log;
import android.util.Xml;
public class XmlTest extends AndroidTestCase {
private static final String TAG = "XmlTest";
public void createXMl() {
Message message = new Message();
CurrentIssueElement element = new CurrentIssueElement();
element.getLotteryid().setTagValue("118");
String xml = message.getXml(element);
Log.i(TAG, xml);
}
public void createXMl2() {
// 序列化
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
// This method can only be called just after setOutput
try {
serializer.setOutput(writer);
serializer.startDocument(ConstantValue.ENCONDING, null);
Message message = new Message();
message.serializerMessage(serializer);
serializer.endDocument();
} catch (Exception e) {
e.printStackTrace();
}
}
public void createXMl1() {
// 序列化
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
// This method can only be called just after setOutput
try {
//生成一个XML
serializer.setOutput(writer);
serializer.startDocument(ConstantValue.ENCONDING, null);
serializer.startTag(null, "message");
serializer.startTag(null, "header");
serializer.startTag(null, "agenterid");
serializer.text(ConstantValue.AGENTERID);
serializer.endTag(null, "agenterid");
serializer.startTag(null, "agenterid");
serializer.text(ConstantValue.AGENTERID);
serializer.endTag(null, "agenterid");
serializer.startTag(null, "agenterid");
serializer.text(ConstantValue.AGENTERID);
serializer.endTag(null, "agenterid");
serializer.endTag(null, "header");
serializer.startTag(null, "body");
serializer.endTag(null, "body");
serializer.endTag(null, "message");
serializer.endDocument();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 存在问题:
// 项目组形势开发:5人,100请求
// 无法预估
// ①开发、维护成本高——代码冗余,极易出错
// ②交接代码:开发、沟通成本
// ③生成了五个封装协议的版本代码
// ④协议变更了
// 预估 :
// 学习协议:5*0.5天
// 学习协议结果的交流:5*0.5天
// 风险管理——规避风险、时间影响最小化
// 单独抽一人学习协议,抽取出一个协议封装的版本(公共)
// 协议 不同之处需要交由其他开发人员处理
}
/*public void testUserLogin() {
// UserEngineImpl impl=new UserEngineImpl();
// UserEngineImpl1
// User user=new User();
// user.setUsername("13200000000");
// user.setPassword("0000000");
// Message login = impl.login(user);
// Log.i(TAG, login.getBody().getOelement().getErrorcode());
UserEngine engine = BeanFactory.getImpl(UserEngine.class);
User user = new User();
user.setUsername("13200000000");
user.setPassword("0000000");
Message login = engine.login(user);
Log.i(TAG, login.getBody().getOelement().getErrorcode());
}*/
}