消息加密

需要到入库:commons-io-2.4.jar,commons-codec-1.9.jar(在官网的Java微信加密demo下)

第一步:访问https://mp.weixin.qq.com/wiki,下载AES加密的示例代码

第二步:新建com.wtz.aes包,把实例代码中的8个AES加密类复制进去,将这些类的包名改为com.wtz.aes,导入库commons-codec-1.9.jar,选上面的Project下的Properties,点击Java Build Path,Libraries,Add Library,选Junit 4,Next,Finish,OK,AES加密导入完成

第三步:找到包com.wtz.util,新建类Parameter.java类,存放参数token,encodingAESKey(随机戳),corpId(AppID),这些在基本配置处可以得到

 package com.wtz.util;

 /**
* @author wangtianze QQ:864620012
* @date 2017年4月21日 下午9:27:50
* <p>version:1.0</p>
* <p>description:参数api</p>
*/
public class Parameter {
//token
public static String token = "wangtianze";
//随机戳
public static String encodingAESKey = "X78dYU3MXpijKArRbiozTRq0jZZnjxxvuB4n8KJwRH1";
//应用AppID
public static String corpId = "wx9621c31e147dfdf9";
}

第四步:找到包com.wtz.util下的MessageUtil.java类,修改parseXml方法

 package com.wtz.util;

 import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.wtz.message.response.ImageMessage;
import com.wtz.message.response.MusicMessage;
import com.wtz.message.response.NewsMessage;
import com.wtz.message.response.TextMessage;
import com.wtz.message.response.VideoMessage;
import com.wtz.message.response.VoiceMessage; /**
* @author wangtianze QQ:864620012
* @date 2017年4月19日 下午3:29:58
* <p>version:1.0</p>
* <p>description:消息处理工具类</p>
*/
public class MessageUtil {
//请求消息类型:文本
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
//请求消息类型:图片
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
//请求消息类型:语音
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
//请求消息类型:视频
public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
//请求消息类型:地理位置
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
//请求消息类型:链接
public static final String REQ_MESSAGE_TYPE_LINK = "link";
//请求消息类型:事件推送
public static final String REQ_MESSAGE_TYPE_EVENT = "event"; //--------------------------------------------------------------- //事件类型:subscribe(订阅)
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
//事件类型:unsubscribe(取消订阅)
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
//事件类型:scan(用户已关注时的扫描带参数的二维码)
public static final String EVENT_TYPE_SCAN = "scan";
//事件类型:LOCATION(上报地理位置)
public static final String EVENT_TYPE_LOCATION = "LOCATION";
//事件类型:CLICK(自定义菜单)
public static final String EVENT_TYPE_CLICK = "CLICK"; //--------------------------------------------------------------- //响应消息类型:文本
public static final String RESP_MESSAGE_TYPE_TEXT = "text";
//响应详细类型:图片
public static final String RESP_MESSAGE_TYPE_IMAGE = "image";
//响应消息类型:语音
public static final String RESP_MESSAGE_TYPE_VOICE = "voice";
//响应消息类型:视频
public static final String RESP_MESSAGE_TYPE_VIDEO = "video";
//响应详细类型:音乐
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
//响应消息类型:图文
public static final String RESP_MESSAGE_TYPE_NEWS = "news"; //--------------------------------------------------------------- //-----------------------------------------老的,加密前---------------------------------------------
// //从流中解析出每个节点的内容
// public static Map<String,String> parseXml(HttpServletRequest request) throws IOException{
// Map<String,String> map = new HashMap<String,String>();
//
// //从输入流中获取流对象
// InputStream in = request.getInputStream();
//
// //构建SAX阅读器对象
// SAXReader reader = new SAXReader();
// try {
// //从流中获得文档对象
// Document doc = reader.read(in);
//
// //获得根节点
// Element root = doc.getRootElement();
//
// //获取根节点下的所有子节点
// List<Element> children = root.elements();
//
// for(Element e:children){
// //遍历每一个节点,并按照节点名--节点值放入map中
// map.put(e.getName(), e.getText());
// System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText());
// }
//
// //关闭流
// in.close();
// in = null;
// } catch (DocumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// return map;
// }
//-----------------------------------------新的,加密后--------------------------------------------
//从流中解析出每个节点的内容
public static Map<String,String> parseXml(String request) throws IOException{
Map<String,String> map = new HashMap<String,String>(); //从request中获取流对象
InputStream in = new ByteArrayInputStream(request.getBytes("UTF-8")); //构建SAX阅读器对象
SAXReader reader = new SAXReader();
try {
//从流中获得文档对象
Document doc = reader.read(in); //获得根节点
Element root = doc.getRootElement(); //获取根节点下的所有子节点
List<Element> children = root.elements(); for(Element e:children){
//遍历每一个节点,并按照节点名--节点值放入map中
map.put(e.getName(), e.getText());
System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText());
} //关闭流
in.close();
in = null;
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return map;
}
//---------------------------------------------------------------------------------------------- /**
* 用于扩展节点数据按照<ToUserName><![CDATA[toUser]]></ToUserName>,中间加了CDATA段
*/
private static XStream xstream = new XStream(new XppDriver(){
public HierarchicalStreamWriter createWriter(Writer out){
return new PrettyPrintWriter(out){
boolean cdata = true;
public void startNode(String name,Class clazz){
super.startNode(name,clazz);
} protected void writeText(QuickWriter writer,String text){
if(cdata){
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
}else{
writer.write(text);
}
}
};
}
}); /**
* 将文本消息对象转换成XML格式
* params:textMessage 文本消息对象
* return:xml
*/
public static String messageToXml(TextMessage textMessage){
xstream.alias("xml",textMessage.getClass());
return xstream.toXML(textMessage);
} /**
* 将图片消息对象转换成XML格式
* params:imageMessage
* return:xml
*/
public static String messageToXml(ImageMessage imageMessage){
xstream.alias("xml", imageMessage.getClass());
return xstream.toXML(imageMessage);
} /**
* 将语音消息对象转换成XML格式
* params:voiceMessage
* return:xml
*/
public static String messageToXml(VoiceMessage voiceMessage){
xstream.alias("xml",voiceMessage.getClass());
return xstream.toXML(voiceMessage);
} /**
* 将视频消息对象转换成XML格式
* params:videoMessage
* return:xml
*/
public static String messageToXml(VideoMessage videoMessage){
xstream.alias("xml",videoMessage.getClass());
return xstream.toXML(videoMessage);
} /**
* 将音乐消息对象转换成XML格式
* params:musicMessage
* return:xml
*/
public static String messageToXml(MusicMessage musicMessage){
xstream.alias("xml",musicMessage.getClass());
return xstream.toXML(musicMessage);
} /**
* 将图文消息对象转换成XML格式
* params:newsMessage
* return:xml
*/
public static String messageToXml(NewsMessage newsMessage){
xstream.alias("xml",newsMessage.getClass());
return xstream.toXML(newsMessage);
}
}

第五步:找到包com.wtz.util下的ProcessService.java类,修改dealRequest方法

 package com.wtz.util;

 import java.io.IOException;
import java.util.Date;
import java.util.Map; import javax.servlet.http.HttpServletRequest; import com.wtz.dao.PostCodeDao;
import com.wtz.message.response.TextMessage; /**
* @author wangtianze QQ:864620012
* @date 2017年4月19日 下午8:04:14
* <p>version:1.0</p>
* <p>description:核心服务类</p>
*/
public class ProcessService {
//定义数据访问的dao
private static PostCodeDao dao = new PostCodeDao(); //-----------------------------------老的,加密前--------------------------------------------------
// public static String dealRequest(HttpServletRequest request){
// //XML格式的消息数据
// String respXml = "";
// //默认返回的文本消息内容
// String respContent = "未知的消息类型";
// //调用parseXml方法解析请求消息
// Map<String, String> requestMap;
// try {
// requestMap = MessageUtil.parseXml(request);
// //发送方账号
// String fromUserName = requestMap.get("FromUserName");
// //开发者微信号
// String toUserName = requestMap.get("ToUserName");
// //消息类型
// String MsgType = requestMap.get("MsgType");
// //消息内容
// String content = requestMap.get("Content");
//
// //回复文本消息
// TextMessage textMessage = new TextMessage();
// textMessage.setToUserName(fromUserName);
// textMessage.setFromUserName(toUserName);
// textMessage.setCreateTime(new Date().getTime());
// textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
//
// if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){
// respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
// if(content.equals("1")){
// respContent = "请按照格式输入地区名,例如输入 邮编:东城";
// }
// if(content.equals("2")){
// respContent = "请按照格式输入地区名,例如输入 区号:东城";
// }
// if(content.equals("?")){
// respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
// }
// if(content.startsWith("邮编:")){
// int pos = content.indexOf(":");
// String cityName = content.substring(pos + 1);
// respContent = dao.findPostCodeByCityName(cityName);
// System.out.println("邮编:respContent:" + respContent);
// }
// if(content.startsWith("区号:")){
// int pos = content.indexOf(":");
// String cityName = content.substring(pos + 1);
// respContent = dao.findTelCodeByCityName(cityName);
// System.out.println("区号:respContent:" + respContent);
// }
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){
// respContent = "您发送的是图片消息";
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
// respContent = "您发送的是语音消息";
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)){
// respContent = "您发送的是视频消息";
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)){
// respContent = "您发送的是地理位置消息";
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)){
// respContent = "您发送的是链接消息";
// }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){
// //事件类型
// String eventType = requestMap.get("Event");
// if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
// respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
// }else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
// //TODO 取消订阅后用户不会再收到公众号发送的消息,因此不需要回复
// }else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){
// //TODO 处理扫描带参数二维码事件
// }else if(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)){
// //TODO 处理上报地理位置事件
// }else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
// //TODO 处理菜单点击事件
// }
// }
// //设置文本消息的内容
// textMessage.setContent(respContent);
// //将文本消息对象转换成xml
// respXml = MessageUtil.messageToXml(textMessage);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// return respXml;
// } //----------------------------------------------新的,加密后---------------------------------------------
public static String dealRequest(String request){
//XML格式的消息数据
String respXml = "";
//默认返回的文本消息内容
String respContent = "未知的消息类型";
//调用parseXml方法解析请求消息
Map<String, String> requestMap;
try {
requestMap = MessageUtil.parseXml(request);
//发送方账号
String fromUserName = requestMap.get("FromUserName");
//开发者微信号
String toUserName = requestMap.get("ToUserName");
//消息类型
String MsgType = requestMap.get("MsgType");
//消息内容
String content = requestMap.get("Content"); //回复文本消息
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT); if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){
respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
if(content.equals("1")){
respContent = "请按照格式输入地区名,例如输入 邮编:东城";
}
if(content.equals("2")){
respContent = "请按照格式输入地区名,例如输入 区号:东城";
}
if(content.equals("?")){
respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
}
if(content.startsWith("邮编:")){
int pos = content.indexOf(":");
String cityName = content.substring(pos + 1);
respContent = dao.findPostCodeByCityName(cityName);
System.out.println("邮编:respContent:" + respContent);
}
if(content.startsWith("区号:")){
int pos = content.indexOf(":");
String cityName = content.substring(pos + 1);
respContent = dao.findTelCodeByCityName(cityName);
System.out.println("区号:respContent:" + respContent);
}
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){
respContent = "您发送的是图片消息";
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){
respContent = "您发送的是语音消息";
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)){
respContent = "您发送的是视频消息";
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)){
respContent = "您发送的是地理位置消息";
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)){
respContent = "您发送的是链接消息";
}else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){
//事件类型
String eventType = requestMap.get("Event");
if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
respContent = "感谢您关注【王天泽的服务号】\n" + "微信号:wangtianze1\n" + "请回复序号:\n" + "1.查邮政编码\n" + "2.查电话区号\n" + "?.返回帮助菜单\n";
}else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
//TODO 取消订阅后用户不会再收到公众号发送的消息,因此不需要回复
}else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){
//TODO 处理扫描带参数二维码事件
}else if(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)){
//TODO 处理上报地理位置事件
}else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
//TODO 处理菜单点击事件
}
}
//设置文本消息的内容
textMessage.setContent(respContent);
//将文本消息对象转换成xml
respXml = MessageUtil.messageToXml(textMessage);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return respXml;
}
}

第六步:找到包com.wtz.service,修改LoginServlet.java类,修改doPost方法

 package com.wtz.service;

 import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import com.wtz.aes.AesException;
import com.wtz.aes.WXBizMsgCrypt;
import com.wtz.util.MessageUtil;
import com.wtz.util.Parameter;
import com.wtz.util.ProcessService;
import com.wtz.util.ValidationUtil; /**
* @author wangtianze QQ:864620012
* @date 2017年4月17日 下午8:11:32
* <p>version:1.0</p>
* <p>description:微信请求验证类</p>
*/
public class LoginServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("get请求。。。。。。"); //1.获得微信签名的加密字符串
String signature = request.getParameter("signature"); //2.获得时间戳信息
String timestamp = request.getParameter("timestamp"); //3.获得随机数
String nonce = request.getParameter("nonce"); //4.获得随机字符串
String echostr = request.getParameter("echostr"); System.out.println("获得微信签名的加密字符串:"+signature);
System.out.println("获得时间戳信息:"+timestamp);
System.out.println("获得随机数:"+nonce);
System.out.println("获得随机字符串:"+echostr); PrintWriter out = response.getWriter(); //验证请求确认成功原样返回echostr参数内容,则接入生效,成为开发者成功,否则失败
if(ValidationUtil.checkSignature(signature, timestamp, nonce)){
out.print(echostr);
} out.close();
out = null;
} /**
* 接受微信服务器发过来的XML数据包(通过post请求发送过来的)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//将请求响应的编码均设置为UTF-8,防止中文乱码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8"); //------------------------老的,不加密----------------------------
// //获取微信加密的签名字符串
// String signature = request.getParameter("signature");
//
// //获取时间戳
// String timestamp = request.getParameter("timestamp");
//
// //获取随机数
// String nonce = request.getParameter("nonce");
//
// PrintWriter out = response.getWriter();
//
// if(ValidationUtil.checkSignature(signature,timestamp,nonce)){
// String respXml = "";
// try {
// respXml = ProcessService.dealRequest(request);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// out.print(respXml);
// }
// out.close();
// out = null;
//---------------------------新的,加密---------------------------
//获取微信加密的签名字符串
String signature = request.getParameter("msg_signature"); //获取时间戳
String timestamp = request.getParameter("timestamp"); //获取随机数
String nonce = request.getParameter("nonce"); //从请求中读取整个post数据
InputStream inputStream = request.getInputStream(); //commons.io.jar方法,直接将流转成字符串
String Post = IOUtils.toString(inputStream,"UTF-8"); System.out.println("Post:" + Post); String Msg = "";
WXBizMsgCrypt wxcpt = null;
try {
wxcpt = new WXBizMsgCrypt(Parameter.token,Parameter.encodingAESKey,Parameter.corpId);
//解密消息
Msg = wxcpt.decryptMsg(signature,timestamp,nonce,Post);
} catch (AesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Msg打印结果
System.out.println("Msg打印结果:" + Msg); //调用核心业务类接收消息,处理消息
String respMessage = ProcessService.dealRequest(Msg); //respMessage打印结果
System.out.println("respMessage打印结果:" + respMessage); String encryptMsg = "";
try {
//加密回复消息
encryptMsg = wxcpt.encryptMsg(respMessage, timestamp, nonce);
System.out.println("encryptMsg:" + encryptMsg);
} catch (AesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //响应消息
PrintWriter out = response.getWriter();
out.print(encryptMsg);
out.close();
}
}

消息加密完成。

Java微信二次开发(五)的更多相关文章

  1. Java微信二次开发(一)

    准备用Java做一个微信二次开发项目,把流程写在这里吧. 第一天,做微信请求验证 需要导入库:servlet-api.jar 第一步:新建包com.wtz.service,新建类LoginServle ...

  2. Java微信二次开发(七)

    自定义菜单 第一步:新建包com.wtz.menu,新建类Button.java package com.wtz.menu; /** * @author wangtianze QQ:864620012 ...

  3. Java微信公众平台开发(五)--文本及图文消息回复的实现

    转自:http://www.cuiyongzhi.com/post/43.html 上篇我们说到回复消息可以根据是否需要上传文件到微信服务器可划分为[普通消息]和[多媒体消息],这里我们来讲述普通消息 ...

  4. Java微信二次开发(十)

    生成带参数的二维码以及长链接转短链接 第一步:找到包com.wtz.vo,新建类WeixinQRCode.java package com.wtz.vo; /** * @author wangtian ...

  5. Java微信二次开发(八)

    高级接口,先做了两个(获取用户信息和获取关注者列表) 第一步:找到包com.wtz.vo,新建类UserInfo.java package com.wtz.vo; /** * @author wang ...

  6. Java微信二次开发(六)

    Token定时获取 需要导入库:添加log4j(slf4j-api-1.5.10.jar,slf4j-log4j12-1.5.10.jar,log4j-1.2.15.jar,并且在src下添加log4 ...

  7. Java微信二次开发(三)

    各种类型消息的封装 第一步:找到com.wtz.message.response包,新建类Image.java package com.wtz.message.response; /** * @aut ...

  8. Java微信二次开发(二)

    第二天,做微信文本消息接口请求与发送 需要导入库:dom4j-1.6.1.jar,xstream-1.3.1.jar 第一步:新建包com.wtz.message.response,新建类BaseMe ...

  9. Java微信二次开发(九)

    多媒体文件上传与下载 第一步:找到包com.wtz.vo,新建类WeixinMedia.java package com.wtz.vo; /** * @author wangtianze QQ:864 ...

随机推荐

  1. docker容器启动设置固定IP

    docker安装以后的网络类型 [root@insure updev]# docker network ls NETWORK ID NAME DRIVER SCOPE 14da40175b01 bri ...

  2. 20175105 2018-2019-2 《Java程序设计》第八周学习总结

    20175105 2018-2019-2 <Java程序设计>第八周学习总结 教材学习内容总结 第十五章主要内容有:泛型.链表.堆栈.散列映射.树集以及树映射. 泛型:可以使用class名 ...

  3. docker[caffe&&pycaffe]

    0 引言 今天花了一天,完成了整个caffe的dockerfile编写,其支持python3.6.6,这里主要的注意点是protobuf的版本(在3.6.0之后,只支持c11),还有在制作镜像的时候注 ...

  4. Hive 表分区

    Hive表的分区就是一个目录,分区字段不和表的字段重复 创建分区表: create table tb_partition(id string, name string) PARTITIONED BY ...

  5. China Intelligent Office Summit(2018.11.21)

    时间:2018.11.21地点:中关村软件园国际会议中心

  6. Python高级特性(切片,迭代,列表生成式,生成器,迭代器)

    掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n = 1 while n ...

  7. Xamarin开发的一个简单画图程序分享

    最近Xamarin比较火,于是稍微看了下,感觉接触过MVC的都应该能很快上手,还挺有意思,于是忍不住写了个简单的画图程序,之前看帖子有人说装不上或者无法部署,估计我比较幸运,编译完了一次就安装成功了, ...

  8. Redis常用操作-------List(列表)

    1.BLPOP key [key ...] timeout BLPOP 是列表的阻塞式(blocking)弹出原语. 它是 LPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被  ...

  9. 北航学堂Android客户端Beta阶段发布说明

    在从学姐那里拿到服务接口的代码最终连通服务器之后,经过我们团队的努力,终于把前后端融合生成了我们目前的版本, 因为我们在Alpha阶段网络连接部分是一直没有搞定的,所以这个版本其实并不算是真正的Bet ...

  10. Linux 第七章学习笔记

    1:链接概述 链接(linking)是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或被拷贝)到存储并执行. 编译系统提供的调用预处理器.编译器.汇编器和链接器来构造目标 ...