首先,需要说明的是,这篇博文是在续写我之前写的两篇博客之后的,其他两篇博客具体链接参见:
记录mini-task--代理邮件发收系统的开发过程(一)
http://blog.csdn.net/kuzuozhou/article/details/7881335
记录mini-task--代理邮件发收系统的开发过程(二)
http://blog.csdn.net/kuzuozhou/article/details/7910043
而我想强调的是,我是个未来渴望从技术之路走下去的菜鸟一枚,由于没写过什么博客,可能前面的博客完全是水文,加之自己没写过几行代码,写出的代码可能也很幼稚,低级,但是我还是大胆地贴出自己的代码,我想,至少有两方面的好处:其一,可以给自己的代码做个备份,万一哪天自己的硬盘挂了,或者是电脑丢了,不至于代码全丢失;另一方面,代码虽幼稚,拿出来与各位网友看看,兴许能得到朋友们的指点,我想这何乐而不为呢?
好了,言归正传,促使我写这个demo或者说是mini-task也只是一时兴起,今年在华为实习三个月所做的内容是web相关方面,java也是在此期间刚开始接触,之前是学C的,正好学网络编程时,模仿(或者说照搬)网友的demo写过实现SMTP的程序,这个也可以从我的博客中找到。所以自然想到能不能做点关于Java发邮件的东西。
只是写这篇文章时还停留在“记录mini-task--代理邮件发收系统的开发过程(二)”中的工作量,并没有更多的功能展现。
先简要回顾下所谓的“代理邮件发收系统的开发过程”的概念,当初一个基本的想法是,现阶段每个人都有可能有好几个邮箱,(不同的原因导致),如果每天检查收发邮件时都去登录相应的服务器,未免麻烦,能不能给自己写个统一的界面或者系统呢?只需在该系统里进行适当的配置,便可以登录不同的邮箱服务器进行收发邮件,具有一定的新颖性。
具体的业务流程参见:记录mini-task--代理邮件发收系统的开发过程(二)
首先进入代理邮件发收系统时是一界面,可以维护自己的邮箱信息,包括代理邮箱服务器、代理邮箱、密码属性,我们用Proxy.java类来描述:
//Proxy.java
package fp;
public class Proxy
{
private String mailServ;
private String mailAddr;
private String mailPasswd;
private String number;
public String getMailServ()
{
return mailServ;
}
public void setMailServ(String mailServ)
{
this.mailServ = mailServ;
}
public String getMailAddr()
{
return mailAddr;
}
public void setMailAddr(String mailAddr)
{
this.mailAddr = mailAddr;
}
public String getMailPasswd()
{
return mailPasswd;
}
public void setMailPasswd(String mailPasswd)
{
this.mailPasswd = mailPasswd;
}
public String getNumber()
{
return number;
}
public void setNumber(String number)
{
this.number = number;
}
}
连接的是本地的mysql数据库,我们有连接数据库的操作类connDb.java
//connDb.java
package fp;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
public class connDb {
private static Connection con = null;
private static Statement stmt = null;
private static ResultSet rs = null;
public static void startconn() {
//������ݿⷽ��
try {
Class.forName("com.mysql.jdbc.Driver");
//����������ݿ��м��
try {
con = DriverManager.getConnection(
"jdbc:MySQL://127.0.0.1:3306/test", "root", "fupeng");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void endconn() throws SQLException {
//�ر�����
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
if (con != null) {
con.close();
con = null;
}
}
public static void update(String sql) throws SQLException {
//��ݿ����
startconn();
stmt = con.createStatement();
stmt.executeUpdate(sql);
endconn();
}
public static ArrayList<Proxy> getList(String sql) throws SQLException {
//��ݿ��ѯ
ArrayList<Proxy> list = new ArrayList<Proxy>();
startconn();
stmt = con.createStatement();
rs = stmt.executeQuery(sql);
while (rs.next()) {
Proxy pro = new Proxy();
pro.setMailServ(rs.getString("mailserv"));
pro.setMailAddr(rs.getString("mailaddr"));
pro.setMailPasswd(rs.getString("mailpasswd"));
pro.setNumber(rs.getString("number"));
list.add(pro);
}
endconn();
return list;
}
}
点击写邮件时,进入写邮件界面,我们用MailContent.java实现相应的setter和getter方法。
//MailContent.java
package fp;
public class MailContent
{
private String destAddr;
private String subject;
private String content;
public MailContent(String destAddr, String subject, String content)
{
super();
this.destAddr = destAddr;
this.subject = subject;
this.content = content;
}
public String getDestAddr()
{
return destAddr;
}
public void setDestAddr(String destAddr)
{
this.destAddr = destAddr;
}
public String getSubject()
{
return subject;
}
public void setSubject(String subject)
{
this.subject = subject;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
}
我们用SocketMail.java来封装SMTP的实现:
//SocketMail.java
package fp;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
//import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
/**
* ͨ��socket��smtpЭ������������ʼ�
* @author kuzuozhou
*
*/
/**
* @author fupeng
*
*/
public class SocketMail
{
private String lineFeet = "\r\n";
private int port = 25;
private Socket client;
private BufferedReader in;
private DataOutputStream os;
/**
* �����ʼ�
* @return
*/
public boolean sendMail(Proxy pro , MailContent mc)
{
//��ʼ��
if(client==null)
{
if(!init(pro))
{
return false;
}
}
//�ж�from,to
if(pro.getMailAddr()==null || pro.getMailAddr().isEmpty() || mc.getDestAddr() == null || mc.getDestAddr().isEmpty())
{
return false;
}
//��������
// String result = sendCommand("HELO "+strMailServ+lineFeet);
String result = sendCommand("HELO "+pro.getMailServ()+lineFeet);
if(!isStartWith(result,"250"))
{
System.out.println("����ʧ�ܣ�"+result);
return false;
}
//��֤��������Ϣ
String auth = sendCommand("AUTH LOGIN"+lineFeet);
if(!isStartWith(auth,"334"))
{
return false;
}
String user = sendCommand(new String(Base64.encode(parseUser(pro.getMailAddr())))+lineFeet);
if(!isStartWith(user,"334"))
{
return false;
}
String pass = sendCommand(new String(Base64.encode(pro.getMailPasswd()))+lineFeet);
if(!isStartWith(pass,"235"))
{
return false;
}
//����ָ��
String f = sendCommand("Mail From:<"+pro.getMailAddr()+">"+lineFeet);
if(!isStartWith(f,"250"))
{
return false;
}
String toStr = sendCommand("RCPT TO:<"+mc.getDestAddr()+">"+lineFeet);
if(!isStartWith(toStr,"250"))
{
return false;
}
String data = sendCommand("DATA"+lineFeet);
if(!isStartWith(data,"354"))
{
return false;
}
StringBuilder sb = new StringBuilder();
sb.append("From:<"+pro.getMailAddr()+">"+lineFeet);
sb.append("To:<"+mc.getDestAddr()+">"+lineFeet);
sb.append("Subject:"+mc.getSubject()+lineFeet);
sb.append("Date:2010/10/27 17:30"+lineFeet);
sb.append("Content-Type:text/html;charset=\"UTF-8\""+lineFeet);
sb.append(lineFeet);
sb.append(mc.getContent());
sb.append(lineFeet+"."+lineFeet);
String conStr = sendCommand(sb.toString());
if(!isStartWith(conStr,"250"))
{
return false;
}
//quit
String quit = sendCommand("QUIT"+lineFeet);
if(!isStartWith(quit,"221"))
{
return false;
}
close();
return true;
}
/**
* ��ʼ������
* @return
*/
private boolean init(Proxy pro)
{
boolean boo = true;
if(pro.getMailServ()==null || "".equals(pro.getMailServ()))
{
return false;
}
try
{
client = new Socket(pro.getMailServ(),port);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
os = new DataOutputStream(client.getOutputStream());
String isConnect = response();
if(isConnect.startsWith("220"))
{
}
else
{
System.out.println("��������ʧ�ܣ�"+isConnect);
boo = false;
}
}
catch (UnknownHostException e)
{
System.out.println("��������ʧ�ܣ�");
e.printStackTrace();
boo = false;
}
catch (IOException e)
{
System.out.println("��ȡ��ʧ�ܣ�");
e.printStackTrace();
boo = false;
}
return boo;
}
/**
* ����smtpָ��
* �����ط�������Ӧ��Ϣ
*/
private String sendCommand(String msg)
{
String result = null;
try
{
os.writeBytes(msg);
os.flush();
result = response();
}
catch (IOException e)
{
e.printStackTrace();
}
return result;
}
/**
* ��ȡ����������Ӧ��Ϣ
* @return
*/
private String response()
{
String result = null;
try
{
result = in.readLine();
}
catch (IOException e)
{
e.printStackTrace();
}
return result;
}
/**
* �ر�
*/
private void close()
{
try
{
os.close();
in.close();
client.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private boolean isStartWith(String res,String with)
{
return res.startsWith(with);
}
/**
* �������������ַ�������û���,��kuzuozhou@126.com,������kuzuozhou
* @param mailAddr
* @return
*/
private String parseUser(String mailAddr)
{
return mailAddr.substring(0, mailAddr.lastIndexOf('@'));
}
}
其中,Base64.java是base64编码的封装类,SMTP中加密密码的方法。
//Base64.java
package fp;
import java.io.ByteArrayOutputStream;
public class Base64 {
/**
* Base64����/��������
*
* @author Sol
*/
private final static char[] BASE64_ENCODING_TABLE;
private final static byte[] BASE64_DECODING_TABLE;
static {
BASE64_ENCODING_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
BASE64_DECODING_TABLE = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, -1, -1, -1, -1, -1 };
}
private Base64() {
}
/**
* ����ݽ���Base64���롣
*
* @param data
* ���
* @param offset
* ����еij�ʼƫ����
* @param length
* д����ֽ���
* @return �������ַ�
*/
public final static String encode(byte[] data, int offset, int length) {
if (data == null) {
return null;
}
StringBuffer buffer = new StringBuffer();
int[] temp = new int[3];
int end = offset + length;
while (offset < end) {
temp[0] = data[offset++] & 255;
if (offset == data.length) {
buffer.append(BASE64_ENCODING_TABLE[(temp[0] >>> 2) & 63]);
buffer.append(BASE64_ENCODING_TABLE[(temp[0] << 4) & 63]);
buffer.append('=');
buffer.append('=');
break;
}
temp[1] = data[offset++] & 255;
if (offset == data.length) {
buffer.append(BASE64_ENCODING_TABLE[(temp[0] >>> 2) & 63]);
buffer.append(BASE64_ENCODING_TABLE[((temp[0] << 4) | (temp[1] >>> 4)) & 63]);
buffer.append(BASE64_ENCODING_TABLE[(temp[1] << 2) & 63]);
buffer.append('=');
break;
}
temp[2] = data[offset++] & 255;
buffer.append(BASE64_ENCODING_TABLE[(temp[0] >>> 2) & 63]);
buffer.append(BASE64_ENCODING_TABLE[((temp[0] << 4) | (temp[1] >>> 4)) & 63]);
buffer.append(BASE64_ENCODING_TABLE[((temp[1] << 2) | (temp[2] >>> 6)) & 63]);
buffer.append(BASE64_ENCODING_TABLE[temp[2] & 63]);
}
return buffer.toString();
}
/**
* ����ݽ���Base64���롣
*
* @param data
* ���
* @return �������ַ�
*/
public final static String encode(byte[] data) {
return encode(data, 0, data.length);
}
/**
* ���ַ����Base64���롣
*
* @param str
* �ַ�
* @return �������ַ�
*/
public final static String encode(String str) {
return encode(str.getBytes());
}
/**
* ��ʹ��Base64������ַ���н��롣
*
* @param str
* ���������ַ�
* @return ���������
*/
public final static byte[] decode(String str) {
if (str == null) {
return null;
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = str.getBytes();
int[] temp = new int[4];
int index = 0;
while (index < data.length) {
do {
temp[0] = BASE64_DECODING_TABLE[data[index++]];
} while (index < data.length && temp[0] == -1);
if (temp[0] == -1) {
break;
}
do {
temp[1] = BASE64_DECODING_TABLE[data[index++]];
} while (index < data.length && temp[1] == -1);
if (temp[1] == -1) {
break;
}
buffer.write(((temp[0] << 2) & 255) | ((temp[1] >>> 4) & 255));
do {
temp[2] = data[index++];
if (temp[2] == 61) {
return buffer.toByteArray();
}
temp[2] = BASE64_DECODING_TABLE[temp[2]];
} while (index < data.length && temp[2] == -1);
if (temp[2] == -1) {
break;
}
buffer.write(((temp[1] << 4) & 255) | ((temp[2] >>> 2) & 255));
do {
temp[3] = data[index++];
if (temp[3] == 61) {
return buffer.toByteArray();
}
temp[3] = BASE64_DECODING_TABLE[temp[3]];
} while (index < data.length && temp[3] == -1);
if (temp[3] == -1) {
break;
}
buffer.write(((temp[2] << 6) & 255) | temp[3]);
}
return buffer.toByteArray();
}
}
页面展示jsp方面,list.jsp用于刚进入时的页面展示,从数据库获取信息并展示出来。
//list.jsp
<%@ page language="java" import="fp.connDb,fp.Proxy,java.util.*"
pageEncoding="gbk"%>
<%--jsp头文件,包括引入的包和支持语言,gbk为支持中文--%>
<%
ArrayList<Proxy> list = connDb.getList("select mailserv,mailaddr,mailpasswd,number from proxy"); //获得proxy表中所有数据并以列表形式返回
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>代理邮箱系统设置</title>
</head>
<body>
<table border="1">
<tr>
<td>
代理邮箱服务器
</td>
<td>
代理邮箱
</td>
<td>
密码
</td>
<td>
操作
</td>
</tr>
<%
{
for (Iterator it = list.iterator(); it.hasNext();)
{
Proxy pro = (Proxy) it.next();
System.out.println(pro.getMailServ());
%>
<tr>
<td><%=pro.getMailServ()%></td>
<td><%=pro.getMailAddr()%></td>
<td><%=pro.getMailPasswd()%></td>
<td><a href="update.jsp?number=<%=pro.getNumber()%>">编辑</a></td>
</tr>
<%
}
}
%>
</table>
<a href="writeMail.jsp">去写邮件</a>
</body>
</html>
其他几个不在一一赘述,通过自己跑可以很容易看出其功能。
//sendMail.jsp
<%@ page language="java" import="fp.SocketMail,fp.MailContent,fp.connDb,fp.Proxy,java.util.*" pageEncoding="UTF-8"%>
<%
String destAddr = new String(request.getParameter("destAddr").getBytes("UTF-8")); //接收信息
String subject = new String(request.getParameter("subject").getBytes("UTF-8"));
String content = new String(request.getParameter("content").getBytes("UTF-8"));
MailContent mc = new MailContent(destAddr,subject,content);
ArrayList<Proxy> list = connDb.getList("select mailserv,mailaddr,mailpasswd,number from proxy"); //获得proxy表中所有数据并以列表形式返回
Proxy pro =null;
for (Iterator it = list.iterator(); it.hasNext();)
{
pro = (Proxy) it.next();
}
SocketMail sm = new SocketMail();
//执行发送
boolean b = sm.sendMail(pro,mc);
if(b)
response.sendRedirect("success.jsp"); //转到list.jsp页面
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'updateInfo.jsp' starting page</title>
</head>
<body>
This is my JSP page.
<br>
</body>
</html>
//success.jsp
提示成功信息。
//update.jsp
<%@ page language="java" import="fp.connDb,fp.Proxy,java.util.*"
pageEncoding="gbk"%>
<%
String number = new String(request.getParameter("number")); //获得要修改
ArrayList list = connDb.getList("select * from proxy where number="+"'"+number+"'");//查询要修改的信息,并以列表返回
Proxy pro = (Proxy) list.get(0); //将列表内容换成学生类
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'update.jsp' starting page</title>
</head>
<body>
<form method="post" action="updateMailServInfo.jsp">
<p>
代理邮箱服务器:
<input type="text" name="mailserv" value="<%=pro.getMailServ()%>">
</p>
<p>
代理邮箱地址
<input type="text" name="mailaddr" value="<%=pro.getMailAddr()%>">
</p>
<p>
密码
<input type="text" name="mailpasswd" value="<%=pro.getMailPasswd()%>">
<input type="hidden" name="number" value="<%=number%>">
</p>
<p>
<input type="submit" value="保存" name="button1">
</p>
</form>
</body>
</html>
//updateMailServInfo.jsp
<%@ page language="java" import="fp.connDb" pageEncoding="gbk"%>
<%
String mailserv = new String(request.getParameter("mailserv").getBytes("ISO-8859-1")); //接收信息
String mailaddr = new String(request.getParameter("mailaddr").getBytes("ISO-8859-1"));
String mailpasswd = new String(request.getParameter("mailpasswd").getBytes("ISO-8859-1"));
String number = new String(request.getParameter("number").getBytes("ISO-8859-1"));
String sql = "update proxy set mailserv="+"'"+mailserv+"'"+","+"mailaddr="+"'"+mailaddr+"'"+","+"mailpasswd="+"'"+mailpasswd+"'"+"where number="+"'"+number+"'";
connDb.update(sql); //执行修改
response.sendRedirect("list.jsp"); //转到list.jsp页面
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'updateInfo.jsp' starting page</title>
</head>
<body>
This is my JSP page.
<br>
</body>
</html>
//writeMail.jsp
<%@ page language="java" import="fp.connDb,fp.Proxy,java.util.*"
pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>写邮件</title>
</head>
<body>
<form method="post" action="sendMail.jsp">
<p>
</p>
<p>
收件人
<input type="text" style="height:25px;width:395px;" name="destAddr" >
</p>
<p>
主题
<input type="text" style="height:25px;width:395px;" name="subject" >
</p>
<p>
内容
<textarea name = "content" rows="6" cols="50"></textarea>
</p>
<p>
<input type="submit" value="发送" name="button2">
</p>
</form>
</body>
</html>
当然,项目没有采用采用任何的框架(structs等),导致本项目也只是功能的初步实现,很多方面还值得改进,这在后面,需要持续改进,当然也欢迎您的不吝赐教!