前言:以前的我,很喜欢写东西,写一写所想所见所闻所感,但是工作之后,总不能写出让自己满意的文章,突发奇想,能否利用写博客的时机,将其写成类似散文似的博文呢?哈哈...

邮件功能尝试:作为一个小菜鸟,对于技术性的东西却有特殊的偏好,每每通过自己学习而获得新的知识,总会如孩童拥有一个新奇的玩意儿一样,欢欣雀跃。第一次写邮件功能,这一篇文章就是记录下,我在参考网上前辈的博文敲代码时遇到的情况,代码大部分都是参考的网上的博文,感谢!我尽量写的详细,以备后用和帮助后来者。

言归正传:

1.环境及工具:myeclipse 9.0 ; jdk7 ;

2.项目截图:

3.jar备注:需要的jar包如上图所示,javamail-1[1].4.2.zip ; jaf-1_1_1.zip ;dom4j-1.6.1.jar ;jaxen-1.1.6.jar ,可以在网上自己下载

4.代码示例:主要参考网上的博文 ,地址:http://www.cnblogs.com/java-pan/archive/2012/03/06/javamail.html

4.1定义邮件发送所需要的字段:

 package com.email.emailtest;

 /**
* 定义发送邮件的所有字段的javabean
*
* @author Administrator
*
*/
public class MailInfo {
private String host;// 邮件服务器域名或IP
private String from;// 发件人
private String to;// 收件人
private String cc;// 抄送人
private String username;// 发件人用户名
private String password;// 发件人密码
private String title;// 邮件的主题
private String content;// 邮件的内容 public String getHost() {
return host;
} public void setHost(String host) {
this.host = host;
} public String getFrom() {
return from;
} public void setFrom(String from) {
this.from = from;
} public String getTo() {
return to;
} public void setTo(String to) {
this.to = to;
} public String getCc() {
return cc;
} public void setCc(String cc) {
this.cc = cc;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
}
}

4.2对密码进行加解密

 package com.email.emailtest;

 /**
* 对密码进行加密和解密
*
* @author Administrator
*
*/
public class Encrypt { public static final int pass1 = 10;
public static final int pass2 = 1; public Encrypt() {
} /**
* @Title: DoEncrypt
* @Description: 对密码进行加密的方法
* @param @param str
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String DoEncrypt(String str) {
StringBuffer enStrBuff = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
int tmpch = str.charAt(i);
tmpch ^= 1;
tmpch ^= 0xa;
enStrBuff.append(Integer.toHexString(tmpch));
} return enStrBuff.toString().toUpperCase();
} /**
* @Title: DoDecrypt
* @Description: 对密码进行解密的方法
* @param @param str
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String DoDecrypt(String str) {
String deStr = str.toLowerCase();
StringBuffer deStrBuff = new StringBuffer();
for (int i = 0; i < deStr.length(); i += 2) {
String subStr = deStr.substring(i, i + 2);
int tmpch = Integer.parseInt(subStr, 16);
tmpch ^= 1;
tmpch ^= 0xa;
deStrBuff.append((char) tmpch);
} return deStrBuff.toString();
} public static void main(String args[]) {
String source = "123456";
String s = DoEncrypt(source);
System.out.println("de=" + s); source = DoDecrypt(s);
System.out.println("en=" + source); } }

4.3邮件授权类

 package com.email.emailtest;

 import javax.mail.PasswordAuthentication;

 /**
* 邮件授权类
*
* @author Administrator
*
*/
public class MyAuthenticator extends javax.mail.Authenticator { private String strUser;
private String strPwd; public MyAuthenticator(String user, String password) {
this.strUser = user;
this.strPwd = password;
} protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(strUser, strPwd);
}
}

4.4邮件发送

 package com.email.emailtest;

 import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Properties;
import java.util.logging.Logger; import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element; import com.email.utils.LogManager; /**
* 发送邮件
*
* @author Administrator
*
*/
public class SendMail {
private static final Logger log = LogManager.getLogger(SendMail.class);
// 配置文件xml的路径
private final static String XML_PATH = "src" + File.separator
+ "com\\email\\emailtest" + File.separator + "SendMail.xml"; // private final static String XML_PATH =
// "src\\com\\email\\emailtest\\SendMail.xml"; // xml文件中字段对应的javabean对象
private static MailInfo mailInfo = new MailInfo(); /**
* <p>
* Title: readXML
* </p>
* <p>
* Description:读取xml文件,把文件内容以字符串形式输出
* </p>
*
* @param xmlPath
* 配置文件的路径
* @return
* @throws Exception
*/
private String readXML(String xmlPath) throws Exception {
log.info("----xmlPath----" + xmlPath); String fileContent = "";
File file = new File(xmlPath);
if (file.isFile() && file.exists()) {
try {
InputStreamReader read = new InputStreamReader(
new FileInputStream(file), "UTF-8");
BufferedReader reader = new BufferedReader(read);
String line;
try {
while ((line = reader.readLine()) != null) {
fileContent += line;
}
reader.close();
read.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
throw new Exception("config目录下的配置文件SendMail.xml不存在,请检查");
}
log.info("xml=" + fileContent);
return fileContent;
} /**
* <p>
* Title: parseXML
* </p>
* <p>
* Description:发送邮件给指定的收件人和抄送人,同时进行一些简单的校验判断,如必填项的字段、type的值
* </p>
*
* @param xml
* 配置文件的内容
* @param type
* 邮件类型
*/
private void parseXML(String xml, String type) { type = type.toLowerCase();// 忽略type字段的大小写
log.info("===========类型:"+type);
try {
// 解析XML,获得doc对象
Document doc = DocumentHelper.parseText(xml); // 判断type的值是否正确,type的值应是报文二级节点中的一个
String flag = doc.getRootElement().element(type) + "";
if (null == flag || flag.equals("null"))
throw new DocumentException(
"传入的type值不对,type的值应是SendMail.xml报文中二级节点的一个,请查看文件然后重新传入type的值"); // 设置主机名称
Element hostEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/host");
if (null == hostEle || "".equals(hostEle.getTextTrim())) {
throw new DocumentException(
"邮件服务器域名或IP不能为空,请检查配置文件SendMail.xml");
}
mailInfo.setHost(hostEle == null ? "" : hostEle.getTextTrim());
log.info("=======mailInfo.getHost():"+mailInfo.getHost());
// 设置发件人
Element fromEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/from");
if (null == fromEle || "".equals(fromEle.getTextTrim())) {
throw new DocumentException("发件人地址不能为空,请检查配置文件SendMail.xml");
}
mailInfo.setFrom(fromEle == null ? "" : fromEle.getTextTrim()); // 设置邮件主题
Element titleEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/title");
mailInfo.setTitle(titleEle == null ? "" : titleEle.getTextTrim()); // 设置收件人,对多个收件人的处理放在后面
Element toEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/to");
if (null == toEle || "".equals(toEle.getTextTrim())) {
throw new DocumentException("收件人地址不能为空,请检查配置文件SendMail.xml");
}
mailInfo.setTo(toEle == null ? "" : toEle.getTextTrim()); // 设置抄送,对多个抄送人的处理放在后面
Element ccEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/cc");
mailInfo.setCc(ccEle == null ? "" : ccEle.getTextTrim()); // 设置发件人用户名
Element nameEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/username");
if (null == nameEle || "".equals(nameEle.getTextTrim())) {
throw new DocumentException("发件人用户名不能为空,请检查配置文件SendMail.xml");
}
mailInfo.setUsername(nameEle == null ? "" : nameEle.getTextTrim()); // 设置发件人密码
Element passEle = (Element) doc.selectSingleNode("/mail/" + type
+ "/password");
if (null == passEle || "".equals(passEle.getTextTrim())) {
throw new DocumentException("发件人密码不能为空,请检查配置文件SendMail.xml");
}
mailInfo.setPassword(passEle == null ? "" : passEle.getTextTrim()); } catch (DocumentException e) {
e.printStackTrace();
}
} /**
* <p>
* Title: sendMailOfValidate
* </p>
* <p>
* Description:发送邮件的方法,Authenticator类验证
* </p>
*/
private void sendMailOfValidate() {
Properties props = System.getProperties();
props.put("mail.smtp.host", mailInfo.getHost());// 设置邮件服务器的域名或IP
props.put("mail.smtp.auth", "true");// 授权邮件,mail.smtp.auth必须设置为true //---------安全
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
props.put("mail.smtp.socketFactory.fallback", "false");
props.put("mail.smtp.starttls.enable", "true"); String password = mailInfo.getPassword();// 密码
try {
password = Encrypt.DoDecrypt(password);// 如果密码经过加密用此方法对密码进行解密
} catch (NumberFormatException e1) {
// 如果密码未经过加密,则对密码不做任何处理
}
// 传入发件人的用户名和密码,构造MyAuthenticator对象
MyAuthenticator myauth = new MyAuthenticator(mailInfo.getUsername(),
password); // 传入props、myauth对象,构造邮件授权的session对象
Session session = Session.getDefaultInstance(props, myauth); // 将Session对象作为MimeMessage构造方法的参数传入构造message对象
Message message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(mailInfo.getFrom()));// 发件人 // 对多个收件人的情况进行处理,配置文件SendMail.xml中每个收件人之间必须用逗号隔开的
if (mailInfo.getTo() != null && !"".equals(mailInfo.getTo())) {
String to[] = mailInfo.getTo().split(",");
// for (int i = 0; i < to.length; i++) {
// message.addRecipient(Message.RecipientType.TO,
// new InternetAddress(to[i]));// 收件人
// }
for(String too : to){
message.addRecipient(Message.RecipientType.TO, new InternetAddress(too)); } } // 对多个抄送人的情况进行处理,每个抄送人之间用逗号隔开的
if (mailInfo.getCc() != null && !"".equals(mailInfo.getCc())) {
String cc[] = mailInfo.getCc().split(",");
for (int j = 0; j < cc.length; j++) {
message.addRecipient(Message.RecipientType.CC,
new InternetAddress(cc[j]));// 抄送
}
}
message.setSubject(mailInfo.getTitle());// 主题 message.setText(mailInfo.getContent());// 内容 Transport.send(message);// 调用发送邮件的方法 log.info("邮件发送成功");
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
} /**
* Title: sendMail Description:外部程序调用的入口
*
* @param type 邮件的类型
* ,目前有三种,即logmessage、checkmessage、ordermessage,
* type只能传这三个值中一个,传其他的任何值都不行
* @param content邮件的内容
* @throws Exception
*/
public void sendMail(String type, String content) throws Exception {
log.info("入参type=" + type);
log.info("入参content=" + content);
if (null == type || "".equals(type) || null == content
|| "".equals(content)) {
throw new Exception("方法的入参type和content字段的值都不能为空或null");
} String xml = readXML(XML_PATH);// 获得xml字符串 parseXML(xml, type);// 解析xml字符串,把对应字段的值放入到mailInfo对象中 mailInfo.setContent(content);// 设置发送的内容 sendMailOfValidate();// 发送邮件 } /**
* 为了方便直接用main方法测试
*
* @param args
* @throws Exception
*/
public static void main(String args[]) throws Exception { SendMail mail = new SendMail(); // type类型,根据此字段去配置文件SendMail.xml中匹配,然后发到相应的邮箱
String type = "logmessage"; // 邮件的内容,实际开发中这个内容是前台传到后台
String content = "你好,欢迎使用JavaMail包开发邮件功能。fuck,终于成功了.."; // 在其他类中调用时只能看到sendMail方法,为了保护内部细节,其它的方法都声明为私有的
mail.sendMail(type, content);
// 这个项目中没有日志文件,所以我打印一句话来告诉自己程序已经成功运行
log.info("----邮件发送成功----"); } }

4.5日志记录类

 package com.email.utils;

 import java.util.logging.Logger;

 public class LogManager {
/**
* 获取日志对象
*
* @param clazz
*
*/
public static Logger getLogger(Class clazz) {
Logger logger = Logger.getLogger(clazz.getName());
return logger;
}
}

4.6xml文件,可以配置邮件发送的一些信息,代码中会解析这个xml文件。但是我自己的考虑是,如果是一个正常的邮件系统,可以用户在客户端进行填写,然后读取到代码中,包括收件人,抄送人等等信息。自己理解,欢迎指正!

<?xml version="1.0" encoding="UTF-8"?>
<mail>
<logmessage><!--报文的二级节点,为了使传入的type值对大小写不限制,故此处必须用小写 -->
<host>smtp.qq.com</host><!-- 邮件服务器域名或IP,必填项 smtp.exmail.qq.com smtp.qq.com smtp.163.com -->
<from>12345@qq.com</from><!-- 发件人 ,必填项 -->
<to>123@qq.com,456@qq.com,789@qq.com,1245@163.com</to><!-- 收件人,多个收件人之间用英文状态下的逗号隔开,必填项 -->
<cc>@qq.com</cc><!-- 抄送,多个抄送人之间用英文状态下的逗号隔开-->
<title>Test JavaMail 001</title><!-- 邮件主题-->
<username>12345@qq.com</username><!-- 发件人邮箱的用户名,即email的全地址,必填项 -->
<password>mima</password><!-- 发件人邮箱的密码,像QQ邮箱如果设置了独立密码应输入独立密码,必填项,为了安全起见填写密码之前最好用Encrypt类的DoEncrypt方法加密 -->
</logmessage>
<checkmessage>
<host></host>
<from></from>
<to></to>
<cc></cc>
<title></title>
<username></username>
<password></password>
</checkmessage> <ordermessage>
<host></host>
<from></from>
<to></to>
<cc></cc>
<title></title>
<username></username>
<password></password>
</ordermessage>
</mail>

5.遇到的问题及解决方案:

先以163邮箱为例讲解:

为了方便起见,代码的测试时直接使用main()进行的,如果你按照上面的代码和xml配置,都准备完成后,直接执行main()方法,可能会有以下错误:

5.1: 550 User has no permission

这时你需要将你的163邮箱开启pop3\smtp\imap等服务,如图在163邮箱的设置中,在POP3/..处设置开启服务,设置完成后,163会强制你设置 ‘客户端授权密码’,这也是为了安全考虑。然后在程序的xml文件配置时候,这个邮箱的密码就是你设置的 ‘客户端授权密码’ 。

5.2 : javax.mail.AuthenticationFailedException: 535 Error: authentication failed   这里你需要检查你的账户密码是否正确,尤其是你设置的‘客户端授权码’,这个要代替你原先的邮箱密码。

5.3: :javax.mail.AuthenticationFailedException: 530 Error: A secure connection is requiered(such as ssl). More information at http://service.mail.qq.com/cgi-bin/help?id=28

这个问题是在qq邮箱中测试出来的。我在网上找了不少的资料看,包括设置邮箱的host,都是不可以的。最后在代码中增加了安全的认证,就ok了。代码中已添加,可以测试。

同样,使用qq邮箱时候,也需要在设置pop3\smtp\imap等服务,这个是在设置-->账户-->然后你就能刚看到了,同样开启哪一个服务,tx也会提供你一个客户端授权码,这个不同于网易的需要你自己设置,你需要记住系统提供你的,在使用客户端收发邮件时候,以其代替密码使用,就ok了。

5.4其他人总结的问题:

 java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
at javax.mail.Session.loadProvidersFromStream(Session.java:928)
at javax.mail.Session.access$000(Session.java:174)
at javax.mail.Session$1.load(Session.java:870)
at javax.mail.Session.loadResource(Session.java:1084)
at javax.mail.Session.loadProviders(Session.java:889)
at javax.mail.Session.<init>(Session.java:210)
at javax.mail.Session.getDefaultInstance(Session.java:299)
at mail.SendMail.sendMail(SendMail.java:31)
at mail.SendMail.main(SendMail.java:50)
Exception in thread "main"
解决方案:在myeclipse的安装目录下搜索javaee.jar,然后用压缩软件打开,删除javax下的mail文件夹 java.lang.NoClassDefFoundError: com/sun/activation/registries/LogSupport
at javax.activation.MailcapCommandMap.<init>(MailcapCommandMap.java:140)
at javax.activation.CommandMap.getDefaultCommandMap(CommandMap.java:61)
at javax.activation.DataHandler.getCommandMap(DataHandler.java:153)
at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:611)
at javax.activation.DataHandler.writeTo(DataHandler.java:315)
at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:264)
at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1299)
at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2071)
at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2039)
at javax.mail.Transport.send(Transport.java:119)
at mail.SendMail.sendMailNoValidate(SendMail.java:48)
at mail.SendMail.main(SendMail.java:96)
Exception in thread "main"
解决方案:在myeclipse的安装目录下搜索javaee.jar,然后用压缩软件打开,删除javax文件夹下的activation文件夹 javax.mail.SendFailedException: Sending failed;
nested exception is:
javax.mail.MessagingException: 503 Error: need EHLO and AUTH first ! at javax.mail.Transport.send0(Transport.java:219)
at javax.mail.Transport.send(Transport.java:81)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMailNoValidate(SendMailServiceImpl.java:210)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMail(SendMailServiceImpl.java:243)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.main(SendMailServiceImpl.java:261)
解决方案:props.put("mail.smtp.auth", "true"); javax.mail.SendFailedException: Sending failed;
nested exception is:
javax.mail.AuthenticationFailedException
at javax.mail.Transport.send0(Transport.java:219)
at javax.mail.Transport.send(Transport.java:81)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMailNoValidate(SendMailServiceImpl.java:211)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.sendMail(SendMailServiceImpl.java:244)
at com.asiainfo.bboss.sendmail.SendMailServiceImpl.main(SendMailServiceImpl.java:262)
解决方案: MyAuthenticator myauth = new MyAuthenticator(mailInfo.getUsername(),password);

6.其他

demo能跑起来,现在考虑:1.整合成一个简单的邮箱客户端,能够发送邮件;

             2.增加邮件功能的其他功能项,包括附件,收发功能,增加数据库,登陆页面等等;

             3.参考博文地址: http://www.cnblogs.com/java-pan/archive/2012/03/06/javamail.html

                      http://www.jspcn.net/htmlnews/1150019680500144.html 

             4.欢迎加群:413066190 ,交流。

             5.路漫漫其修远兮,吾将上下而求索!   

Java: JavaMail 初试(一)的更多相关文章

  1. [Java] JavaMail 发送带图片的 html 格式的邮件

    JavaMail 发送的邮件正文和附件是相互独立的,但是内置图片需要定位图片在正文中的位置,所以内置图片和邮件正文是互相依赖的. 发送带附件的邮件可参考JavaMail 发送 html 格式.带附件的 ...

  2. [Java] JavaMail 发送 html 格式、带附件的邮件

    本案例演示发送 html 格式,可带附件的邮件发送.发送纯文本邮件的例子可参照上一篇博文JavaMail 简单案例. EmailHelper, Email 的帮助类,向帮助类提供 SMTP 服务器域名 ...

  3. [Java] JavaMail 简单案例

    网易提供了免费的 SMTP / POP3服务,可用于编程测试,详情见 什么是POP3.SMTP和IMAP? 只需要拥有一个网易邮箱账号,并开启该账号的 SMTP / POP3 功能,便可以通过程序发送 ...

  4. [Java] JavaMail 查询邮件

    上两篇提到如何发送邮件:JavaMail 发送 html 格式.带附件的邮件, JavaMail 简单案例.本文再演示下,如何读取邮箱上的邮件. 邮件内容的数据格式种类比较多,用户直接阅读邮件比较常见 ...

  5. Java - JavaMail - 利用 JavaMail 发邮件的 小demo

    1. 概述 面试的时候, 被问到一些乱七八糟的运维知识 虽然我不是干运维的, 但是最后却告诉我专业知识深度不够, 感觉很难受 又回到了一个烦人的问题 工作没有深度的情况下, 你该如何的提升自己, 并且 ...

  6. 武汉中科通达软件Java工程师初试总结复盘

       预约的视频面试时间是中午12点,不过面试官并没有准时到,拖了大概5.6分钟吧.Zoom会议上写着xxxJava工程师初试. 面试官戴着口罩,并没有露脸,看起来与我年龄相仿,感觉很年轻. 在我按着 ...

  7. Java JavaMail通过SMPT发送邮件

    概述 本讲讲述如何使用JavaMail工具包,通过SMPT协议,在Java代码中发送邮件. 一.JavaMail简介 JavaMail API提供了一个独立于平台且与协议无关的框架来构建邮件和消息传递 ...

  8. 桂林理工大学第十届java程序设计初试竞赛试题

    原创 三.程序设计题(不得改变已经给出的部分,允许添加新的辅助函数或类)(共36分) (6分)1.以下函数的功能是判断一个正整数是否为质数,若是返回true,否则返回false.其中参数data为要判 ...

  9. java中使用javamail发送邮件

    1. 电子邮件协议 电子邮件的在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括 SMTP,POP3,IMAP. 其中邮件的创建和发送只需要用到 SMTP协议,所有本文也只会涉及到SMT ...

随机推荐

  1. selenium之 文件上传方法

    文件上传是所有UI自动化测试都要面对的一个头疼问题 首先,我们要区分出上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js.flash等实现,标签非input 我们分别 ...

  2. bluedroid源代码分析之ACL包发送和接收(一)

    很多其它内容请參照我的个人网站: http://stackvoid.com/ ACL 链路在 Bluetooth 中很重要,一些重要的应用如 A2DP, 基于 RFCOMM 的应用,BNEP等都要建立 ...

  3. CareerCup之1.6 Rotate Image

    [题目] 原文: 1.6 Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, ...

  4. android开发——自己定义相机(Camera)开发总结

    近期这段时间我一直在开发自己定义相机.谷歌了些网上的demo.发现有非常多各种各样的问题.终于还是从API的camera类開始学习,进行改进. 以下对之前的实现进行一些总结. 官方camera API ...

  5. Windows8-x64 VMWare安装Linux CentOS6-x64

    本文參考了:http://www.cnblogs.com/seesea125/archive/2012/02/25/2368255.html 其内容相当具体,以至于我还没依照其步骤做完.系统就已经安装 ...

  6. UML类图组成

    本文转载至 http://blog.csdn.net/fengsh998/article/details/8105666     UML类图的相关知识,UML类图(Classdiagram)是最常用的 ...

  7. Asynchronous programming with async and await (C#)

    Asynchronous Programming with async and await (C#) | Microsoft Docs https://docs.microsoft.com/en-us ...

  8. Möbius strip

    en.wikipedia.org/wiki/Möbius_strip http://mechproto.olin.edu/final_projects/average_jo.html Fabricat ...

  9. HDU 2444 The Accomodation of Students (二分图最大匹配+二分图染色)

    [题目链接]:pid=2444">click here~~ [题目大意]: 给出N个人和M对关系,表示a和b认识,把N个人分成两组,同组间随意俩人互不认识.若不能分成两组输出No,否则 ...

  10. Decorator Pattern

    1.Decorator 模式通过组合的方式提供了一种给类增加职责(操作)的方法. 2.Decorator模式结构图 3.实现 #ifndef _DECORATOR_H_ #define _DECORA ...