一、背景

  最近朋友的公司有用到这个功能,之前对这一块也不是很熟悉,就和他一起解决出现的异常的同时,也初窥一下使用Apache Common Email组件进行邮件发送。

二、Java发送邮件的注意事项

  1.不同的邮箱有不同的支持协议,比如有些只支持SSL协议,有些只支持TLS协议,还有些同时支持SSL和TLS协议。

  2.支持不同协议的邮箱,在使用Java发送邮件时要使用不同的方式发送,下面我会介绍基于SSL和TLS的两种实现方式。

  附:常用邮箱的服务器(Smtp/POP3)地址和端口总结

三、代码实现

说明:本例采用Apache Common Email组件进行开发。

1.发送邮件实体类

  1. package com.hafiz.zhang.mail.entity;
  2.  
  3. import java.io.Serializable;
  4. import java.util.List;
  5.  
  6. import org.apache.commons.mail.EmailAttachment;
  7.  
  8. /**
  9. * @author hafiz.Zhang
  10. * @Date 2016年5月23日 下午2:40:36
  11. * @Description 邮件实体类
  12. */
  13. public class MailEntity implements Serializable{
  14. private static final long serialVersionUID = 1589570366044890462L;
  15. public static final String ENCODING = "UTF-8"; //邮件编码
  16. private String host;  //服务器地址
  17. private String port; //发送端口
  18. private String sender; //发件人邮箱
  19. private List<String> receiver; //收件人邮箱
  20. private List<String> copier; //抄送人
  21. private String senderName; //发件人昵称
  22. private String userName; //发件邮箱账号
  23. private String password; //发件邮箱密码
  24. private String subject; //邮件主题
  25. private String content; //邮件内容(支持HTML)
  26. private List<EmailAttachment> attachments; //邮件附件
  27. public String getHost() {
  28. return host;
  29. }
  30. public void setHost(String host) {
  31. this.host = host;
  32. }
  33. public String getPort() {
  34. return port;
  35. }
  36. public void setPort(String port) {
  37. this.port = port;
  38. }
  39. public String getSender() {
  40. return sender;
  41. }
  42. public void setSender(String sender) {
  43. this.sender = sender;
  44. }
  45. public List<String> getReceiver() {
  46. return receiver;
  47. }
  48. public void setReceiver(List<String> receiver) {
  49. this.receiver = receiver;
  50. }
  51. public List<String> getCopier() {
  52. return copier;
  53. }
  54. public void setCopier(List<String> copier) {
  55. this.copier = copier;
  56. }
  57. public String getSenderName() {
  58. return senderName;
  59. }
  60. public void setSenderName(String senderName) {
  61. this.senderName = senderName;
  62. }
  63. public String getUserName() {
  64. return userName;
  65. }
  66. public void setUserName(String userName) {
  67. this.userName = userName;
  68. }
  69. public String getPassword() {
  70. return password;
  71. }
  72. public void setPassword(String password) {
  73. this.password = password;
  74. }
  75. public String getSubject() {
  76. return subject;
  77. }
  78. public void setSubject(String subject) {
  79. this.subject = subject;
  80. }
  81. public String getContent() {
  82. return content;
  83. }
  84. public void setContent(String content) {
  85. this.content = content;
  86. }
  87. public List<EmailAttachment> getAttachments() {
  88. return attachments;
  89. }
  90. public void setAttachments(List<EmailAttachment> attachments) {
  91. this.attachments = attachments;
  92. }
  93. @Override
  94. public String toString() {
  95. return "MailEntity [host=" + host + ", port=" + port + ", sender=" + sender + ", receiver=" + receiver
  96. + ", copier=" + copier + ", senderName=" + senderName + ", userName=" + userName + ", password="
  97. + password + ", subject=" + subject + ", content=" + content + ", attachments=" + attachments + "]";
  98. }
  99. }

注:实体类代码比较臃肿,建议使用lombok进行简化,lombok的使用方式见我的另一篇博客:Java简化代码神器-Lombok

2.发送邮件支持协议列举类

  1. package com.hafiz.zhang.mail.tools.factory;
  2.  
  3. /**
  4. * @author hafiz.Zhang
  5. * @Date 2016年5月25日 下午12:08:59
  6. * @Description 列举发送邮件的可用协议
  7. */
  8. public class Protocols {
  9. //SSL协议
  10. public static String SSL_MAIL_UTIL = "com.hafiz.zhang.mail.tools.SSLMailUtil";
  11. //TLS协议
  12. public static String TLS_MAIL_UTIL = "com.hafiz.zhang.mail.tools.TLSMailUtil";
  13. }

3.发送邮件工具接口类

  1. package com.hafiz.zhang.mail.tools;
  2.  
  3. import com.hafiz.zhang.mail.entity.MailEntity;
  4.  
  5. /**
  6. * @author hafiz.Zhang
  7. * @Date 2016年5月23日 下午3:26:15
  8. * @Description 邮件发送接口类
  9. */
  10. public interface IMailUtil {
  11. /**
  12. * @Author hafiz.Zhang
  13. * @Description: 发送邮件
  14. * @param mail要发送邮件的实体类
  15. * @return Boolean 发送结果
  16. */
  17. public abstract Boolean send(MailEntity mail);
  18. }

4.基于SSL协议发送邮件工具实现类

  1. package com.hafiz.zhang.mail.tools;
  2.  
  3. import java.util.List;
  4.  
  5. import org.apache.commons.mail.EmailAttachment;
  6. import org.apache.commons.mail.EmailException;
  7. import org.apache.commons.mail.HtmlEmail;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10.  
  11. import com.hafiz.zhang.mail.entity.MailEntity;
  12.  
  13. /**
  14. * @author hafiz.Zhang
  15. * @Date 2016年5月23日 下午3:09:13
  16. * @Description 通过SSL方式发送邮件工具类
  17. */
  18. public class SSLMailUtil implements IMailUtil{
  19. private static Logger log = LoggerFactory.getLogger(SSLMailUtil.class);
  20.  
  21. public Boolean send(MailEntity mail) {
  22. // 创建待发送的emil对象
  23. HtmlEmail email = new HtmlEmail();
  24. try {
  25.  
  26. // 设置SMTP发送服务器的名字:163的如下:"smtp.163.com"
  27. email.setHostName(mail.getHost());
  28. //设置端口号
  29. if(null != mail.getPort()) {
  30. email.setSmtpPort(Integer.parseInt(mail.getPort()));
  31. }
  32. // 设置邮件字符编码集
  33. email.setCharset(MailEntity.ENCODING);
  34. // 设置抄送人
  35. email.addCc(mail.getCopier().toArray(new String[mail.getCopier().size()]));
  36. // 设置发送人的邮箱
  37. email.setFrom(mail.getSender(), mail.getSenderName());
  38. // 收件人的邮箱
  39. email.addTo(mail.getReceiver().toArray(new String[mail.getReceiver().size()]));
  40. // 如果需要认证信息的话,设置认证:用户名-密码。分别为发件人在邮件服务器上的注册名称和密码
  41. email.setAuthentication(mail.getUserName(), mail.getPassword());
  42. // 设置要发送的邮件主题
  43. email.setSubject(mail.getSubject());
  44. // 设置要发送的信息,由于使用了HtmlEmail,可以在邮件内容中使用HTML标签
  45. email.setMsg(mail.getContent());
  46. // 设置附件
  47. List<EmailAttachment> attachments = mail.getAttachments();
  48. if(null != attachments && attachments.size() > 0) {
  49. for(EmailAttachment attachment : attachments) {
  50. email.attach(attachment);
  51. }
  52. }
  53. // 发送
  54. email.send();
  55.  
  56. log.info(mail.getSender() + " 发送邮箱到 " + mail.getReceiver());
  57.  
  58. return true;
  59. } catch (EmailException e) {
  60. log.error(mail.getSender() + " 发送邮箱到 " + mail.getReceiver() + " 失败,错误原因:" + e.getMessage());
  61. e.printStackTrace();
  62. }
  63. return false;
  64. }
  65. }

5.基于TLS协议的发送邮件实现类

  1. package com.hafiz.zhang.mail.tools;
  2.  
  3. import java.util.List;
  4. import java.util.Properties;
  5.  
  6. import javax.mail.Session;
  7.  
  8. import org.apache.commons.mail.DefaultAuthenticator;
  9. import org.apache.commons.mail.EmailAttachment;
  10. import org.apache.commons.mail.EmailException;
  11. import org.apache.commons.mail.HtmlEmail;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14.  
  15. import com.hafiz.zhang.mail.entity.MailEntity;
  16.  
  17. /**
  18. * @author hafiz.Zhang
  19. * @Date 2016年5月23日 下午3:23:15
  20. * @Description 通过TLS协议发送邮件工具类
  21. */
  22. public class TLSMailUtil implements IMailUtil{
  23. private static Logger log = LoggerFactory.getLogger(TLSMailUtil.class);
  24.  
  25. public Boolean send(MailEntity mail){
  26. HtmlEmail email = new HtmlEmail();
  27. try {
  28. Properties prop = new Properties();
  29. // 设置SMTP发送服务器的名字:163的如下:"smtp.163.com"
  30. prop.setProperty("mail.smtp.host", mail.getHost());
  31. // 设置SMTP发送服务器的端口
  32. prop.setProperty("mail.smtp.port", mail.getPort());
  33. // 设置是否需要认证
  34. prop.setProperty("mail.smtp.auth", "true");
  35. // 开启TLS加密方式
  36. prop.setProperty("mail.smtp.starttls.enable", "true");
  37. // 添加信任的服务器
  38. prop.setProperty("mail.smtp.ssl.trust", mail.getHost());
  39. // 进行认证并获取需要的session
  40. DefaultAuthenticator defaultAuthenticator =
  41. new DefaultAuthenticator(mail.getUserName(), mail.getPassword());
  42. Session session = Session.getInstance(prop,defaultAuthenticator);
  43. email.setMailSession(session);
  44. // 设置字符编码集
  45. email.setCharset(MailEntity.ENCODING);
  46. // 设置发送人的邮箱
  47. email.setFrom(mail.getSender(), mail.getSenderName());
  48. // 设置收件人的邮箱
  49. email.addTo(mail.getReceiver().toArray(new String[mail.getReceiver().size()]));
  50. // 设置抄送人
  51. email.addCc(mail.getCopier().toArray(new String[mail.getCopier().size()]));
  52. // 设置要发送的邮件主题
  53. email.setSubject(mail.getSubject());
  54. // 设置要发送的信息,由于使用了HtmlEmail,可以在邮件内容中使用HTML标签
  55. email.setMsg(mail.getContent());
  56. // 设置附件
  57. List<EmailAttachment> attachments = mail.getAttachments();
  58. if(null != attachments && attachments.size() > 0) {
  59. for(EmailAttachment attachment : attachments) {
  60. email.attach(attachment);
  61. }
  62. }
  63. // 发送
  64. email.send();
  65. log.info(mail.getSender() + " 发送邮箱到 " + mail.getReceiver());
  66. return true;
  67. } catch (EmailException e) {
  68. log.error(mail.getSender() + " 发送邮箱到 " + mail.getReceiver() + " 失败,错误原因:" + e.getMessage());
  69. e.printStackTrace();
  70. }
  71. return false;
  72. }
  73. }

注意:

  1.如果没有设置开启TLS加密方式的代码(上面代码中标红处),则会出现Caused by: com.sun.mail.smtp.SMTPSendFailedException: 530 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM异常,异常图片如下:

  2.如果没有设置添加信任的主机服务器的代码(上面代码中标红处),则会出现:Caused by: javax.mail.MessagingException: Could not convert socket to TLS;异常,异常图片如下:

6.获取邮件发送类的工厂类

  1. package com.hafiz.zhang.mail.tools.factory;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5.  
  6. import com.hafiz.zhang.mail.tools.IMailUtil;
  7.  
  8. /**
  9. * @author hafiz.Zhang
  10. * @Date 2016年5月23日 下午3:43:15
  11. * @Description 获取邮件发送类的工厂类
  12. */
  13. public class MailUtilsFactory {
  14. private static Logger logger = LoggerFactory.getLogger(MailUtilsFactory.class);
  15.  
  16. private MailUtilsFactory() {
  17. super();
  18. }
  19.  
  20. public static IMailUtil getMailUtil(String name) {
  21. IMailUtil mailUtil = null;
  22. try {
  23. mailUtil = (IMailUtil)Class.forName(name).newInstance();
  24. } catch (Exception e) {
  25. logger.error("获取邮件发送类失败,失败原因:" + e.getMessage());
  26. e.printStackTrace();
  27. }
  28. return mailUtil;
  29. }
  30. }

7.测试类

  1. package com.hafiz.zhang.mail.test;
  2.  
  3. import java.net.MalformedURLException;
  4. import java.net.URL;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7.  
  8. import org.apache.commons.mail.Email;
  9. import org.apache.commons.mail.EmailAttachment;
  10.  
  11. import com.hafiz.zhang.mail.entity.MailEntity;
  12. import com.hafiz.zhang.mail.tools.IMailUtil;
  13. import com.hafiz.zhang.mail.tools.factory.MailUtilsFactory;
  14. import com.hafiz.zhang.mail.tools.factory.Protocols;
  15.  
  16. /**
  17. * @author hafiz.Zhang
  18. * @Date 2016年5月23日 下午3:39:52
  19. * @Description 两种方式发送邮件的测试类
  20. */
  21. public class TestMailSender {
  22. public static void main(String[] args) throws MalformedURLException {
  23. MailEntity mail = new MailEntity();
  24. mail.setHost("smtp.163.com");
  25. mail.setSender("xxx@163.com");
  26. mail.setPort("25");
  27. mail.setUserName("xxx@163.com");
  28. mail.setPassword("xxxxx");
  29. //设置收件人
  30. List<String> receiver = new ArrayList<String>();
  31. receiver.add("xxx@qq.com");
  32.      //设置抄送人
  33. List<String> copier = new ArrayList<String>();
  34. copier.add("xxx@163.com");
  35.  
  36. List<EmailAttachment> attachments = new ArrayList<EmailAttachment>();
  37. // 添加本地附件
  38. EmailAttachment att = new EmailAttachment();
  39. att.setDescription("这是附件图片");
  40. att.setDisposition(EmailAttachment.ATTACHMENT);
  41. att.setName("好看的图片.png");
  42. att.setPath("C:\\Users\\ZHF\\Desktop\\333.png");
  43. attachments.add(att);
  44. // 添加网络附件
  45. EmailAttachment att2 = new EmailAttachment();
  46. att2.setDescription("这是网络附件");
  47. att2.setDisposition(EmailAttachment.ATTACHMENT);
  48. att2.setName("网络附件.jpg");
  49. att2.setURL(new URL("http://7xpsw5.com1.z0.glb.clouddn.com/41a9ccf2-2a22-44bd-aa3b-8e8779db1caf.jpg"));
  50. attachments.add(att2);
  51.  
  52. mail.setAttachments(attachments);
  53. mail.setCopier(copier);
  54. mail.setReceiver(receiver);
  55. mail.setSubject("测试邮件发送主题");
  56.      // String string = "<html><head></head><body><div>测试Java发送邮件内容</div></body></html>";
  57. String string = "测试Java发送邮件内容";
  58. mail.setContent(string);
  59. // IMailUtil mailUtil = MailUtilsFactory.getMailUtil(Protocols.SSL_MAIL_UTIL);
  60. IMailUtil mailUtil = MailUtilsFactory.getMailUtil(Protocols.TLS_MAIL_UTIL);
  61. mailUtil.send(mail);
  62. System.out.println("邮件发送成功");
  63. }
  64. }

8.工程pom.xml文件(由于本例使用maven工程)

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4.  
  5. <groupId>com.hafiz.zhang</groupId>
  6. <artifactId>sendEmail</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9.  
  10. <name>sendEmail</name>
  11. <url>http://maven.apache.org</url>
  12.  
  13. <properties>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. </properties>
  16.  
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.apache.commons</groupId>
  20. <artifactId>commons-email</artifactId>
  21. <version>1.4</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.slf4j</groupId>
  25. <artifactId>slf4j-log4j12</artifactId>
  26. <version>1.6.4</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.slf4j</groupId>
  30. <artifactId>slf4j-api</artifactId>
  31. <version>1.6.4</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>log4j</groupId>
  35. <artifactId>log4j</artifactId>
  36. <version>1.2.16</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>junit</groupId>
  40. <artifactId>junit</artifactId>
  41. <version>4.12</version>
  42. </dependency>
  43. </dependencies>
  44. </project>

至于,本文为何采用slf4j而不是直接采用log4j进行日志控制输出,详见另一篇博客:slf4j介绍以及实现原理窥探

9.日志输出格式文件

  1. ### set log levels ###
  2. log4j.rootLogger = DEBUG , stdout , D , E , F
  3.  
  4. ### \u8F93\u51FA\u5230\u63A7\u5236\u53F0 ###
  5. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  6. log4j.appender.stdout.Target = System.out
  7. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  8. log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %l-%t:%r ] %m%n
  9.  
  10. ## \u8F93\u51FA\u5230\u65E5\u5FD7\u6587\u4EF6 ###
  11. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  12. log4j.appender.D.DatePattern = '.'yyyyMMdd
  13. log4j.appender.D.File = logs/api/warn.log
  14. log4j.appender.D.Append = true
  15. log4j.appender.D.Threshold = WARN
  16. log4j.appender.D.layout = org.apache.log4j.PatternLayout
  17. log4j.appender.D.encoding=UTF-8
  18. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %l-%t:%r ] %m%n
  19.  
  20. ## \u4FDD\u5B58\u5F02\u5E38\u4FE1\u606F\u5230\u5355\u72EC\u6587\u4EF6 ###
  21. log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
  22. log4j.appender.E.File = logs/api/error.log
  23. log4j.appender.E.DatePattern = '.'yyyyMMdd
  24. log4j.appender.E.Append = true
  25. log4j.appender.E.Threshold = ERROR
  26. log4j.appender.E.layout = org.apache.log4j.PatternLayout
  27. log4j.appender.E.encoding=UTF-8
  28. log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %l-%t:%r ] %m%n
  29.  
  30. ## \u4FDD\u5B58\u5F02\u5E38\u4FE1\u606F\u5230\u5355\u72EC\u6587\u4EF6 ###
  31. log4j.appender.F = org.apache.log4j.DailyRollingFileAppender
  32. log4j.appender.F.File = logs/api/debug.log
  33. log4j.appender.F.DatePattern = '.'yyyyMMdd
  34. log4j.appender.F.Append = true
  35. log4j.appender.F.Threshold = DEBUG
  36. log4j.appender.F.layout = org.apache.log4j.PatternLayout
  37. log4j.appender.F.encoding=UTF-8
  38. log4j.appender.F.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %l-%t:%r ] %m%n

测试结果:

邮件实际收到的内容:

为了保证以后的兼容性,本例采用了工厂设计模式,有什么不正确的或需要改进的,请各位批评指导,谢谢!

附:项目结构图

Java发送邮件初窥的更多相关文章

  1. Hadoop学习笔记(9) ——源码初窥

    Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...

  2. 初窥ElasticSearch

    初窥ElasticSearch 官网上面的,不知道讲的是什么.. youtube上面有一个start with,内容是在windows以下跑这个elastic search,然后用一个fidler工具 ...

  3. 李洪强iOS开发之函数式 编程初窥

    函数式 编程初窥   最近在学习Erlang和Python.Erlang是完全的函数式编程语言,Python语言是面向对象的语言,但是它的语法引入了大量的函数式编程思想.越研究越觉得函数式的编程思路可 ...

  4. 初窥软件工程 2020BUAA软件工程$\cdot$个人博客作业

    初窥软件工程 2020BUAA软件工程\(\cdot\)个人博客作业 目录 初窥软件工程 2020BUAA软件工程$\cdot$个人博客作业 一.作业要求简介 二.正文 (一) 快速看完整部教材,列出 ...

  5. Scrapy001-框架初窥

    Scrapy001-框架初窥 @(Spider)[POSTS] 1.Scrapy简介 Scrapy是一个应用于抓取.提取.处理.存储等网站数据的框架(类似Django). 应用: 数据挖掘 信息处理 ...

  6. 初窥Kaggle竞赛

    初窥Kaggle竞赛 原文地址: https://www.dataquest.io/mission/74/getting-started-with-kaggle 1: Kaggle竞赛 我们接下来将要 ...

  7. scrapy2_初窥Scrapy

    递归知识:oop,xpath,jsp,items,pipline等专业网络知识,初级水平并不是很scrapy,可以从简单模块自己写. 初窥Scrapy Scrapy是一个为了爬取网站数据,提取结构性数 ...

  8. WWDC15 Session笔记 - Xcode 7 UI 测试初窥

    https://onevcat.com/2015/09/ui-testing/ WWDC15 Session笔记 - Xcode 7 UI 测试初窥 Unit Test 在 iOS 开发中已经有足够多 ...

  9. 【软件工程】week5-个人作业-敏捷开发方法初窥

    敏捷开发方法初窥 引言:本周的软件工程个人博客作业是阅读关于敏捷开发方法的文章(http://martinfowler.com/agile.html),并撰写自己的读后感.文章内容非常丰富,对敏捷开发 ...

随机推荐

  1. Spring的问题解决记录

    问题:在MyEclipse中项目工程重命名以后,例如 原来叫HttpService,改为GameApp,但是项目跑起来发现,tomcat服务器依旧为GameApp目录结构,访问也只能GameApp访问 ...

  2. 校友聊NABCD

    特点之一     界面简洁 N:软件的界面是软件成功的必要条件,界面简洁,用户使用方便,就会吸引用户. A:界面可用多种做法做,暂定用C# B:简洁的界面,用户易于理解各项功能,方便使用. C:没有其 ...

  3. Git 常用命令2

    Git 常用命令 Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势. Git常用操作命令: 1) 远程仓库相关命令 检出仓库:$ gi ...

  4. iOS开发——UI基础-懒加载,plist文件,字典转模型,自定义view

    一.懒加载 只有使用到了商品数组才会创建数组 保证数组只会被创建一次 只要能够保证数组在使用时才创建, 并且只会创建一次, 那么我们就称之为懒加载 lazy - (void)viewDidLoad 控 ...

  5. 解决ScrollView里如果有动态更新的ChildView时会自动滚动到底部的方法

    在这个ChildView的xml属性里加上 android:focusable="true" android:focusableInTouchMode="true&quo ...

  6. [codeforces 55]D. Beautiful numbers

    [codeforces 55]D. Beautiful numbers 试题描述 Volodya is an odd boy and his taste is strange as well. It ...

  7. eclipse中整合springMvc,velocity和sitemesh

    1.项目所需要jar包 (有些可能多余) 2.创建UserController   目录如下: package qust.thb.usermanage.controller; import org.s ...

  8. dango foreign key 指定被引用模型的字段

    用 to_field pool_no = models.ForeignKey('SimCardPool', verbose_name=u'卡池编号', db_column='pool_no', to_ ...

  9. .Net Framework 3.5, 3.5 sp1 中文版离线安装

    安装.Net Framework 3.5和3.5 sp1时会自动下载语言包. 解决办法:下载语言包,将语言包拷贝到安装里. 1.用压缩工具解压.NetFramework3.5 2.将语言包文件拷贝到c ...

  10. iOS开源App整理

    http://duxinfeng.com/2015/07/14/iOS%E5%BC%80%E6%BA%90App%E6%95%B4%E7%90%86/ http://blog.csdn.net/dux ...