说实话 听着这个视频 ,黑马的彩票视频 我看了五遍 关于协议的封装 我自己觉得很难懂 不过搞懂以后 我自己学到了很多。
关于封装,也是因为项目 需要,不过确实对代码,结构优化了很多。 我自己在认真的总结。
前一篇 已经把一个节点已经生成完了,
再看 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()); }*/ }