2007年10月16日

新注册了个独立域名,使用独立的blog了。

http://618119.com

rss订阅地址: http://feed.feedsky.com/lizongbo

从最早的 http://blog.csdn.net/lizongbo,

到 http://blog.donews.com/lizongbo

再到http://www.blogjava.net/lizongbo

现在终于拥有自己的域名和独立的blog了。

2005年09月06日

java.lang.SecurityException: Unsupported keysize or algorithm parameters
            at javax.crypto.Cipher.init(DashoA6275)
的解决

在使用 bouncycastle的时候,会遇到

java.lang.SecurityException: Unsupported keysize or algorithm parameters
            at javax.crypto.Cipher.init(DashoA6275)

这个错误信息,是keysize长度被限制的缘故。

需要下载下面的文件了;来更新jdk的策略文件。

http://java.sun.com/j2se/1.4.2/download.html

Java Cryptography Extension (JCE)
Unlimited Strength Jurisdiction Policy Files 5.0

jce_policy-1_4_2.zip

Java Cryptography Extension (JCE)
Unlimited Strength Jurisdiction Policy Files 1.4.2

http://java.sun.com/j2se/1.5.0/download.jsp

jce_policy-1_5_0.zip


具体可以参考:
http://www.bouncycastle.org/specifications.html

2005年05月16日

代码改自:org.displaytag.sample.displaysourceservlet

web.xml的映射如下:
  <servlet>
    <servlet-name>displayjspsourceservlet</servlet-name>
    <servlet-class>com.lizongbo.displayjspsourceservlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>displayjspsourceservlet</servlet-name>
    <url-pattern>*.jspsrc</url-pattern>
  </servlet-mapping>

java代码如下:
package com.lizongbo;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class displayjspsourceservlet
    extends httpservlet {
  private static final string content_type = "text/html; charset=utf-8";
  public void init() throws servletexception {
  }

  public void doget(httpservletrequest request, httpservletresponse response) throws
      servletexception, ioexception {
    response.setcontenttype(content_type);
    printwriter out = response.getwriter();
    out.println("<html>");
    out.println("<head><title>jsp source ");
    string jspfn = request.getservletpath();
    jspfn = jspfn == null ? "" : jspfn;
    if (jspfn.lastindexof(".jsp.") > 1) {
      jspfn = jspfn.substring(0,jspfn.lastindexof(".jsp.") + 4);
    }
    out.print(jspfn);
    out.println("  — lizongbo edit from org.displaytag.sample.displaysourceservlet </title></head>");
    out.println("<body bgcolor=\"#ffffff\">");
    out.println("<pre>");
    inputstream inputstream = getservletcontext().getresourceasstream(
        jspfn);
    if (inputstream == null) {
      out.println("unable to find jsp file: " + jspfn);
    }
    else {
      for (int currentchar = inputstream.read(); currentchar != -1;
           currentchar = inputstream.read()) {
        if (currentchar == ‘<’) {
          out.print("&lt;");
        }
        else {
          out.print( (char) currentchar);
        }
      }
    }
    out.println("</pre>");
    out.println("</body>");
    out.println("</html>");
    out.close();
  }
  public void dopost(httpservletrequest request, httpservletresponse response) throws
      servletexception, ioexception {
    doget(request, response);
  }

  public void destroy() {
  }
}


使用方法
比如可以访问:http://lizongbo.com:/lizongbo/lizongbo.jsp
那么访问 http://lizongbo.com:/lizongbo/lizongbo.jsp.jspsrc

就可以查看到jsp文件的源代码。

2005年05月13日

在jstl中也可以像php那样随时声明变量而且不操心变量的类型。
下面的代码只需要修改数据库连接的参数,和需要显示的表名即可。


<%@page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x" %>
<html>
<head>
<title>lizongbo 的 jstl 例子</title>
</head>
<body bgcolor="#ffffff">
<c:set var="db_driver" value="org.gjt.mm.mysql.Driver"/>
<c:set var="db_url" value="jdbc:mysql://localhost:3306/lizongbo?useUnicode=true&characterEncoding=UTF-8"/>
<c:set var="db_user" value="lizongbo"/>
<c:set var="db_password" value="lizongbo"/>
<c:set var="table_name" value="tbl_login_log"/>
<c:set var="crtpageno" value="${param.crtpageno > 0? param.crtpageno:1}"/>
<c:set var="countperpage" value="${param.countperpage > 0? param.countperpage:5}"/>
<c:set var="limitb" value="${(crtpageno-1)*countperpage}"/>
<sql:setDataSource driver="${db_driver}" user="${db_user}" password="${db_password}" url="${db_url}" var="mydb" scope="application"/>
<sql:query var="myrs" sql="select count( * ) as countnum from ${table_name}" dataSource="${mydb}" scope="request"></sql:query>
<c:out value="一共有${myrs.rows[0].countnum}条记录<br/>" escapeXml="false"></c:out>
<c:set var="allpageno" value="${myrs.rows[0].countnum % countperpage ==0 ? (myrs.rows[0].countnum) / countperpage : (myrs.rows[0].countnum) / countperpage +1}" scope="request"/>
<%String alpn =String.valueOf( java.lang.Math.round(Double.parseDouble(String.valueOf(request.getAttribute("allpageno")))));%>
<c:set var="allpageno" value="<%=alpn%>"/>
<c:set var="crtpageno" value="${crtpageno > allpageno ? allpageno : crtpageno}"/>
<c:set var="prepageno" value="${crtpageno>1 ? crtpageno-1 : crtpageno}"/>
<c:set var="nrepageno" value="${crtpageno >= allpageno? allpageno : crtpageno+1}"/>
<a href="<%=request.getRequestURI()%>?crtpageno=1">第一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${prepageno}" />">上一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${nrepageno}" />">下一页</a>
<a href="<%=request.getRequestURI()%>?crtpageno=<c:out value="${allpageno}" />">最后一页</a>
<sql:query var="myrs" sql="select * from ${table_name} LIMIT ${limitb}, ${countperpage} " dataSource="${mydb}" scope="request"></sql:query>
<table border="1">
<c:forEach var="row" items="${myrs.rows}" varStatus="status">
<c:if test="${status.first}">
<tr>
<c:forEach var="colname" items="${row}">
<td>
<c:out value="${colname.key}" escapeXml="true"/>
</td>
</c:forEach>
</tr>
</c:if>
<tr>
<c:forEach var="col" items="${row}">
<td>
<c:out value="${col.value}" escapeXml="true"/>
</td>
</c:forEach>
</tr>
<c:set var="crtrsnum" value="${status.count}"/>
</c:forEach>
</table>
当前是第:<c:out value="${limitb+1}"/>到第<c:out value="${limitb+crtrsnum}"/>条记录
<br/>
</body>
</html>


2005年05月09日

<%@page contentType="text/html; charset=UTF-8"%>
<%@page import="java.util.*"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
<html>
<head>
<title>language choose</title>
</head>
<body bgcolor="#ffffff">

copyright @ lizongbo @ donews.net


<c:if test="${param['locale'] != null}">
  <fmt:setLocale value="${param['locale']}" scope="session"/>
  <fmt:setTimeZone value="${param['locale']}" scope="session"/>
</c:if>
<c:if test="${param['locale'] == null}">
  <fmt:setLocale value="${header['locale']}" scope="session"/>
  <fmt:setTimeZone value="${header['locale']}" scope="session"/>
</c:if>
<%
  Locale crtl = Locale.getDefault();
  Object cobj = session.getAttribute("javax.servlet.jsp.jstl.fmt.locale.session");
  if (cobj != null && cobj instanceof Locale) {
    crtl = (Locale) cobj;
  }
  Locale[] la = java.text.NumberFormat.getAvailableLocales();
%>
<form method="POST" action="">
  language choose:
  <br />
<select name="locale">
<%for (int i = 0; i < la.length; i++) {%>
  <option value="<%=la[i]%>" <%if (la[i].equals(crtl)) {
                                 out.print("selected=\"selected\"");
                               }%>><%= la[i].getDisplayName(crtl)%></option>
<%
  }
%>
</select>
<br />
<input type="submit" value="change"/>
</form>
</body>
</html>

2005年04月29日
在对一些字符串格式的时间进行比较的时候,
我看到的做法绝大部分都是先把字符串转换成Date类型,然后再进行比较。
 
 
而实际情况中,
如果是确定格式的,并且长度固定一样长的字符串。
完全可以直接借助String 的compareTo就进行比较:
例如:
String aa="2004/03/04";//("2004-02-03 11:22:33")
String bb="2004/03/05";//("2005-02-06 12:21:33")
if (aa.compareTo(aa)>0) {
System.out.println("aa da ");
}else{
System.out.println("bb da");
}
这样完全可以省略掉对字符串进行时间转换的开销。
我喜欢这样的做法:)偷懒也是一种乐趣。
 
 

例如:
String aa="2004/03/04";//("2004-02-03 11:22:33")
String bb="2004/03/05";//("2005-02-06 12:21:33")
if (aa.compareTo(aa)>0) {
System.out.println("aa da ");
}else{
System.out.println("bb da");
}
这样完全可以省略掉对字符串进行时间转换的开销。
我喜欢这样的做法:)偷懒也是一种乐趣。
 
 
2005年03月15日
使用hsqldb将常用数据库整合到应用程序中
 
http://blog.csdn.net/lizongbo/archive/2005/02/13/286697.aspx 
提到过一些常用数据库,可以视作固定编码的数据库。对于这些书库,通常只进行查询使用。
 
因此针对一些比如用户希望只传入ip地址就要查询到用户信息,或者只传入行政区划编号,
就可以得到行政区划名字等等需求。而且用户不希望去配置数据库信息等等,
Access文件虽然比较方便,却不具有跨平台的效果,因此可以借助开源免费的hsql来进行在应用小型数据库的嵌入。
尤其是在1.7.2版本加入了新的特性,可以支持在jar里直接以只读方式访问数据库。
因此,把封装好的class和数据文件一并打包,可以非常方便的给别人使用。
 
以下是操作过程,
首先下载hsql,最新的稳定版本是1.7.3.3:
http://heanet.dl.sourceforge.net/sourceforge/hsqldb/hsqldb_1_7_3_3.zip
 
下载ip数据库:
http://96hk.y365.com/soft/qqwry.rar
 
然后利用自带工具将其数据解压导出为文本文件
,用Editplus打开,替换掉  CZ88.NET,以减少文件占用空间,(使用正则表达式进行替换,将数据规整。
用xmlspy进行转换成xml再导入access,(这一步完全可以省略掉)),然后直接用access导入这195074条记录。
 
然后是从Access里导入数据
比如我的常用数据有ip地址信息表,行政区划和省份信表:
 //创建表
    connto.createStatement().execute(“CREATE TABLE PROVINCE(PDOMAIN VARCHAR(3),PLABEL VARCHAR(50),PNAME VARCHAR(6),PNO VARCHAR(3),PSHORTNAME VARCHAR(2))”);
    connto.createStatement().execute(
        “CREATE TABLE XZQH(NAME VARCHAR(30),CODE VARCHAR(6),O_CODE VARCHAR(8))”);
    connto.createStatement().execute(
        “CREATE TABLE IPINFO(IPS BIGINT,IPE BIGINT,AREA VARCHAR(60))”);
    ResultSet rs = stmtin.executeQuery(“SELECT * FROM province”);
 
 
PreparedStatement pstmt = connto.prepareStatement(
        “insert into province (pdomain,plabel,pname,pno,pshortname) values(?,?,?,?,?)”);
 
导入完成之后,将数据文件添加到jar文件中,再封装好常用方法。
就可以了,以后的数据维护也非常简单,只要不修改表结果,只需要把数据文件更新即可,不需要修改任何代码。
 
调用方法示例 :
先引入这个jar文件,然后使用下面的方法调用,
String area=com.lizongbo.database.SearchUtil.findAreabyIp(“192.168.9.1″);
 
使用者不需要关心任何其它的东西,一行代码就得到想要的结果了。
 
 
不过需要注意的是,使用了ip数据库之后,因为ip数据库记录量很大,生成的scrpit文件比较大,我的文件有22M,
打包压缩后的jar,也有 3M大小,初始化数据库的时候会非常缓慢。
综合考虑, 牺牲空间和一部分内存来换取应用程序的可复用和跨平台以及数据记录可维护性,还是比较值得的。
 
抓图:  
 
 
参考:
 

http://hsqldb.sourceforge.net

 
http://hsqldb.sourceforge.net/web/hsqlFAQ.html
 
http://www-900.ibm.com/developerWorks/cn/java/l-hsqldb/index.shtml
 




 

2005年03月12日
利用xml+xsl快速生成大量JSP的常用代码的方法.
 
参考Jbuilder的Servlet向导来使用xml+xsl产生JSP的常用代码。
xml样本:
 
<?xml version=”1.0″ encoding=”GB2312″?>
<?xml-stylesheet type=”text/xsl” href=”jspram.xsl”?>
<jsp xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”jspsrcgen.xsd”>
 <param>
  <variable>rloginusername</variable>
  <name>loginusername</name>
  <type>String</type>
  <src>request</src>
  <default>lizongbo</default>
  <desc>用户的登录名</desc>
 </param>
 <param>
  <variable>clastlogintime</variable>
  <name>lastlogintime</name>
  <type>long</type>
  <src>cookie</src>
  <default>0</default>
  <desc>用户最近一次的登录时间</desc>
 </param>
 <param>
  <variable>suserpass</variable>
  <name>userpass</name>
  <type>String</type>
  <src>session</src>
  <default>password</default>
  <desc>存放在session里的密码</desc>
 </param>
</jsp>
 
xsl文件略。
 
 
转换后的效果图和相关代码:
 

testjsp.jsp

变量名字 参数名字 变量类型 变量来源 默认值 备注
rloginusername loginusername String request lizongbo 用户的登录名
rloginusername loginusername String request lizongbo 用户的登录名
rloginusername loginusername String request lizongbo 用户的登录名
suserpass userpass String session password 存放在session里的密码
suserpass userpass String session password 存放在session里的密码
suserpass userpass String session password 存放在session里的密码
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
clastlogintime lastlogintime long cookie 0 用户最近一次的登录时间
生成好的java代码:
<%@page import=”com.lizongbo.util.JSPUtil”%>
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//用户的登录名
String rloginusername = JSPUtil. getParameter(request,”loginusername”,lizongbo);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//存放在session里的密码
String suserpass = JSPUtil.getAttribute(session,”userpass”,password);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
//用户最近一次的登录时间
long clastlogintime = JSPUtil. getValue(request.getCookies(),”lastlogintime”,0);
 
 
 
我封装的JSPUtil代码片断:
 
  public static string getparameter(httpservletrequest request, string name,
                                    string defval) {
    string param = request.getparameter(name);
    return (param != null ? param : defval);
  }
 
  public static boolean getparameter(httpservletrequest request, string name,
                                     boolean defval) {
    string bv = request.getparameter(name);
    return bv == null ? defval : parseboolean(bv);
 
  }
 
  public static double getparameter(httpservletrequest request, string name,
                                    double defval) {
    return parsedouble(request.getparameter(name), defval);
  }
 
  public static float getparameter(httpservletrequest request, string name,
                                   float defval) {
    return parsefloat(request.getparameter(name), defval);
  }
 
  public static int getparameter(httpservletrequest request, string name,
                                 int defval) {
    return parseint(request.getparameter(name), defval);
  }
 
  public static long getparameter(httpservletrequest request, string name,
                                  long defval) {
    return parselong(request.getparameter(name), defval);
  }
 
  public static short getparameter(httpservletrequest request, string name,
                                   short defval) {
    return parseshort(request.getparameter(name), defval);
  }

一般的javamil发送附件的代码如下:
                bodypart = new mimebodypart();
                datasource datasource = new filedatasource(“c:\测试附件.doc”);
                bodypart.setdatahandler(new datahandler(datasource));
                bodypart.setfilename(mimeutility.encodeword(“测试附件.doc”,”gb2312″, null));
                multipart.addbodypart(bodypart);
由于javamail 的包里默认的对javax.activation.datasource只有两个实现:
分别是:filedatasource和urldatasource。
因此在webapp里为了不把上传的文件再保存为本地文件,然后再使用filedatasource,
我结合apache的commons fileupload组件,写了一个实现了datasource的uploadfiledatasource。

其实代码非常简单,具体代码如下:

 

package com.lizongbo.util;

import java.io.*;

import javax.activation.*;
import org.apache.commons.fileupload.fileitem;

/**
 * <p>title: uploadfile datasource for javamail</p>
 * <p>description: </p>
 * <p>copyright: copyright (c) 2005</p>
 * <p>company: zongboli</p>
 * @author lizongbo
 * @version 1.0
 */
public class uploadfiledatasource implements datasource {
    private fileitem uploadfileitem = null;
    public uploadfiledatasource() {
    }

    public uploadfiledatasource(fileitem uploadfile) {
        this.uploadfileitem = uploadfile;
    }
    public string getcontenttype() {
        return uploadfileitem.getcontenttype();
    }

    public inputstream getinputstream() throws ioexception {
        return uploadfileitem.getinputstream();
    }

    public string getname() {
        return uploadfileitem.getname();
    }

    public outputstream getoutputstream() throws ioexception {
        return null;
    }

    public static void main(string[] args) {
    }
}

附在struts里的使用例子:

if (diskfileupload.ismultipartcontent(servletrequest)) {
            diskfileupload fileupload = new diskfileupload();
            fileupload.setsizemax(1024 * 1024);
            try {
                list filelist = fileupload.parserequest(servletrequest);
                iterator itr = filelist.iterator();
                fileitem item;
                while (itr.hasnext()) {
                    item = (fileitem) itr.next();
                    if (item.isformfield()) {
                        logger.debug(item.getfieldname() + “=” +
                                     item.getstring() + “”);
                    } else {
                     mimebodypart   bodypart = new mimebodypart();
                     datasource datasource = new com.webmail.util.uploadfiledatasource(item);
                     bodypart.setdatahandler(new datahandler(datasource));
                     multipart.addbodypart(bodypart);                    }
                }
            } catch (org.apache.commons.fileupload.fileuploadbase.
                     sizelimitexceededexception sle) {
                logger.debug(“size is too large”, sle);
            } catch (org.apache.commons.fileupload.fileuploadbase.
                     unknownsizeexception use) {
                logger.debug(“unknown size “, use);
            } catch (org.apache.commons.fileupload.fileuploadexception fue) {
                logger.debug(fue.getmessage() + “  “);
            } catch (exception e) {
                logger.debug(“chucuo”, e);
            }

        } else {
            logger.debug(“没有附件!!!”);
        }


由于《用javamail免认证方式发送邮件给163.com的用户的完整代码实例。》 代码被人copy直接运行, 给我带来了很大的麻烦(发了很多垃圾邮件到我邮箱 :( ),
从现在开始发布的代码,一律转为小写之后再进行发布,以仅供阅读参考。

 

2005年03月06日
1.把邮件保存为一个文件,这个文件可以直接用Outlook,Foxmail等邮件客户端工具打开。
 
 
    private void savemail(MimeMessage msg, String path) {
        try {
            File f = new File(path);
            f.getParentFile().mkdirs();
            FileOutputStream fo = new FileOutputStream(f);
//CRLFOutputStream 可以把一些换行符不满足MIME规范的邮件进行修正。
            CRLFOutputStream CRLFO = new CRLFOutputStream(fo);
            msg.writeTo(CRLFO);
            CRLFO.close();
            fo.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
调用:
 
savemail(msg,”c:/lizongbo/testmail.eml”);
 
2.对邮件体使用base64编码。
 
默认情况下使用的是quoted-printable编码:
示例如下:
 
    MimeMessage msg = new MimeMessage((Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    msg.setText(“测试一下,邮件来自 http://www.donews.net/lizongbo !!!”);
    msg.setSubject(“测试标题!!!”, “GB2312″);
    MimeMultipart multipart = new MimeMultipart();
    MimeBodyPart txtbodyPart = new MimeBodyPart();
    txtbodyPart.setText(“这是一封html邮件,请用html方式察看!!!”);
    multipart.addBodyPart(txtbodyPart);
    MimeBodyPart htmlodyPart = new MimeBodyPart();
    String content=”html邮件内容!来自 http://www.donews.net/lizongbo “;
    content = “<html><body>” + content + “</body><html>”;
    htmlodyPart.setContent(content, “text/html;charset=GBK”);
    multipart.addBodyPart(htmlodyPart);
    msg.setContent(multipart);
    msg.saveChanges();
得到的邮件内容为:
————————————————————–
 
 
 
Subject: =?GB2312?B?suLK1LHqzOKjoaOho6E=?=
 
Mime-Version: 1.0
 
Content-Type: multipart/mixed; boundary=”—-=_Part_0_8568863.1110043294484″
 
 
 
——=_Part_0_8568863.1110043294484
 
Content-Type: text/plain; charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
1eLKx9K7t+JodG1s08q8/qOsx+vTw2h0bWy3vcq9suy/tKOho6GjoQ==
 
——=_Part_0_8568863.1110043294484
 
Content-Type: text/html;charset=GBK
 
Content-Transfer-Encoding: quoted-printable
 
 
 
<html><body>html=D3=CA=BC=FE=A3=A1 http://www.donews.net/lizongbo </body><h=
 
tml>
 
——=_Part_0_8568863.1110043294484–
 
 
 
 
 
————————————————————–
 
使用base64编码的代码:
————————————————————–
    MimeMessage msg = new MimeMessage( (Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    msg.setText(“测试一下,邮件来自 http://www.donews.net/lizongbo !!!”);
    msg.setSubject(“测试标题!!!”, “GB2312″);
    MimeMultipart multipart = new MimeMultipart();
    MimeBodyPart txtbodyPart = new MimeBodyPart();
    txtbodyPart.setText(“这是一封html邮件,请用html方式察看!!!”);
    multipart.addBodyPart(txtbodyPart);
    MimeBodyPart htmlodyPart = new MimeBodyPart();
    String content = “html邮件! http://www.donews.net/lizongbo “;
    content = “<html><body>” + content + “</body><html>”;
    htmlodyPart.setContent(content, “text/html;charset=GBK”);
    //最最关键的就这么一行
    htmlodyPart.setHeader(“Content-Transfer-Encoding”, “base64″);
    multipart.addBodyPart(htmlodyPart);
    msg.setContent(multipart);
    msg.saveChanges();
 
得到邮件内容如下:
 
————————————————————–
 
 
 
Subject: =?GB2312?B?suLK1LHqzOKjoaOho6E=?=
 
Mime-Version: 1.0
 
Content-Type: multipart/mixed; boundary=”—-=_Part_0_8568863.1110043370687″
 
 
 
——=_Part_0_8568863.1110043370687
 
Content-Type: text/plain; charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
1eLKx9K7t+JodG1s08q8/qOsx+vTw2h0bWy3vcq9suy/tKOho6GjoQ==
 
——=_Part_0_8568863.1110043370687
 
Content-Type: text/html;charset=GBK
 
Content-Transfer-Encoding: base64
 
 
 
PGh0bWw+PGJvZHk+aHRtbNPKvP6joSBodHRwOi8vd3d3LmRvbmV3cy5uZXQvbGl6b25nYm8gPC9i
 
b2R5PjxodG1sPg==
 
——=_Part_0_8568863.1110043370687–
 
3.启动javamail的调试模式,可以在发送和接收邮件的时候方便查看详细的调试信息,只需要:
 
    //Session session = Session.getInstance(System.getProperties());
    session.getProperties().setProperty(“mail.debug”,”true”);
    session.setDebug(true);
//默认的是输出调试信息到控制台
 
4.显式连接到需要验证的smtp服务器进行邮件发送。
一般的资料都说是自己继承javax.mail.Authenticator.
代码如下:
 
package com.lizongbo.javamail;
 
 
import javax.mail.*;
 
public class MailAuthenticator extends Authenticator {
    public MailAuthenticator() {
    }
 
    private String mUser;
    private String mPass;
 
    public MailAuthenticator(String userName, String passWord) {
        super();
        mUser = userName;
        mPass = passWord;
    }
 
    public PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(mUser, mPass);
    }
 
}

调用的示例:
 Session session = Session.getInstance(System.getProperties(),new MailAuthenticator (“lizongbo”,”password”) );
    MimeMessage msg = new MimeMessage(session);
Transport.send(msg);
 
    其实也可以不继承这个class,而是直接使用用户名和密码连接到邮件服务器进行邮件发送操作。
    MimeMessage msg = new MimeMessage( (Session)null);
    msg.setFrom(new InternetAddress(“lizongbo@gmail.com“));
    msg.setRecipient(Message.RecipientType.TO,
                     new InternetAddress(“lizongbo@msn.com“));
    //中间代码略去
    msg.saveChanges();
    Transport smtpTransport = session.getTransport(“smtp”);
    smtpTransport.connect(“smtp.163.com”, 25, “lizongbo”, “password”);
    //切忌不可以使用 smtpTransport.send(msg)和smtpTransport.send(msg,msg.getAllRecipients());
    //因为这两个是静态方法,无法获取与smtpTransport这个实例有关的参数.
    smtpTransport.sendMessage(msg, msg.getAllRecipients());
 
具体可以通过阅读javamail1.3.2的源代码来发现一些细节差异。