﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Terry.B.Li           彬-文章分类-java</title><link>http://www.blogjava.net/libin2722/category/25649.html</link><description>虚其心，可解天下之问；专其心，可治天下之学；静其心，可悟天下之理；恒其心，可成天下之业。</description><language>zh-cn</language><lastBuildDate>Sat, 20 Nov 2010 20:27:16 GMT</lastBuildDate><pubDate>Sat, 20 Nov 2010 20:27:16 GMT</pubDate><ttl>60</ttl><item><title>纯真IP数据库格式详解</title><link>http://www.blogjava.net/libin2722/articles/338551.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 20 Nov 2010 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/338551.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/338551.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/338551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/338551.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/338551.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 摘要				  网络上的IP数据库以纯真版的最为流行，LumaQQ也采用了纯真版IP数据库做为IP查询功能的基础。不过关于其格式的文档却非常之少，后来终于在网上找到了一份文档，得以了解其内幕，不过那份文档寥寥数语，也是颇为耐心才读明白。在这里我重写一份，以此做为LumaQQ开发者文档的一部分，我想还是必要的。本文详细介绍了纯真IP数据库的格式，并且给出了一些Demo以供参考。 ...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/338551.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/338551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2010-11-20 15:15 <a href="http://www.blogjava.net/libin2722/articles/338551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java读取纯真IP数据库QQwry.dat的源代码</title><link>http://www.blogjava.net/libin2722/articles/338543.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 20 Nov 2010 06:23:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/338543.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/338543.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/338543.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/338543.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/338543.html</trackback:ping><description><![CDATA[
		<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">
				<span class="Apple-style-span" style="font-family: 'ms shell dlg'; font-size: 14px; line-height: 28px;">java读取纯真IP数据库QQwry.dat的源代码,要运行此程序必须有<br style="clear: both;" />到网上下载QQwry.da，由于太大，我这里就不提供了。<br style="clear: both;" />一、IPEntry.java<br style="clear: both;" />/** *<br style="clear: both;" />* 一条IP范围记录，不仅包括国家和区域，也包括起始IP和结束IP *<span class="Apple-converted-space"> </span><br style="clear: both;" /><br style="clear: both;" />*<span class="Apple-converted-space"> </span><br style="clear: both;" />* @author 马若劼<br style="clear: both;" />*/<br style="clear: both;" />public class IPEntry {<br style="clear: both;" />    public String beginIp;<br style="clear: both;" />    public String endIp;<br style="clear: both;" />    public String country;<br style="clear: both;" />    public String area;<br style="clear: both;" />    <br style="clear: both;" />    /**<br style="clear: both;" />     * 构造函数<br style="clear: both;" />     */<br style="clear: both;" />  <span class="Apple-converted-space"> </span><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />public IPEntry() {<br style="clear: both;" />        beginIp = endIp = country = area = "";<br style="clear: both;" />    }<br style="clear: both;" />    <br style="clear: both;" />    public String toString(){<br style="clear: both;" />       retur        this.area+"  "+this.country+"IP范围:"+this.beginIp+"-"+this.endIp;<br style="clear: both;" />    }<br style="clear: both;" />   }<span class="Apple-converted-space"> </span><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />二、Utils.java<br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />/*<br style="clear: both;" />* Created on 2004-8-4<br style="clear: both;" />*<br style="clear: both;" />*/<br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />import java.io.UnsupportedEncodingException;<br style="clear: both;" /><br style="clear: both;" />/**<br style="clear: both;" />* @author LJ-silver<br style="clear: both;" />*/<br style="clear: both;" />public class Utils {<br style="clear: both;" />    /**<br style="clear: both;" />     * 从ip的字符串形式得到字节数组形式<br style="clear: both;" />     * @param ip 字符串形式的ip<br style="clear: both;" />     * @return 字节数组形式的ip<br style="clear: both;" />     */<br style="clear: both;" />    public static byte[] getIpByteArrayFromString(String ip) {<br style="clear: both;" />        byte[] ret = new byte[4];<br style="clear: both;" />        java.util.StringTokenizer st = new java.util.StringTokenizer(ip, ".");<br style="clear: both;" />        try {<br style="clear: both;" />            ret[0] = (byte)(Integer.parseInt(st.nextToken()) &amp; 0xFF);<br style="clear: both;" />            ret[1] = (byte)(Integer.parseInt(st.nextToken()) &amp; 0xFF);<br style="clear: both;" />            ret[2] = (byte)(Integer.parseInt(st.nextToken()) &amp; 0xFF);<br style="clear: both;" />            ret[3] = (byte)(Integer.parseInt(st.nextToken()) &amp; 0xFF);<br style="clear: both;" />        } catch (Exception e) {<br style="clear: both;" />            System.out.println(e.getMessage());<br style="clear: both;" />        }<br style="clear: both;" />        return ret;<br style="clear: both;" />    }<br style="clear: both;" />    <br style="clear: both;" />    public static void main(String args[]){<br style="clear: both;" />         byte[] a=getIpByteArrayFromString(args[0]);<br style="clear: both;" />          for(int i=0;i&lt; a.length;i++)<br style="clear: both;" />                System.out.println(a[i]);<br style="clear: both;" />          System.out.println(getIpStringFromBytes(a));<span class="Apple-converted-space"> </span><br style="clear: both;" />    }<br style="clear: both;" />    /**<br style="clear: both;" />     * 对原始字符串进行编码转换，如果失败，返回原始的字符串<br style="clear: both;" />     * @param s 原始字符串<br style="clear: both;" />     * @param srcEncoding 源编码方式<br style="clear: both;" />     * @param destEncoding 目标编码方式<br style="clear: both;" />     * @return 转换编码后的字符串，失败返回原始字符串<br style="clear: both;" />     */<br style="clear: both;" />    public static String getString(String s, String srcEncoding, String destEncoding) {<br style="clear: both;" />        try {<br style="clear: both;" />            return new String(s.getBytes(srcEncoding), destEncoding);<br style="clear: both;" />        } catch (UnsupportedEncodingException e) {<br style="clear: both;" />            return s;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" />    <br style="clear: both;" />    /**<br style="clear: both;" />     * 根据某种编码方式将字节数组转换成字符串<br style="clear: both;" />     * @param b 字节数组<br style="clear: both;" />     * @param encoding 编码方式<br style="clear: both;" />     * @return 如果encoding不支持，返回一个缺省编码的字符串<br style="clear: both;" />     */<br style="clear: both;" />    public static String getString(byte[] b, String encoding) {<br style="clear: both;" />        try {<br style="clear: both;" />            return new String(b, encoding);<br style="clear: both;" />        } catch (UnsupportedEncodingException e) {<br style="clear: both;" />            return new String(b);<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" />    <br style="clear: both;" />    /**<br style="clear: both;" />     * 根据某种编码方式将字节数组转换成字符串<br style="clear: both;" />     * @param b 字节数组<br style="clear: both;" />     * @param offset 要转换的起始位置<br style="clear: both;" />     * @param len 要转换的长度<br style="clear: both;" />     * @param encoding 编码方式<br style="clear: both;" />     * @return 如果encoding不支持，返回一个缺省编码的字符串<br style="clear: both;" />     */<br style="clear: both;" />    public static String getString(byte[] b, int offset, int len, String encoding) {<br style="clear: both;" />        try {<br style="clear: both;" />            return new String(b, offset, len, encoding);<br style="clear: both;" />        } catch (UnsupportedEncodingException e) {<br style="clear: both;" />            return new String(b, offset, len);<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" />    <br style="clear: both;" />    /**<br style="clear: both;" />     * @param ip ip的字节数组形式<br style="clear: both;" />     * @return 字符串形式的ip<br style="clear: both;" />     */<br style="clear: both;" />    public static String getIpStringFromBytes(byte[] ip) {<br style="clear: both;" />        StringBuffer sb = new StringBuffer();<br style="clear: both;" />        sb.append(ip[0] &amp; 0xFF);<br style="clear: both;" />        sb.append('.');       <br style="clear: both;" />        sb.append(ip[1] &amp; 0xFF);<br style="clear: both;" />        sb.append('.');       <br style="clear: both;" />        sb.append(ip[2] &amp; 0xFF);<br style="clear: both;" />        sb.append('.');       <br style="clear: both;" />        sb.append(ip[3] &amp; 0xFF);<br style="clear: both;" />        return sb.toString();<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />}<span class="Apple-converted-space"> </span><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />三、IPSeeker.java<br style="clear: both;" /><br style="clear: both;" />/*<br style="clear: both;" />* LumaQQ - Java QQ Client<br style="clear: both;" />*<br style="clear: both;" />* Copyright (C) 2004 luma &lt; stubma@163.com&gt;<br style="clear: both;" />*<br style="clear: both;" />* This program is free software; you can redistribute it and/or modify<br style="clear: both;" />* it under the terms of the GNU General Public License as published by<br style="clear: both;" />* the Free Software Foundation; either version 2 of the License, or<br style="clear: both;" />* (at your option) any later version.<br style="clear: both;" />*<br style="clear: both;" />* This program is distributed in the hope that it will be useful,<br style="clear: both;" />* but WITHOUT ANY WARRANTY; without even the implied warranty of<br style="clear: both;" />* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br style="clear: both;" />* GNU General Public License for more details.<br style="clear: both;" />*<br style="clear: both;" />* You should have received a copy of the GNU General Public License<br style="clear: both;" />* along with this program; if not, write to the Free Software<br style="clear: both;" />* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br style="clear: both;" />*/<br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />import java.io.FileNotFoundException;<br style="clear: both;" />import java.io.IOException;<br style="clear: both;" />import java.io.RandomAccessFile;<br style="clear: both;" />import java.nio.ByteOrder;<br style="clear: both;" />import java.nio.MappedByteBuffer;<br style="clear: both;" />import java.nio.channels.FileChannel;<br style="clear: both;" />import java.util.ArrayList;<br style="clear: both;" />import java.util.Hashtable;<br style="clear: both;" />import java.util.List;<br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" /><br style="clear: both;" />/**<br style="clear: both;" />*  * 用来读取QQwry.dat文件，以根据ip获得好友位置，QQwry.dat的格式是<br style="clear: both;" />* 一. 文件头，共8字节<br style="clear: both;" />*        1. 第一个起始IP的绝对偏移， 4字节<br style="clear: both;" />*     2. 最后一个起始IP的绝对偏移， 4字节<br style="clear: both;" />* 二. "结束地址/国家/区域"记录区<br style="clear: both;" />*     四字节ip地址后跟的每一条记录分成两个部分<br style="clear: both;" />*     1. 国家记录<br style="clear: both;" />*     2. 地区记录<br style="clear: both;" />*     但是地区记录是不一定有的。而且国家记录和地区记录都有两种形式<br style="clear: both;" />*     1. 以0结束的字符串<br style="clear: both;" />*     2. 4个字节，一个字节可能为0x1或0x2<br style="clear: both;" />*           a. 为0x1时，表示在绝对偏移后还跟着一个区域的记录，注意是绝对偏移之后，而不是这四个字节之后<br style="clear: both;" />*        b. 为0x2时，表示在绝对偏移后没有区域记录<br style="clear: both;" />*        不管为0x1还是0x2，后三个字节都是实际国家名的文件内绝对偏移<br style="clear: both;" />*           如果是地区记录，0x1和0x2的含义不明，但是如果出现这两个字节，也肯定是跟着3个字节偏移，如果不是<br style="clear: both;" />*        则为0结尾字符串<br style="clear: both;" />* 三. "起始地址/结束地址偏移"记录区<br style="clear: both;" />*     1. 每条记录7字节，按照起始地址从小到大排列<br style="clear: both;" />*        a. 起始IP地址，4字节<br style="clear: both;" />*        b. 结束ip地址的绝对偏移，3字节<br style="clear: both;" />*<br style="clear: both;" />* 注意，这个文件里的ip地址和所有的偏移量均采用little-endian格式，而java是采用<br style="clear: both;" />* big-endian格式的，要注意转换<br style="clear: both;" />*<span class="Apple-converted-space"> </span><br style="clear: both;" />*<br style="clear: both;" />* @author 马若劼<br style="clear: both;" />*/<br style="clear: both;" />public class IPSeeker {<br style="clear: both;" />    /**<br style="clear: both;" />     *      * 用来封装ip相关信息，目前只有两个字段，ip所在的国家和地区<br style="clear: both;" />     *<span class="Apple-converted-space"> </span><br style="clear: both;" />     *<br style="clear: both;" />     * @author 马若劼<br style="clear: both;" />     */<br style="clear: both;" />    private class IPLocation {<br style="clear: both;" />        public String country;<br style="clear: both;" />        public String area;<br style="clear: both;" /><br style="clear: both;" />        public IPLocation() {<br style="clear: both;" />            country = area = "";<br style="clear: both;" />        }<br style="clear: both;" /><br style="clear: both;" />        public IPLocation getCopy() {<br style="clear: both;" />            IPLocation ret = new IPLocation();<br style="clear: both;" />            ret.country = country;<br style="clear: both;" />            ret.area = area;<br style="clear: both;" />            return ret;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    private static final String IP_FILE = IPSeeker.class.getResource("/QQWry.dat").toString().substring(5);<br style="clear: both;" /><br style="clear: both;" />    // 一些固定常量，比如记录长度等等<br style="clear: both;" />    private static final int IP_RECORD_LENGTH = 7;<br style="clear: both;" />    private static final byte AREA_FOLLOWED = 0x01;<br style="clear: both;" />    private static final byte NO_AREA = 0x2;<br style="clear: both;" /><br style="clear: both;" />    // 用来做为cache，查询一个ip时首先查看cache，以减少不必要的重复查找<br style="clear: both;" />    private Hashtable ipCache;<br style="clear: both;" />    // 随机文件访问类<br style="clear: both;" />    private RandomAccessFile ipFile;<br style="clear: both;" />    // 内存映射文件<br style="clear: both;" />    private MappedByteBuffer mbb;<br style="clear: both;" />    // 单一模式实例<br style="clear: both;" />    private static IPSeeker instance = new IPSeeker();<br style="clear: both;" />    // 起始地区的开始和结束的绝对偏移<br style="clear: both;" />    private long ipBegin, ipEnd;<br style="clear: both;" />    // 为提高效率而采用的临时变量<br style="clear: both;" />    private IPLocation loc;<br style="clear: both;" />    private byte[] buf;<br style="clear: both;" />    private byte[] b4;<br style="clear: both;" />    private byte[] b3;<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 私有构造函数<br style="clear: both;" />     */<br style="clear: both;" />    private IPSeeker()  {<br style="clear: both;" />        ipCache = new Hashtable();<br style="clear: both;" />        loc = new IPLocation();<br style="clear: both;" />        buf = new byte[100];<br style="clear: both;" />        b4 = new byte[4];<br style="clear: both;" />        b3 = new byte[3];<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile = new RandomAccessFile(IP_FILE, "r");<br style="clear: both;" />        } catch (FileNotFoundException e) {<br style="clear: both;" />                        System.out.println(IPSeeker.class.getResource("/QQWry.dat").toString());<br style="clear: both;" />                        System.out.println(IP_FILE);<br style="clear: both;" />            System.out.println("IP地址信息文件没有找到，IP显示功能将无法使用");<br style="clear: both;" />            ipFile = null;<br style="clear: both;" /><br style="clear: both;" />        }<br style="clear: both;" />        // 如果打开文件成功，读取文件头信息<br style="clear: both;" />        if(ipFile != null) {<br style="clear: both;" />            try {<br style="clear: both;" />                ipBegin = readLong4(0);<br style="clear: both;" />                ipEnd = readLong4(4);<br style="clear: both;" />                if(ipBegin == -1 || ipEnd == -1) {<br style="clear: both;" />                    ipFile.close();<br style="clear: both;" />                    ipFile = null;<br style="clear: both;" />                }<br style="clear: both;" />            } catch (IOException e) {<br style="clear: both;" />                System.out.println("IP地址信息文件格式有错误，IP显示功能将无法使用");<br style="clear: both;" />                ipFile = null;<br style="clear: both;" />            }<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * @return 单一实例<br style="clear: both;" />     */<br style="clear: both;" />    public static IPSeeker getInstance() {<br style="clear: both;" />        return instance;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 给定一个地点的不完全名字，得到一系列包含s子串的IP范围记录<br style="clear: both;" />     * @param s 地点子串<br style="clear: both;" />     * @return 包含IPEntry类型的List<br style="clear: both;" />     */<br style="clear: both;" />    public List getIPEntriesDebug(String s) {<br style="clear: both;" />        List ret = new ArrayList();<br style="clear: both;" />        long endOffset = ipEnd + 4;<br style="clear: both;" />        for(long offset = ipBegin + 4; offset &lt;= endOffset; offset += IP_RECORD_LENGTH) {<br style="clear: both;" />            // 读取结束IP偏移<br style="clear: both;" />            long temp = readLong3(offset);<br style="clear: both;" />            // 如果temp不等于-1，读取IP的地点信息<br style="clear: both;" />            if(temp != -1) {<br style="clear: both;" />                IPLocation loc = getIPLocation(temp);<br style="clear: both;" />                // 判断是否这个地点里面包含了s子串，如果包含了，添加这个记录到List中，如果没有，继续<br style="clear: both;" />                if(loc.country.indexOf(s) != -1 || loc.area.indexOf(s) != -1) {<br style="clear: both;" />                    IPEntry entry = new IPEntry();<br style="clear: both;" />                    entry.country = loc.country;<br style="clear: both;" />                    entry.area = loc.area;<br style="clear: both;" />                    // 得到起始IP<br style="clear: both;" />                    readIP(offset - 4, b4);<br style="clear: both;" />                    entry.beginIp = Utils.getIpStringFromBytes(b4);<br style="clear: both;" />                    // 得到结束IP<br style="clear: both;" />                    readIP(temp, b4);<br style="clear: both;" />                    entry.endIp = Utils.getIpStringFromBytes(b4);<br style="clear: both;" />                    // 添加该记录<br style="clear: both;" />                    ret.add(entry);<br style="clear: both;" />                }<br style="clear: both;" />            }<br style="clear: both;" />        }<br style="clear: both;" />        return ret;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 给定一个地点的不完全名字，得到一系列包含s子串的IP范围记录<br style="clear: both;" />     * @param s 地点子串<br style="clear: both;" />     * @return 包含IPEntry类型的List<br style="clear: both;" />     */<br style="clear: both;" />    public List getIPEntries(String s) {<br style="clear: both;" />        List ret = new ArrayList();<br style="clear: both;" />        try {<br style="clear: both;" />            // 映射IP信息文件到内存中<br style="clear: both;" />            if(mbb == null) {<br style="clear: both;" />                FileChannel fc = ipFile.getChannel();<br style="clear: both;" />                mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length());<br style="clear: both;" />                mbb.order(ByteOrder.LITTLE_ENDIAN);<br style="clear: both;" />            }<br style="clear: both;" /><br style="clear: both;" />            int endOffset = (int)ipEnd;<br style="clear: both;" />            for(int offset = (int)ipBegin + 4; offset &lt;= endOffset; offset += IP_RECORD_LENGTH) {<br style="clear: both;" />                int temp = readInt3(offset);<br style="clear: both;" />                if(temp != -1) {<br style="clear: both;" />                    IPLocation loc = getIPLocation(temp);<br style="clear: both;" />                    // 判断是否这个地点里面包含了s子串，如果包含了，添加这个记录到List中，如果没有，继续<br style="clear: both;" />                    if(loc.country.indexOf(s) != -1 || loc.area.indexOf(s) != -1) {<br style="clear: both;" />                        IPEntry entry = new IPEntry();<br style="clear: both;" />                        entry.country = loc.country;<br style="clear: both;" />                        entry.area = loc.area;<br style="clear: both;" />                        // 得到起始IP<br style="clear: both;" />                        readIP(offset - 4, b4);<br style="clear: both;" />                        entry.beginIp = Utils.getIpStringFromBytes(b4);<br style="clear: both;" />                        // 得到结束IP<br style="clear: both;" />                        readIP(temp, b4);<br style="clear: both;" />                        entry.endIp = Utils.getIpStringFromBytes(b4);<br style="clear: both;" />                        // 添加该记录<br style="clear: both;" />                        ret.add(entry);<br style="clear: both;" />                    }<br style="clear: both;" />                }<br style="clear: both;" />            }<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            System.out.println(e.getMessage());<br style="clear: both;" />        }<br style="clear: both;" />        return ret;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从内存映射文件的offset位置开始的3个字节读取一个int<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private int readInt3(int offset) {<br style="clear: both;" />        mbb.position(offset);<br style="clear: both;" />        return mbb.getInt() &amp; 0x00FFFFFF;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从内存映射文件的当前位置开始的3个字节读取一个int<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private int readInt3() {<br style="clear: both;" />        return mbb.getInt() &amp; 0x00FFFFFF;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 根据IP得到国家名<br style="clear: both;" />     * @param ip ip的字节数组形式<br style="clear: both;" />     * @return 国家名字符串<br style="clear: both;" />     */<br style="clear: both;" />    public String getCountry(byte[] ip) {<br style="clear: both;" />        // 检查ip地址文件是否正常<br style="clear: both;" />        if(ipFile == null) return "错误的IP数据库文件";<br style="clear: both;" />        // 保存ip，转换ip字节数组为字符串形式<br style="clear: both;" />        String ipStr = Utils.getIpStringFromBytes(ip);<br style="clear: both;" />        // 先检查cache中是否已经包含有这个ip的结果，没有再搜索文件<br style="clear: both;" />        if(ipCache.containsKey(ipStr)) {<br style="clear: both;" />            IPLocation loc = (IPLocation)ipCache.get(ipStr);<br style="clear: both;" />            return loc.country;<br style="clear: both;" />        } else {<br style="clear: both;" />            IPLocation loc = getIPLocation(ip);<br style="clear: both;" />            ipCache.put(ipStr, loc.getCopy());<br style="clear: both;" />            return loc.country;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 根据IP得到国家名<br style="clear: both;" />     * @param ip IP的字符串形式<br style="clear: both;" />     * @return 国家名字符串<br style="clear: both;" />     */<br style="clear: both;" />    public String getCountry(String ip) {<br style="clear: both;" />        return getCountry(Utils.getIpByteArrayFromString(ip));<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 根据IP得到地区名<br style="clear: both;" />     * @param ip ip的字节数组形式<br style="clear: both;" />     * @return 地区名字符串<br style="clear: both;" />     */<br style="clear: both;" />    public String getArea(byte[] ip) {<br style="clear: both;" />        // 检查ip地址文件是否正常<br style="clear: both;" />        if(ipFile == null) return "错误的IP数据库文件";<br style="clear: both;" />        // 保存ip，转换ip字节数组为字符串形式<br style="clear: both;" />        String ipStr = Utils.getIpStringFromBytes(ip);<br style="clear: both;" />        // 先检查cache中是否已经包含有这个ip的结果，没有再搜索文件<br style="clear: both;" />        if(ipCache.containsKey(ipStr)) {<br style="clear: both;" />            IPLocation loc = (IPLocation)ipCache.get(ipStr);<br style="clear: both;" />            return loc.area;<br style="clear: both;" />        } else {<br style="clear: both;" />            IPLocation loc = getIPLocation(ip);<br style="clear: both;" />            ipCache.put(ipStr, loc.getCopy());<br style="clear: both;" />            return loc.area;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 根据IP得到地区名<br style="clear: both;" />     * @param ip IP的字符串形式<br style="clear: both;" />     * @return 地区名字符串<br style="clear: both;" />     */<br style="clear: both;" />    public String getArea(String ip) {<br style="clear: both;" />        return getArea(Utils.getIpByteArrayFromString(ip));<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 根据ip搜索ip信息文件，得到IPLocation结构，所搜索的ip参数从类成员ip中得到<br style="clear: both;" />     * @param ip 要查询的IP<br style="clear: both;" />     * @return IPLocation结构<br style="clear: both;" />     */<br style="clear: both;" />    private IPLocation getIPLocation(byte[] ip) {<br style="clear: both;" />        IPLocation info = null;<br style="clear: both;" />        long offset = locateIP(ip);<br style="clear: both;" />        if(offset != -1)<br style="clear: both;" />            info = getIPLocation(offset);<br style="clear: both;" />        if(info == null) {<br style="clear: both;" />            info = new IPLocation();<br style="clear: both;" />            info.country = "未知国家";<br style="clear: both;" />            info.area = "未知地区";<br style="clear: both;" />        }<br style="clear: both;" />        return info;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset位置读取4个字节为一个long，因为java为big-endian格式，所以没办法<br style="clear: both;" />     * 用了这么一个函数来做转换<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return 读取的long值，返回-1表示读取文件失败<br style="clear: both;" />     */<br style="clear: both;" />    private long readLong4(long offset) {<br style="clear: both;" />        long ret = 0;<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile.seek(offset);<br style="clear: both;" />            ret |= (ipFile.readByte() &amp; 0xFF);<br style="clear: both;" />            ret |= ((ipFile.readByte() &lt;&lt; 8) &amp; 0xFF00);<br style="clear: both;" />            ret |= ((ipFile.readByte() &lt;&lt; 16) &amp; 0xFF0000);<br style="clear: both;" />            ret |= ((ipFile.readByte() &lt;&lt; 24) &amp; 0xFF000000);<br style="clear: both;" />            return ret;<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            return -1;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset位置读取3个字节为一个long，因为java为big-endian格式，所以没办法<br style="clear: both;" />     * 用了这么一个函数来做转换<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return 读取的long值，返回-1表示读取文件失败<br style="clear: both;" />     */<br style="clear: both;" />    private long readLong3(long offset) {<br style="clear: both;" />        long ret = 0;<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile.seek(offset);<br style="clear: both;" />            ipFile.readFully(b3);<br style="clear: both;" />            ret |= (b3[0] &amp; 0xFF);<br style="clear: both;" />            ret |= ((b3[1] &lt;&lt; 8) &amp; 0xFF00);<br style="clear: both;" />            ret |= ((b3[2] &lt;&lt; 16) &amp; 0xFF0000);<br style="clear: both;" />            return ret;<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            return -1;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从当前位置读取3个字节转换成long<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private long readLong3() {<br style="clear: both;" />        long ret = 0;<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile.readFully(b3);<br style="clear: both;" />            ret |= (b3[0] &amp; 0xFF);<br style="clear: both;" />            ret |= ((b3[1] &lt;&lt; 8) &amp; 0xFF00);<br style="clear: both;" />            ret |= ((b3[2] &lt;&lt; 16) &amp; 0xFF0000);<br style="clear: both;" />            return ret;<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            return -1;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset位置读取四个字节的ip地址放入ip数组中，读取后的ip为big-endian格式，但是<br style="clear: both;" />     * 文件中是little-endian形式，将会进行转换<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @param ip<br style="clear: both;" />     */<br style="clear: both;" />    private void readIP(long offset, byte[] ip) {<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile.seek(offset);<br style="clear: both;" />            ipFile.readFully(ip);<br style="clear: both;" />            byte temp = ip[0];<br style="clear: both;" />            ip[0] = ip[3];<br style="clear: both;" />            ip[3] = temp;<br style="clear: both;" />            temp = ip[1];<br style="clear: both;" />            ip[1] = ip[2];<br style="clear: both;" />            ip[2] = temp;<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            System.out.println(e.getMessage());<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset位置读取四个字节的ip地址放入ip数组中，读取后的ip为big-endian格式，但是<br style="clear: both;" />     * 文件中是little-endian形式，将会进行转换<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @param ip<br style="clear: both;" />     */<br style="clear: both;" />    private void readIP(int offset, byte[] ip) {<br style="clear: both;" />        mbb.position(offset);<br style="clear: both;" />        mbb.get(ip);<br style="clear: both;" />        byte temp = ip[0];<br style="clear: both;" />        ip[0] = ip[3];<br style="clear: both;" />        ip[3] = temp;<br style="clear: both;" />        temp = ip[1];<br style="clear: both;" />        ip[1] = ip[2];<br style="clear: both;" />        ip[2] = temp;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 把类成员ip和beginIp比较，注意这个beginIp是big-endian的<br style="clear: both;" />     * @param ip 要查询的IP<br style="clear: both;" />     * @param beginIp 和被查询IP相比较的IP<br style="clear: both;" />     * @return 相等返回0，ip大于beginIp则返回1，小于返回-1。<br style="clear: both;" />     */<br style="clear: both;" />    private int compareIP(byte[] ip, byte[] beginIp) {<br style="clear: both;" />        for(int i = 0; i &lt; 4; i++) {<br style="clear: both;" />            int r = compareByte(ip[i], beginIp[i]);<br style="clear: both;" />            if(r != 0)<br style="clear: both;" />                return r;<br style="clear: both;" />        }<br style="clear: both;" />        return 0;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 把两个byte当作无符号数进行比较<br style="clear: both;" />     * @param b1<br style="clear: both;" />     * @param b2<br style="clear: both;" />     * @return 若b1大于b2则返回1，相等返回0，小于返回-1<br style="clear: both;" />     */<br style="clear: both;" />    private int compareByte(byte b1, byte b2) {<br style="clear: both;" />        if((b1 &amp; 0xFF) &gt; (b2 &amp; 0xFF)) // 比较是否大于<br style="clear: both;" />            return 1;<br style="clear: both;" />        else if((b1 ^ b2) == 0)// 判断是否相等<br style="clear: both;" />            return 0;<br style="clear: both;" />        else<br style="clear: both;" />            return -1;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 这个方法将根据ip的内容，定位到包含这个ip国家地区的记录处，返回一个绝对偏移<br style="clear: both;" />     * 方法使用二分法查找。<br style="clear: both;" />     * @param ip 要查询的IP<br style="clear: both;" />     * @return 如果找到了，返回结束IP的偏移，如果没有找到，返回-1<br style="clear: both;" />     */<br style="clear: both;" />    private long locateIP(byte[] ip) {<br style="clear: both;" />        long m = 0;<br style="clear: both;" />        int r;<br style="clear: both;" />        // 比较第一个ip项<br style="clear: both;" />        readIP(ipBegin, b4);<br style="clear: both;" />        r = compareIP(ip, b4);<br style="clear: both;" />        if(r == 0) return ipBegin;<br style="clear: both;" />        else if(r &lt; 0) return -1;<br style="clear: both;" />        // 开始二分搜索<br style="clear: both;" />        for(long i = ipBegin, j = ipEnd; i &lt; j; ) {<br style="clear: both;" />            m = getMiddleOffset(i, j);<br style="clear: both;" />            readIP(m, b4);<br style="clear: both;" />            r = compareIP(ip, b4);<br style="clear: both;" />            // log.debug(Utils.getIpStringFromBytes(b));<br style="clear: both;" />            if(r &gt; 0)<br style="clear: both;" />                i = m;<br style="clear: both;" />            else if(r &lt; 0) {<br style="clear: both;" />                if(m == j) {<br style="clear: both;" />                    j -= IP_RECORD_LENGTH;<br style="clear: both;" />                    m = j;<br style="clear: both;" />                } else<br style="clear: both;" />                    j = m;<br style="clear: both;" />            } else<br style="clear: both;" />                return readLong3(m + 4);<br style="clear: both;" />        }<br style="clear: both;" />        // 如果循环结束了，那么i和j必定是相等的，这个记录为最可能的记录，但是并非<br style="clear: both;" />        //     肯定就是，还要检查一下，如果是，就返回结束地址区的绝对偏移<br style="clear: both;" />        m = readLong3(m + 4);<br style="clear: both;" />        readIP(m, b4);<br style="clear: both;" />        r = compareIP(ip, b4);<br style="clear: both;" />        if(r &lt;= 0) return m;<br style="clear: both;" />        else return -1;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 得到begin偏移和end偏移中间位置记录的偏移<br style="clear: both;" />     * @param begin<br style="clear: both;" />     * @param end<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private long getMiddleOffset(long begin, long end) {<br style="clear: both;" />        long records = (end - begin) / IP_RECORD_LENGTH;<br style="clear: both;" />        records &gt;&gt;= 1;<br style="clear: both;" />        if(records == 0) records = 1;<br style="clear: both;" />        return begin + records * IP_RECORD_LENGTH;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 给定一个ip国家地区记录的偏移，返回一个IPLocation结构<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private IPLocation getIPLocation(long offset) {<br style="clear: both;" />        try {<br style="clear: both;" />            // 跳过4字节ip<br style="clear: both;" />            ipFile.seek(offset + 4);<br style="clear: both;" />            // 读取第一个字节判断是否标志字节<br style="clear: both;" />            byte b = ipFile.readByte();<br style="clear: both;" />            if(b == AREA_FOLLOWED) {<br style="clear: both;" />                // 读取国家偏移<br style="clear: both;" />                long countryOffset = readLong3();<br style="clear: both;" />                // 跳转至偏移处<br style="clear: both;" />                ipFile.seek(countryOffset);<br style="clear: both;" />                // 再检查一次标志字节，因为这个时候这个地方仍然可能是个重定向<br style="clear: both;" />                b = ipFile.readByte();<br style="clear: both;" />                if(b == NO_AREA) {<br style="clear: both;" />                    loc.country = readString(readLong3());<br style="clear: both;" />                    ipFile.seek(countryOffset + 4);<br style="clear: both;" />                } else<br style="clear: both;" />                    loc.country = readString(countryOffset);<br style="clear: both;" />                // 读取地区标志<br style="clear: both;" />                loc.area = readArea(ipFile.getFilePointer());<br style="clear: both;" />            } else if(b == NO_AREA) {<br style="clear: both;" />                loc.country = readString(readLong3());<br style="clear: both;" />                loc.area = readArea(offset + 8);<br style="clear: both;" />            } else {<br style="clear: both;" />                loc.country = readString(ipFile.getFilePointer() - 1);<br style="clear: both;" />                loc.area = readArea(ipFile.getFilePointer());<br style="clear: both;" />            }<br style="clear: both;" />            return loc;<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            return null;<br style="clear: both;" />        }<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private IPLocation getIPLocation(int offset) {<br style="clear: both;" />        // 跳过4字节ip<br style="clear: both;" />        mbb.position(offset + 4);<br style="clear: both;" />        // 读取第一个字节判断是否标志字节<br style="clear: both;" />        byte b = mbb.get();<br style="clear: both;" />        if(b == AREA_FOLLOWED) {<br style="clear: both;" />            // 读取国家偏移<br style="clear: both;" />            int countryOffset = readInt3();<br style="clear: both;" />            // 跳转至偏移处<br style="clear: both;" />            mbb.position(countryOffset);<br style="clear: both;" />            // 再检查一次标志字节，因为这个时候这个地方仍然可能是个重定向<br style="clear: both;" />            b = mbb.get();<br style="clear: both;" />            if(b == NO_AREA) {<br style="clear: both;" />                loc.country = readString(readInt3());<br style="clear: both;" />                mbb.position(countryOffset + 4);<br style="clear: both;" />            } else<br style="clear: both;" />                loc.country = readString(countryOffset);<br style="clear: both;" />            // 读取地区标志<br style="clear: both;" />            loc.area = readArea(mbb.position());<br style="clear: both;" />        } else if(b == NO_AREA) {<br style="clear: both;" />            loc.country = readString(readInt3());<br style="clear: both;" />            loc.area = readArea(offset + 8);<br style="clear: both;" />        } else {<br style="clear: both;" />            loc.country = readString(mbb.position() - 1);<br style="clear: both;" />            loc.area = readArea(mbb.position());<br style="clear: both;" />        }<br style="clear: both;" />        return loc;<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset偏移开始解析后面的字节，读出一个地区名<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return 地区名字符串<br style="clear: both;" />     * @throws IOException<br style="clear: both;" />     */<br style="clear: both;" />    private String readArea(long offset) throws IOException {<br style="clear: both;" />        ipFile.seek(offset);<br style="clear: both;" />        byte b = ipFile.readByte();<br style="clear: both;" />        if(b == 0x01 || b == 0x02) {<br style="clear: both;" />            long areaOffset = readLong3(offset + 1);<br style="clear: both;" />            if(areaOffset == 0)<br style="clear: both;" />                return "未知地区";<br style="clear: both;" />            else<br style="clear: both;" />                return readString(areaOffset);<br style="clear: both;" />        } else<br style="clear: both;" />            return readString(offset);<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private String readArea(int offset) {<br style="clear: both;" />        mbb.position(offset);<br style="clear: both;" />        byte b = mbb.get();<br style="clear: both;" />        if(b == 0x01 || b == 0x02) {<br style="clear: both;" />            int areaOffset = readInt3();<br style="clear: both;" />            if(areaOffset == 0)<br style="clear: both;" />                return "未知地区";<br style="clear: both;" />            else<br style="clear: both;" />                return readString(areaOffset);<br style="clear: both;" />        } else<br style="clear: both;" />            return readString(offset);<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从offset偏移处读取一个以0结束的字符串<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return 读取的字符串，出错返回空字符串<br style="clear: both;" />     */<br style="clear: both;" />    private String readString(long offset) {<br style="clear: both;" />        try {<br style="clear: both;" />            ipFile.seek(offset);<br style="clear: both;" />            int i;<br style="clear: both;" />            for(i = 0, buf[i] = ipFile.readByte(); buf[i] != 0; buf[++i] = ipFile.readByte());<br style="clear: both;" />            if(i != 0)<br style="clear: both;" />                return Utils.getString(buf, 0, i, "GBK");<br style="clear: both;" />        } catch (IOException e) {<br style="clear: both;" />            System.out.println(e.getMessage());<br style="clear: both;" />        }<br style="clear: both;" />        return "";<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    /**<br style="clear: both;" />     * 从内存映射文件的offset位置得到一个0结尾字符串<br style="clear: both;" />     * @param offset<br style="clear: both;" />     * @return<br style="clear: both;" />     */<br style="clear: both;" />    private String readString(int offset) {<br style="clear: both;" />        try {<br style="clear: both;" />            mbb.position(offset);<br style="clear: both;" />            int i;<br style="clear: both;" />            for(i = 0, buf[i] = mbb.get(); buf[i] != 0; buf[++i] = mbb.get());<br style="clear: both;" />            if(i != 0)<br style="clear: both;" />                return Utils.getString(buf, 0, i, "GBK");<br style="clear: both;" />        } catch (IllegalArgumentException e) {<br style="clear: both;" />            System.out.println(e.getMessage());<br style="clear: both;" />        }<br style="clear: both;" />        return "";<br style="clear: both;" />    }<br style="clear: both;" /><br style="clear: both;" />    public String getAddress(String ip){<br style="clear: both;" />        String country = getCountry(ip).equals(" CZ88.NET")?"":getCountry(ip);<br style="clear: both;" />        String area = getArea(ip).equals(" CZ88.NET")?"":getArea(ip);<br style="clear: both;" />        String address = country+" "+area;<br style="clear: both;" />        return address.trim();<br style="clear: both;" />    }<br style="clear: both;" />}</span>
		</span>
<img src ="http://www.blogjava.net/libin2722/aggbug/338543.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2010-11-20 14:23 <a href="http://www.blogjava.net/libin2722/articles/338543.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图片截取和缩略</title><link>http://www.blogjava.net/libin2722/articles/338536.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 20 Nov 2010 04:26:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/338536.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/338536.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/338536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/338536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/338536.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: package												 com.supben.util;  																																				  																																						import												 java.awt.Dimension;  																				...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/338536.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/338536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2010-11-20 12:26 <a href="http://www.blogjava.net/libin2722/articles/338536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>spring任务调度方法之Quartz</title><link>http://www.blogjava.net/libin2722/articles/336753.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Tue, 02 Nov 2010 00:52:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/336753.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/336753.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/336753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/336753.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/336753.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、Quartz简介						 												    Quartz是一个开放源码项目，专注于任务调度器，提供了极为广泛的特性如持久化任务，集群和分布式任务等。Spring对Quartz的集成与其对JDK Timer的集成在任务、触发器和调度计划的声明式配置方面等都非常相似。     Quartz的核心由两个接口和两个类组成：Job和Scheduler接口，JobDetail...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/336753.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/336753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2010-11-02 08:52 <a href="http://www.blogjava.net/libin2722/articles/336753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JMeter进行性能测试</title><link>http://www.blogjava.net/libin2722/articles/294573.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 10 Sep 2009 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/294573.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/294573.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/294573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/294573.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/294573.html</trackback:ping><description><![CDATA[
		<blockquote>JMeter 是 Apache 组织的开放源代码项目，它是功能和性能测试的工具，100%的用java实现，最新的版本是1.9.1。本文中作者将向大家介绍如何使用 JMeter 进行测试。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>JMeter是Apache组织的开放源代码项目，它是功能和性能测试的工具，100%的用java实现，最新的版本是1.9.1，大家可以到
        <a href="http://jakarta.apache.org/jmeter/index.html">http://jakarta.apache.org/jmeter/index.html</a>下载源代码和查看相关文档。
      </p>
		<p>
				<a name="1">
						<span class="atitle">JMeter作用领域</span>
				</a>
		</p>
		<p>
		</p>
		<p>JMeter
可以用于测试静态或者动态资源的性能（文件、Servlets、Perl脚本、java对象、数据库和查询、ftp服务器或者其他的资源）。JMeter
用于模拟在服务器、网络或者其他对象上附加高负载以测试他们提供服务的受压能力，或者分析他们提供的服务在不同负载条件下的总性能情况。你可以用
JMeter提供的图形化界面分析性能指标或者在高负载情况下测试服务器/脚本/对象的行为。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www.ibm.com/developerworks/cn/java/l-jmeter/index.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">使用JMeter测试Web应用</span>
				</a>
		</p>
		<p>
		</p>
		<p>接下来的章节里，作者将详细的演示如何使用JMeter来测试Web应用的完整过程。</p>
		<p>
				<a name="N1005C">
						<span class="smalltitle">2.1	测试环境</span>
				</a>
		</p>
		<p>
		</p>
		<p>作
者使用了Tomcat作为Web服务器进行测试，被测试的内容是一个jsp文件和一个servlet，jsp文件调用JavaBean、打印相关信
息，servlet接受用户参数、调用javabean、输出相关信息。详细的内容请参考作者提供的JMeter.war的内容。</p>
		<p>
				<a name="N10067">
						<span class="smalltitle">2.2	安装启动JMeter</span>
				</a>
		</p>
		<p>
		</p>
		<p>大
家可以到通过http://apache.linuxforum.net/dist/jakarta/jmeter/binaries/jakarta-
jmeter-1.9.1.zip下载JMeter的release版本，然后将下载的.zip文件解压缩到C:/JMeter（后面的文章中将使
用%JMeter%来引用这个目录）目录下。</p>
		<p>现在，请使用%JMeter%/bin下面的jmeter.bat批处理文件来启动JMeter的可视化界面，下面的工作都将在这个可视化界面界面上进行操作。下面的图片是JMeter的可视化界面的屏幕截图。</p>
		<br />
		<a name="N10077">
				<b>图一： JMeter打开时的屏幕截图</b>
		</a>
		<br />
		<img alt="图一： JMeter打开时的屏幕截图" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image001.png" height="371" width="408" />
		<br />
		<p>
				<a name="N10084">
						<span class="smalltitle">2.3	建立测试计划（Test Plan）</span>
				</a>
		</p>
		<p>
		</p>
		<p>测
试计划描述了执行测试过程中JMeter的执行过程和步骤，一个完整的测试计划包括一个或者多个线程组(Thread
Groups)、逻辑控制（Logic Controller）、实例产生控制器（Sample Generating
Controllers）、侦听器(Listener)、定时器（Timer）、比较（Assertions）、配置元素（Config
Elements）。打开JMeter时，它已经建立一个默认的测试计划,一个JMeter应用的实例只能建立或者打开一个测试计划。</p>
		<p>现在我们开始填充一个测试计划的内容，这个测试计划向一个jsp文件和一个servlet发出请求，我们需要JMeter模拟五个请求者（也就是五个线程），每个请求者连续请求两次，下面的章节介绍了详细的操作步骤。</p>
		<p>
				<a name="N10092">
						<span class="smalltitle">2.4	增加负载信息设置</span>
				</a>
		</p>
		<p>
		</p>
		<p>这一步，我们将向测试计划中增加相关负载设置,是Jmeter知道我们需要模拟五个请求者，每个请求者在测试过程中连续请求两次。详细步骤如下：</p>
		<p>1.	选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'Thread Group，界面右边将会出现他的设置信息框。</p>
		<p>2.	Thread Group有三个和负载信息相关的参数：
        <br />
Number of Threads： 设置发送请求的用户数目
        <br />
Ramp-up period：   每个请求发生的总时间间隔，单位是秒。比如你的请求数目是5，而这个参数是10，那么每个请求之间的间隔就是10／5，也就是2秒
        <br />
Loop Count：      请求发生的重复次数，如果选择后面的forever（默认），那么		请求将一直继续，如果不选择forever，而在输入框中输入数字，那么请求将重复		指定的次数，如果输入0，那么请求将执行一次。
      </p>
		<p>根据我们演示例子的设计，我们应该将Number of Threads设置为5，Ramp-up period设置为0（也就是同时并发请求），不选中forever，在Loop Count后面的输入框中输入2，设置后的屏幕截图如下：</p>
		<br />
		<a name="N100AE">
				<b>图二：设置好参数的Thread Group。</b>
		</a>
		<br />
		<img alt="图二：设置好参数的Thread Group。" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image003.png" height="218" width="447" />
		<br />
		<p>
				<a name="N100BB">
						<span class="smalltitle">2.5	增加默认Http属性（可选）</span>
				</a>
		</p>
		<p>
		</p>
		<p>实际的测试工作往往是针对同一个服务器上Web应用展开的,所以Jmeter提供了这样一种设置, 在默认Http属性设置需要被测试服务器的相关属性，以后的http请求设置中就可以忽略这些相同参数的设置,减少设置参数录入的时间。</p>
		<p>我们这里将采用这种属性。你可以通过下面的步骤来设置默认http属性：</p>
		<p>1.	选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'config element'http request defaults，界面右边将会出现他的设置信息框。</p>
		<p>2.	默认http属性的主要参数说明如下：
        <br />
protocal：发送测试请求时使用的协议
        <br />
server name or ip：被测试服务器的ip地址或者名字
        <br />
path： 默认的起始位置。比如将path设置为／jmeter，那么所有的http请求的url中都将增加／jmeter路径。
        <br />
port number： 服务器提供服务的端口号
      </p>
		<p>我
们的测试计划将针对本机的Web服务器上的Web应用进行测试，所以protocal应该是http，ip使用localhost，因为这个web应用发
布的context路径是／jmeter，所以这里的path设置为／jmeter，因为使用Tomcat服务器，所以port
number是8080。设置后的屏幕截图如下：</p>
		<br />
		<a name="N100DC">
				<b>图三： 测试计划中使用的默认Http参数</b>
		</a>
		<br />
		<img alt="图三： 测试计划中使用的默认Http参数" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image005.png" height="176" width="500" />
		<br />
		<p>
				<a name="N100E9">
						<span class="smalltitle">2.6	增加Http请求</span>
				</a>
		</p>
		<p>
		</p>
		<p>现在我们需要增加http请求了，他也是我们测试的内容主体部分。你可以通过下面的步骤来增加性的http请求：</p>
		<p>1.	选中可视化界面中左边树的Thread Group节点，单击右键，选择Add'sampler'http request，界面右边将会出现他的设置信息框。</p>
		<p>2.	他的参数和2.5中介绍的http属性差不多，增加的属性中有发送http时方法的选择，你可以选择为get或者post。</p>
		<p>我们现在增加两个http 请求，因为我们设置了默认的http属性，所以和默认http属性中相同的属性不再重复设置。设置后的屏幕截图如下：</p>
		<br />
		<a name="N100FF">
				<b>图四：设置好的jsp测试请求</b>
		</a>
		<br />
		<img alt="图四：设置好的jsp测试请求" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image007.png" height="362" width="506" />
		<br />
		<br />
		<a name="N1010E">
				<b>图五：设置好的Servlet测试请求（带参数）</b>
		</a>
		<br />
		<img alt="图五：设置好的Servlet测试请求（带参数）" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image009.png" height="364" width="505" />
		<br />
		<p>
				<a name="N1011B">
						<span class="smalltitle">2.7	增加Listener</span>
				</a>
		</p>
		<p>
		</p>
		<p>增
加listener是为了记录测试信息并且可以使用Jmeter提供的可视化界面查看测试结果，里面有好几种结果分析方式可供选择，你可以根据自己习惯的
分析方式选择不同的结果显示方式，我们这里使用表格的形式来查看和分析测试结果。你可以通过下面的步骤来增加listener：</p>
		<p>1.	选中可视化界面中左边树的Test Plan节点，单击右键，选择Add'listener'view result in table，界面右边将会出现他的设置信息和结果显示框。</p>
		<p>2.	你可以设置界面上面的filename属性设置将测试结果保存到某个文件中
界面下面将使用表格显示测试结果，表格的第一列sampleno显示请求执行的顺序和编号，url显示请求发送的目标，sample－ms列显示这个请求完成耗费的时间，最后的success列显示改请求是否成功执行。</p>
		<p>界面的最下面你还可以看到一些统计信息，最关心的应该是Average吧，也就是相应的平均时间。</p>
		<p>
				<a name="N1012F">
						<span class="smalltitle">2.8	开始执行测试计划</span>
				</a>
		</p>
		<p>
		</p>
		<p>现在你可以通过单击菜单栏run -&gt; Start开始执行测试计划了。下面这两个图是作者第一次、第二次执行该测试计划的结果图:</p>
		<br />
		<a name="N1013C">
				<b>图六：第一次执行后的结果显示</b>
		</a>
		<br />
		<img alt="图六：第一次执行后的结果显示" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image011.png" height="453" width="564" />
		<br />
		<br />
		<a name="N1014B">
				<b>图七：第二次执行的结果显示</b>
		</a>
		<br />
		<img alt="图七：第二次执行的结果显示" src="http://www.ibm.com/developerworks/cn/java/l-jmeter/images/image013.png" height="456" width="564" />
		<br />
		<p>大家可以看到第一次执行时的几个大时间值均来自于jsp request，这可以通过下面的理由进行解释：jsp执行前都需要被编译成.class文件。所以第二次的结果才是正常的结果。</p>
		<br />
		<table border="0" cellpadding="0" cellspacing="0" width="100%">
				<tbody>
						<tr>
								<td>
										<img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" />
										<br />
										<img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" align="right" cellpadding="0" cellspacing="0">
				<tbody>
						<tr align="right">
								<td>
										<img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" />
										<br />
										<table border="0" cellpadding="0" cellspacing="0">
												<tbody>
														<tr>
																<td valign="middle">
																		<img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" />
																		<br />
																</td>
																<td align="right" valign="top">
																		<a href="http://www.ibm.com/developerworks/cn/java/l-jmeter/index.html#main" class="fbox">
																				<b>回页首</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">总结</span>
				</a>
		</p>
		<p>
		</p>
		<p>JMeter用于进行供能或者性能测试，通过使用JMeter提供的供能，我们可以可视化的制定测试计划：包括规定使用什么样的负载、测试什么内容、传入的参数，同时，他提供了好多种图形化的测试结果显示方式，使我们能够简单的开始测试工作和分析测试结果。</p>
		<p>本
文中，作者根据自己的使用经验，详细演示了如何使用JMeter来进行Web测试的全部过程，简单的介绍了JMeter提供测试结果的图形化显示界面中相
关参数的含义。希望能够帮助大家学会使用JMeter的基本知识，同时，大家可以参考这个过程和JMeter的帮助文档来实现对java对象、数据库等的
测试过程。</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/294573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-09-10 13:51 <a href="http://www.blogjava.net/libin2722/articles/294573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(原)Proxool 连接池</title><link>http://www.blogjava.net/libin2722/articles/294485.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 09 Sep 2009 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/294485.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/294485.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/294485.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/294485.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/294485.html</trackback:ping><description><![CDATA[导入jar包：proxool-0.9.1.jar 和 proxool-cglib.jar<br /><br />一、使用硬编码方式<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);"> com.proxool.test;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.Connection;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.DriverManager;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.SQLException;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.Log;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.LogFactory;<br /><br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Test1 {<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> Log LOG </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> LogFactory.getLog(Test1.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * </span><span style="color: rgb(128, 128, 128);">@param</span><span style="color: rgb(0, 128, 0);"> args<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated method stub</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        Connection connection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">           Class.forName("com.mysql.jdbc.Driver");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">             Class.forName(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">org.logicalcobwebs.proxool.ProxoolDriver</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />           </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">             connection = DriverManager.getConnection("jdbc:mysql:</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">172.16.220.154:3306/sipityprofile?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8&amp;user=root&amp;password=12345678");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">               connection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> DriverManager.getConnection(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">proxool.example:com.mysql.jdbc.Driver:jdbc:mysql://172.16.220.154:3306/sipityprofile?user=root&amp;password=12345678</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">               connection = DriverManager.getConnection("proxool.example");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">           } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SQLException e) {<br />             LOG.error(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Problem getting connection</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e);<br />           }<br />           <br />          </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (connection </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />            LOG.info(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Got connection :)</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />          } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />            LOG.error(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Didn't get connection, which probably means that no Driver accepted the URL</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />          }<br />          <br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (ClassNotFoundException e) {<br />          LOG.error(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Couldn't find driver</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e);<br />        } </span><span style="color: rgb(0, 0, 255);">finally</span><span style="color: rgb(0, 0, 0);"> {<br />          </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Check to see we actually got a connection before we<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> attempt to close it.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (connection </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />              connection.close();<br />            }<br />          } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SQLException e) {<br />            LOG.error(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Problem closing connection</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, e);<br />          }<br />        } <br />    }<br /><br />}<br /></span></div><br />二、使用 xml 配置文件<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);"> com.proxool.test;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.Connection;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.DriverManager;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.ResultSet;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.SQLException;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.Statement;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.Log;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.LogFactory;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.logicalcobwebs.proxool.ProxoolException;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.logicalcobwebs.proxool.configuration.JAXPConfigurator;<br /><br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Test2ByXml {<br />    <br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> Log LOG </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> LogFactory.getLog(Test2ByXml.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * </span><span style="color: rgb(128, 128, 128);">@param</span><span style="color: rgb(0, 128, 0);"> args<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated method stub</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            JAXPConfigurator.configure(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">src/proxool.xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">);<br />            Connection connection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> DriverManager.getConnection(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">proxool.proxool-sipity</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> connection) {<br />                LOG.info(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">connection is null</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            }</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                LOG.info(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">connection successfull</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />                Statement statement </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> connection.createStatement();<br />                ResultSet resultSet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> statement.executeQuery(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">select * from event</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />                </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (resultSet.next()) {<br />                    LOG.info(resultSet.getInt(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">resultSet.getString(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">));<br />                }<br />            }<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (ProxoolException e) {<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SQLException e) {<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        }<br />    }<br /><br />}<br /></span></div><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;?</span><span style="color: rgb(255, 0, 255);">xml version="1.0" encoding="ISO-8859-1"</span><span style="color: rgb(0, 0, 255);">?&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">something-else-entirely</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">proxool</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">alias</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">proxool-sipity</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">alias</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">driver-url</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">jdbc:mysql://172.16.220.154:3306/sipityprofile</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">driver-url</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">driver-class</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">com.mysql.jdbc.Driver</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">driver-class</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">driver-properties</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="user"</span><span style="color: rgb(255, 0, 0);"> value</span><span style="color: rgb(0, 0, 255);">="root"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />            </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">property </span><span style="color: rgb(255, 0, 0);">name</span><span style="color: rgb(0, 0, 255);">="password"</span><span style="color: rgb(255, 0, 0);"> value</span><span style="color: rgb(0, 0, 255);">="12345678"</span><span style="color: rgb(255, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">/&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">driver-properties</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">maximum-connection-count</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">maximum-connection-count</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">house-keeping-test-sql</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">select 1</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">house-keeping-test-sql</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">proxool</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">something-else-entirely</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><br /></span><span style="color: rgb(0, 0, 0);"></span></div><br /><br />三、使用 properties 方式<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);"> com.proxool.test;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.Connection;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.DriverManager;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.ResultSet;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.SQLException;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.sql.Statement;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.Log;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.apache.commons.logging.LogFactory;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.logicalcobwebs.proxool.ProxoolException;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> org.logicalcobwebs.proxool.configuration.PropertyConfigurator;<br /><br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Test3ByProp {<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> Log LOG </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> LogFactory.getLog(Test3ByProp.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">);<br />    <br />    </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">{<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            PropertyConfigurator.configure(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">src/proxool.properties</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (ProxoolException e) {<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        }<br />    }<br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * </span><span style="color: rgb(128, 128, 128);">@param</span><span style="color: rgb(0, 128, 0);"> args<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated method stub</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        testConnection();<br />        testConnection();<br />    }<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> testConnection() {<br />        Connection connection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            <br />            connection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> DriverManager.getConnection(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">proxool.proxool-sipity</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> connection) {<br />                LOG.info(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">connection is null</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            }</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                LOG.info(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">connection successfull</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />                Statement statement </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> connection.createStatement();<br />                ResultSet resultSet </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> statement.executeQuery(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">select * from event</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />                </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (resultSet.next()) {<br />                    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">LOG.info(resultSet.getInt(1)+"    "+resultSet.getString(2));</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">                }<br />            }<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SQLException e) {<br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        } </span><span style="color: rgb(0, 0, 255);">finally</span><span style="color: rgb(0, 0, 0);"> {<br />            </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />                connection.close();<br />            } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (SQLException e) {<br />                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">                e.printStackTrace();<br />            }<br />        }<br />    }<br /><br />}<br /></span></div><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.proxool.alias</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">proxool</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">sipity<br />jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.proxool.driver</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">url</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">jdbc:mysql:</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">172.16.220.154:3306/sipityprofile</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.proxool.driver</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">com.mysql.jdbc.Driver<br />jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.user</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">root<br />jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.password</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">12345678</span><span style="color: rgb(0, 0, 0);"><br />jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.proxool.maximum</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">connection</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">count</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);"><br />jdbc</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">.proxool.house</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">keeping</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">test</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">sql</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">select </span><span style="color: rgb(0, 0, 0);">1</span></div><br /><img src ="http://www.blogjava.net/libin2722/aggbug/294485.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-09-09 17:09 <a href="http://www.blogjava.net/libin2722/articles/294485.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>（原）Java 类访问 URI</title><link>http://www.blogjava.net/libin2722/articles/294483.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 09 Sep 2009 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/294483.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/294483.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/294483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/294483.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/294483.html</trackback:ping><description><![CDATA[
		<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;">
				<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
				<span style="color: rgb(0, 0, 255);">import</span>
				<span style="color: rgb(0, 0, 0);"> java.io.IOException;<br /><br /></span>
				<span style="color: rgb(0, 0, 255);">import</span>
				<span style="color: rgb(0, 0, 0);"> org.apache.commons.httpclient.HttpClient;<br /></span>
				<span style="color: rgb(0, 0, 255);">import</span>
				<span style="color: rgb(0, 0, 0);"> org.apache.commons.httpclient.HttpException;<br /></span>
				<span style="color: rgb(0, 0, 255);">import</span>
				<span style="color: rgb(0, 0, 0);"> org.apache.commons.httpclient.HttpStatus;<br /></span>
				<span style="color: rgb(0, 0, 255);">import</span>
				<span style="color: rgb(0, 0, 0);"> org.apache.commons.httpclient.methods.GetMethod;<br /><br /><br /></span>
				<span style="color: rgb(0, 0, 255);">public</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">class</span>
				<span style="color: rgb(0, 0, 0);"> Test {<br /><br />    </span>
				<span style="color: rgb(0, 128, 0);">/**</span>
				<span style="color: rgb(0, 128, 0);">
						<br />     * </span>
				<span style="color: rgb(128, 128, 128);">@param</span>
				<span style="color: rgb(0, 128, 0);"> args<br />     </span>
				<span style="color: rgb(0, 128, 0);">*/</span>
				<span style="color: rgb(0, 0, 0);">
						<br />    </span>
				<span style="color: rgb(0, 0, 255);">public</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">static</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">void</span>
				<span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        </span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);"> TODO Auto-generated method stub</span>
				<span style="color: rgb(0, 128, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 0);">        GetMethod method </span>
				<span style="color: rgb(0, 0, 0);">=</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">new</span>
				<span style="color: rgb(0, 0, 0);"> GetMethod(</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">http://api.telenav.com/tnapi/services/geoutil/geocode?apiKey=AQAAASNiwsIwf/////////8AAAABAAAAAQEAAAAQF55mB/t8b4u/xsTdcidXpAEAAAAOAwAAAA8AAAAXAAAAAQA=&amp;firstLine=1130%20kifer%20rd,Sunnyvale,ca&amp;country=US</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">);<br />        HttpClient httpClient </span>
				<span style="color: rgb(0, 0, 0);">=</span>
				<span style="color: rgb(0, 0, 0);"> </span>
				<span style="color: rgb(0, 0, 255);">new</span>
				<span style="color: rgb(0, 0, 0);"> HttpClient();<br />        </span>
				<span style="color: rgb(0, 0, 255);">try</span>
				<span style="color: rgb(0, 0, 0);"> {<br />            </span>
				<span style="color: rgb(0, 0, 255);">int</span>
				<span style="color: rgb(0, 0, 0);"> state </span>
				<span style="color: rgb(0, 0, 0);">=</span>
				<span style="color: rgb(0, 0, 0);"> httpClient.executeMethod(method);<br />            </span>
				<span style="color: rgb(0, 0, 255);">if</span>
				<span style="color: rgb(0, 0, 0);"> (state </span>
				<span style="color: rgb(0, 0, 0);">==</span>
				<span style="color: rgb(0, 0, 0);"> HttpStatus.SC_OK) {<br />                System.out.println(</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">OK</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">);<br />            }</span>
				<span style="color: rgb(0, 0, 255);">else</span>
				<span style="color: rgb(0, 0, 0);">{<br />                System.out.println(</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">Error</span>
				<span style="color: rgb(0, 0, 0);">"</span>
				<span style="color: rgb(0, 0, 0);">);<br />            }<br />            String result </span>
				<span style="color: rgb(0, 0, 0);">=</span>
				<span style="color: rgb(0, 0, 0);"> method.getResponseBodyAsString();<br />            System.out.println(result);<br />        } </span>
				<span style="color: rgb(0, 0, 255);">catch</span>
				<span style="color: rgb(0, 0, 0);"> (HttpException e) {<br />            </span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span>
				<span style="color: rgb(0, 128, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        } </span>
				<span style="color: rgb(0, 0, 255);">catch</span>
				<span style="color: rgb(0, 0, 0);"> (IOException e) {<br />            </span>
				<span style="color: rgb(0, 128, 0);">//</span>
				<span style="color: rgb(0, 128, 0);"> TODO Auto-generated catch block</span>
				<span style="color: rgb(0, 128, 0);">
						<br />
				</span>
				<span style="color: rgb(0, 0, 0);">            e.printStackTrace();<br />        }<br />    }<br /><br />}<br /></span>
		</div>
		<br />Maven 依赖<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">dependency</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">    &lt;</span><span style="color: rgb(128, 0, 0);">groupId</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">commons-httpclient</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">groupId</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">artifactId</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">commons-httpclient</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">artifactId</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">version</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">3.0.1</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">version</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">dependency</span><span style="color: rgb(0, 0, 255);">&gt;</span></div><br /><br /><img src ="http://www.blogjava.net/libin2722/aggbug/294483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-09-09 17:04 <a href="http://www.blogjava.net/libin2722/articles/294483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)应用架构设计“防火”经验分享</title><link>http://www.blogjava.net/libin2722/articles/293768.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 03 Sep 2009 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/293768.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/293768.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/293768.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/293768.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/293768.html</trackback:ping><description><![CDATA[
		<p style="text-align: center;" class="MsoNormal" align="center">
				<span style="font-family: 宋体; font-size: 15pt;">应用架构设计“防火”经验分享</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Author : </span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">岑文初</span>
				<span style="line-height: 150%; color: black; font-size: 12pt;">(</span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">淘宝花名：放翁</span>
				<span style="line-height: 150%; color: black; font-size: 12pt;">)</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Email: </span>
				<span style="line-height: 150%; color: blue; font-size: 12pt;">
						<a href="mailto:fangweng@taobao.com">fangweng@taobao.com</a>
				</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Blog: </span>
				<span style="line-height: 150%; font-family: 宋体; color: black; font-size: 12pt;">
						<a href="http://blog.csdn.net/cenwenchu79">
								<span style="font-family: 'Calibri','sans-serif';">http://blog.csdn.net/cenwenchu79</span>
						</a>
				</span>
		</p>
		<p style="background: white none repeat scroll 0% 0%; text-align: left; line-height: 150%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;" class="MsoNormal" align="left">
				<span style="line-height: 150%; color: black; font-size: 12pt;">Date: 2009-08-26</span>
		</p>
		<p>         <span style="font-family: 宋体;">刚从阿软到淘宝不久，现在主要负责</span>TOP<span style="font-family: 宋体;">平台的技术框架设计，同时要肩负“救火”和“防火”的工作，也需要培养团队的同学能够有“防火”意识，减少“救火”次数，因此今天下午花了一点时间，也没于写任何的</span>PPT<span style="font-family: 宋体;">，就直接将自己想的起来的一些自己认为应用架构设计“防火”知识做了一下事例分享，这里也想记录下来给更多的同学分享一下，当然很多都是老生常谈的常识，但是有时候不经意就会忘记一些血的教训。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">资源是有限的</span>
				</strong>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">着火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">系统设计的时候总是估摸不到会有大数据量从远端传输过来（例如处理</span>Http<span style="font-family: 宋体;">请求时，对于大附件内容的处理，全部装载到内存，结果资源耗尽。从搜索引擎或者</span>DB<span style="font-family: 宋体;">或者缓存里面拉数据，没有分页，结果内存被吃尽。</span>Socket<span style="font-family: 宋体;">无限建立连接，结果</span>linux<span style="font-family: 宋体;">的文件句柄被耗尽。）</span></p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对业务场景中资源的分配与申请需要做到上限控制，以及达到上限以后的逻辑处理（排队，丢弃，告警）。可以采取一些滑动窗口设计来将不需要过多处理的内容分段直接送入下一个处理管道中。</span>
		</p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">依赖是未知的</span>
				</strong>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">着火点：</span>
		</p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">事务中嵌入对于第三方系统的请求（例如在数据库操作时去发送邮件或者缓存获取内容，结果连接池资源被</span>Hold<span style="font-family: 宋体;">，导致系统不可用）。默认依赖系统会给出结果，如果出现异常就反复重试，结果对方被压垮，自己也牺牲。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于第三方系统的依赖能够异步的就采用异步方式，能够从主流程
中剥离的就剥离。同时设计好容错的机制，采用本地时效性缓存减少对对方的压力和依赖。最重要的就是注意系统间的死锁，申请了一套资源处理业务逻辑，结果由
于远端系统的不可用，导致本地资源的无法释放，最后击垮自己系统。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">线程安全与性能</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于线程不安全的对象处理一定要小心，否则业务出现异常的地方其实已经离设计出现问题的地方十万八千里，问题时常成为灵异问题，解决只有靠经验。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">首先对于自己设计的类和方法需要注释是否是线程安全的。同时明确类的使用场景，对线程安全及高性能作判断，因为采用线程安全的对象一定会有性能损耗。最近给同学写的一个</span>Http<span style="font-family: 宋体;">消息的</span>Lazy<span style="font-family: 宋体;">获取参数，就是线程不安全的类，但是这个类只会保存在</span>ThreadLocal<span style="font-family: 宋体;">中，因此不存在问题。很直观的一点判断是否线程安全，就看看你设计的类里面的成员变量在多线程操作时候是否会有并发问题，例如一个普通的</span>Map<span style="font-family: 宋体;">，多个线程操作就会导致结果的不可估量性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">资源释放</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">正常逻辑都会将</span>IO<span style="font-family: 宋体;">流关闭，</span>Socket<span style="font-family: 宋体;">关闭，但是异常抛出时候，没有走到资源释放的流程中，产生了资源泄露问题。另外，资源中可能会有内嵌资源，当内部资源被外部的对象引用，则释放将不成功，内部资源依然会泄露。一些需要显式回收的资源（例如</span>ThreadLocal<span style="font-family: 宋体;">），如果不回收，那么下次线程被操作系统重用，则会出现莫名其妙的问题（</span>Java<span style="font-family: 宋体;">的线程创建和使用依赖于操作系统的实现）。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         Finally<span style="font-family: 宋体;">的处理。需要释放的资源要做深度检查。需要显式回收的资源要确保使用完毕以后被回收（异常情况也需要考虑）。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">创建与复用</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">在以前设计</span>Cache<span style="font-family: 宋体;">客户端的时候，有同学给我建议说我对于字节数组利用可以采取复用的方式，这样可以减少对象的申请。但是做了一下测试，这样的重复利用其实效果不像想象的那么好，甚至还不如直接创建。</span></p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">Java<span style="font-family: 宋体;">的垃圾收集器已经在性能上有了很大的提高，同时对于对象的复用需要考虑对象复用前的初始化或者是内容重置，这些得成本及复杂度可能远远要高于复用带来的优势，因此需要根据具体的业务场景选择复用和创建。当然对于稀缺资源采用池的方式是最好的。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">字符串处理，日志级别的选择</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">这两个是小问题，但是会带来大麻烦。首先字符串的累加是老生常谈的问题，但是很多新手不以为然，当你是一个高速运转的系统时，你就会发现</span>1ms<span style="font-family: 宋体;">的延时在上千万次调用下回被无限放大，</span>10byte<span style="font-family: 宋体;">的申请，在上千万次的请求下会带来</span>GC<span style="font-family: 宋体;">多次的操作（带来的短暂处理停滞直接影响系统的可用性）。日志级别的随意性会导致线上环境日志迅速膨胀，出错难以查找，影响系统的效率。（</span>log4j<span style="font-family: 宋体;">优化的再好也是要写文件的，虽然是异步刷页）</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">谨慎处理字符串拼接，选择线程安全或者不安全的两个</span>StringBuilder<span style="font-family: 宋体;">和</span>StringBuffer<span style="font-family: 宋体;">。日志尽量区分清楚，</span>debug<span style="font-family: 宋体;">和</span>Info<span style="font-family: 宋体;">，前者纯粹调试，可以有海量信息，</span>Info<span style="font-family: 宋体;">一般用于系统或者模块的状况报告。</span>Warn<span style="font-family: 宋体;">通常不建议使用了。</span>Error<span style="font-family: 宋体;">就把你需要的关键信息都打出来。附带这里说一下对于日期对象的处理，在传输和保存的过程中，建议都还是采用</span>long<span style="font-family: 宋体;">型，可以很好的提高性能及满足国际化的需求。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">原子操作与并发控制</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于本地的对象操作通常情况下通过锁机制保证并发的一致性，当在设计一个对于资源访问控制的策略时，例如集群应用处理某人每天发送短信</span>1000<span style="font-family: 宋体;">条，这时候计数器保存在远端的集中式缓存中，采用</span>get<span style="font-family: 宋体;">和</span>put<span style="font-family: 宋体;">方式就会有并发问题，因为在应用获得到</span>999<span style="font-family: 宋体;">这个计数器值的时候，也许正有</span>10000<span style="font-family: 宋体;">个请求也获得了这个值，这样原有的控制就失效了。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">其实就是一个原子操作的支持，本地数据可以通过锁来达到原子操作，远程依赖就需要对方系统提供原子操作接口来实现高并发下的业务处理，例如</span>Memcached Cache<span style="font-family: 宋体;">提供的</span>incr <span style="font-family: 宋体;">和</span>decr<span style="font-family: 宋体;">。结合黑名单策略，计数器可以发挥很多用途，包括及时监控告警等。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">接口实现与松耦合</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点</span>:</p>
		<p>         <span style="font-family: 宋体;">没有接口提供，团队间合作困难，无法</span>Mock<span style="font-family: 宋体;">，相互之间进度影响很大。同时业务实现的修改直接影响业务调用方，使得双方耦合性很强，系统不稳定性被放大。</span></p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">防火点：</span>
		</p>
		<p style="text-indent: 20.25pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对外提供的服务，或者模块间交互的服务都需要接口化。框架性代码需要在模块载入时考虑是否需要接口化定义，以便在不同环境可以切换不同实现提供对特殊场景的支持，同时也可以将具体实现延后交给使用者实现，使得框架更加灵活。</span>Jdk<span style="font-family: 宋体;">对于</span>xml<span style="font-family: 宋体;">的解析就是最好的范例。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">灵活性和性能和可维护性的折中</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">最近看了一些同学的代码，看到大量的使用了反射，拦截器等。但是在线上环境运行过程中就发现对于一些拦截器的配置疏漏导致系统性能大幅度降低。对于几十个</span>spring<span style="font-family: 宋体;">文件，有谁能够很清楚和直观的了解到这些看似灵活和无侵入性的设计。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于业务逻辑不复杂，同时场景不多变的流程采用简单的实现，不要追求花哨的灵活性，带来的只会是可读性，可维护性，可用性的降低。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">要有分布式和并发的观念，但是不要本末倒置</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">有些同学在做设计的时候考虑的很清晰，但是就是没有考虑集群部署的情况，结果系统上线以后出现了无法集群部署的问题。并发情况的设计也一样，仅仅在满足业务需求以后，对于多用户并发操作的考虑缺失，导致系统流程错误。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">设计的时候需要适度考虑这些问题，但是是在满足现有业务逻辑的前提下，不要为了追求分布式而分布式。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">便利性的函数与性能的冲突</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">首先申明的是这点适用范围有限（高速运转的模块）。对于</span>String,Date<span style="font-family: 宋体;">等对象的便利性函数，例如正则匹配，分割，</span>Format<span style="font-family: 宋体;">等等其实都会有不少的性能损耗。例如你只是需要判断文件名最后的后缀是否满足需求，采用了正则匹配，结果发现性能在高速运转的情况下大大下降。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">高速运转的模块尽量采用原始方式或者半原始方式。例如上面说到的文件后缀，就用</span>string<span style="font-family: 宋体;">的</span>endwith<span style="font-family: 宋体;">来判断。对于一些字符串的替换，能够用字符串拼接就拼接。对于一些字节流的处理也可以自己根据需求来订制的写。总的一句话，能够满足的就用最低成本的方法。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">防止系统设计的完备性成为攻击或者压力的瓶颈</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">在很多设计的时候，对于一些系统设计讲究比较完美。例如对于对象的查询会分本地缓存，集中缓存，</span>DB<span style="font-family: 宋体;">三个阶段。当对方攻击采用不存在的资源名称时候，这种分阶段的设计反而会增加系统负荷。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">简化流程的分支和层次，对于消耗性资源的访问尽量减少或者没有（采用黑名单本地缓存或者集中缓存的方式），同时改</span>Pull<span style="font-family: 宋体;">为</span>Push<span style="font-family: 宋体;">方式，通过控制数据变更点来通知相关系统，而非轮询获取更新状态。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">多级缓存和异步缓解异构系统的瓶颈</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">有时候设计系统时，服务提供方向我们许诺说对方系统如何高效和健壮，但是当频繁访问产生网络风暴的时候，我们发现原来带宽和网络</span>IO<span style="font-family: 宋体;">本身都会成为瓶颈。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p style="text-indent: 21pt;" class="MsoNormal">
				<span style="font-family: 宋体;">对于第三方系统的依赖，要做到松耦合就要从流程的异步化来实现。同时通过缓存的使用来达到，系统的高效性和降低对于第三方系统的依赖程度。这样可以大大降低系统的瓶颈。</span>
		</p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">运行期白盒化，模块可重置</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">系统运行起来以后就无法在知道内部的状态，也无法对问题组件进行单独处理，造成线上环境的不可知性和无法部分修复。不得不停机重起和看日志。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">模块设计过程中考虑运行期可观测和可重置，提高系统的模块化程度及健壮性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">站在用户角度设计接口，提升系统可用性</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">总是从自身业务体系和架构去考虑如何设计对外接口，但是发现最后用户使用的很别扭，同时由于需求不能直接被满足，会多次反复调用接口，导致自身系统的压力增大。例如对于一个状态的检查接口，是否提供一个状态变更通知接口就会极大降低轮询的压力</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">需要从客户角度考虑问题，设计接口，防止需求和实现脱节，导致系统压力增加。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">懒惰有时候是件好事</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点</span>:</p>
		<p>         <span style="font-family: 宋体;">业务流程中很多耗时的操作在流程编排方面没有考虑清楚，当耗时工作做完以后，发现不符合最基本的交验，这样就会导致系统无谓的增加了开销。对于需要申请的资源，考虑处理流程的阶段，阶段性申请要优于一次申请（不过需要注意死锁）。</span></p>
		<p>         <span style="font-family: 宋体;">防火点</span>:</p>
		<p>         <span style="font-family: 宋体;">流程编排需要合理性，尽量将耗时的工作放到合理的位置，同时做好基础的防攻击轻量前端屏障逻辑，提高系统的健壮性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">主流程和副流程隔离</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         SIP<span style="font-family: 宋体;">早先的日志分析模块中有分析日志，备份，发邮件，更新系统缓存，操作数据库等多种操作，但是一股脑儿都被放到一个流程中，结果当邮件没有发成功导致整个流程的失败。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">把真正的主流程梳理出来，同时对于一些副流程可以考虑采用后台异步方式完成，提高系统稳定性。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">模块间接口交互，控制资源直接操作入口</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">对于数据库中的资源任何模块不区分范围都可以访问，最后导致数据结构变更困难，业务对象管理混乱，模块无法剥离独立。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">模块化设计的基本思想，模块间通过接口交互获得其他模块管辖的数据，接口方式屏蔽了对于后端实现及业务对象的依赖。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">学习份外的事情，配置决定成败</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">没有</span>SA<span style="font-family: 宋体;">就高不定环境，也无法了解操作系统的配置与</span>Web<span style="font-family: 宋体;">容器的配置对于应用的影响。没有</span>DBA<span style="font-family: 宋体;">就无法确定如何写</span>SQL<span style="font-family: 宋体;">避免一些简单的耗时查询。没有测试同学就无法作压力测试，无法了解当前系统性能。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">多学多问，多了解一些其他岗位的内容，才能够更加全面的掌握好架构设计。</span></p>
		<p>
				<strong>
						<span style="font-family: 宋体; color: red; font-size: 14pt;">不要迷信</span>
				</strong>
		</p>
		<p>         <span style="font-family: 宋体;">着火点：</span></p>
		<p>         <span style="font-family: 宋体;">总是看到新技术如何有优点，但是看不到它的成熟度。总是听到很多经验之谈，但是从来没有真的比较过。结果就是别人说什么就是什么，系统地稳定性和可用性基于</span>Google<span style="font-family: 宋体;">出来的结果。</span></p>
		<p>         <span style="font-family: 宋体;">防火点：</span></p>
		<p>         <span style="font-family: 宋体;">需要听取各种意见和经验，同时用测试结果说明问题的结果，看代码说明结果背后的问题。这样才会走得更加踏实，学的更加实际。其实技术发展来说，真正的基础性内容还是有限的，而且各种技术都是触类旁通。分布式，不论是文件系统，</span>DB<span style="font-family: 宋体;">，缓存都会遇到分布式的共性问题（负载均摊，容错，数据复制，动态扩容等等），在结合一些文件系统，</span>DB<span style="font-family: 宋体;">，缓存的自身特质。因此扎扎实实学好基础，了解</span>Http<span style="font-family: 宋体;">协议，了解七层通信协议，了解文件系统设计，了解</span>MapReduce<span style="font-family: 宋体;">思路，了解结构化，半结构化（</span>bigmap<span style="font-family: 宋体;">），非结构化存储的要点，就会不会让自己迷失在技术宣传中。</span></p>
		<p>         <span style="font-family: 宋体;">明天晚上去北京参加系统架构师会议，到时候会和大家分享一下</span>TOP<span style="font-family: 宋体;">的一些商业和技术上的心得，准备得很仓促，但是个人觉得分享就在于自己将自己知道的说出来，时间不长，</span>45<span style="font-family: 宋体;">分钟，能讲的也不多，但是如果对于淘宝开放平台有兴趣的同学可以来听一下。这里也算是做个广告，不过不要期望过高，免得失望也大</span>^_^<span style="font-family: 宋体;">。五年没有来北京了，首都应该也变化不小了。</span></p>
<img src ="http://www.blogjava.net/libin2722/aggbug/293768.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-09-03 17:25 <a href="http://www.blogjava.net/libin2722/articles/293768.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)各种架构图汇总!</title><link>http://www.blogjava.net/libin2722/articles/272007.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 21 May 2009 08:05:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/272007.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/272007.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/272007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/272007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/272007.html</trackback:ping><description><![CDATA[
		<p> <a href="http://blog.csdn.net/liuxiaotao008/archive/2008/06/29/2595391.aspx">http://blog.csdn.net/liuxiaotao008/archive/2008/06/29/2595391.aspx</a> </p>
		<p>1.Spring架构图</p>
		<p> <img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/liuxiaotao008/spring-overview.png" /></p>
		<p>
				<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/liuxiaotao008/spring1.gif" />
		</p>
		<p>
				<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/liuxiaotao008/spring2.gif" />
		</p>
		<p>2.Hibernate架构图</p>
		<p>
				<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/liuxiaotao008/hibernate1.gif" />
		</p>
		<p> </p>
		<p>
				<img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/liuxiaotao008/hibernate2.gif" />
		</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/272007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-05-21 16:05 <a href="http://www.blogjava.net/libin2722/articles/272007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式30分钟入门教程</title><link>http://www.blogjava.net/libin2722/articles/252901.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Mon, 02 Feb 2009 00:44:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/252901.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/252901.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/252901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/252901.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/252901.html</trackback:ping><description><![CDATA[<ol>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#mission">本文目标</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#howtouse">如何使用本教程</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#introduction">正则表达式到底是什么东西？</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#getstarted">入门</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#testing">测试正则表达式</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#metacode">元字符</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#escape">字符转义</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#repeat">重复</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#charclass">字符类</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#alternative">分枝条件</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negation">反义</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#grouping">分组</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#backreference">后向引用</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#lookaround">零宽断言</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negativelookaround">负向零宽断言</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#commenting">注释</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#greedyandlazy">贪婪与懒惰</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#regexoptions">处理选项</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#balancedgroup">平衡组/递归匹配</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#more">还有些什么东西没提到</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#contact">联系作者</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#ad">最后,来点广告...</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#resources">网上的资源及本文参考文献</a></li>
    <li><a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#updatelog">更新说明</a></li>
</ol>
<h2 id="mission">本文目标</h2>
<p>30分钟内让你明白正则表达式是什么，并对它有一些基本的了解，让你可以在自己的程序或网页里使用它。</p>
<h2 id="howtouse">如何使用本教程</h2>
<p id="giveMe30Minutes" class="important note">最重要的是——请给我<em>30分钟</em>，如果你没有使用正则表达式的经验，请不要试图在30<em>秒</em>内入门——除非你是超人 :)</p>
<p>别被下面那些复杂的表达式吓倒，只要跟着我一步一步来，你会发现正则表达式其实并没有你
想像中的那么困难。当然，如果你看完了这篇教程之后，发现自己明白了很多，却又几乎什么都记不得，那也是很正常的——我认为，没接触过正则表达式的人在看
完这篇教程后，能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理，以后你还需要多练习，多使用，才能熟练掌握正则表达式。</p>
<p>除了作为入门教程之外，本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说，这个目标还是完成得不错的——你看，我自己也没能把所有的东西记下来，不是吗？</p>
<p><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm" id="clearButton" onclick="return clearFormats();">清除格式</a>&nbsp;文本格式约定：专业术语&nbsp;元字符/语法格式&nbsp;正则表达式&nbsp;正则表达式中的一部分(用于分析)&nbsp;对其进行匹配的源字符串&nbsp;对正则表达式或其中一部分的说明</p>
<p><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm" id="hideButton" onclick="return hideNotes();">隐藏边注</a>&nbsp;本文右边有一些注释，主要是用来提供一些相关信息，或者给没有程序员背景的读者解释一些基本概念，通常可以忽略。</p>
<h2 id="introduction">正则表达式到底是什么东西？</h2>
<p>字符是计算机软件处理文字时最基本的单位，可能是字母，数字，标点符号，空格，换行符，汉字等等。字符串是0个或更多个字符的序列。文本也就是文字，字符串。说某个字符串匹配某个正则表达式，通常是指这个字符串里有一部分（或几部分分别）能满足表达式给出的条件。</p>
<p>在编写处理字符串的程序或网页时，经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说，正则表达式就是记录文本规则的代码。</p>
<p>很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard)，也就是*和?。如果你想查找某个目录下的所有的Word文档的话，你会搜索<span style="color: red;">*.doc</span>。在这里，*会被解释成任意的字符串。和通配符类似，正则表达式也是用来进行文本匹配的工具，只不过比起通配符，它能更精确地描述你的需求——当然，代价就是更复杂——比如你可以编写一个正则表达式，用来查找所有以0开头，后面跟着2-3个数字，然后是一个连字号&#8220;-&#8221;，最后是7或8位数字的字符串(像010-12345678或0376-7654321)。</p>
<h2 id="getstarted">入门</h2>
<p>学习正则表达式的最好方法是从例子开始，理解例子之后再自己对例子进行修改，实验。下面给出了不少简单的例子，并对它们作了详细的说明。</p>
<p>假设你在一篇英文小说里查找hi，你可以使用正则表达式hi。</p>
<p>这几乎是最简单的正则表达式了，它可以精确匹配这样的字符串：由两个字符组成，前一个字符是h,后一个是i。通常，处理正则表达式的工具会提供一个忽略大小写的选项，如果选中了这个选项，它可以匹配hi,HI,Hi,hI这四种情况中的任意一种。</p>
<p>不幸的是，很多单词里包含hi这两个连续的字符，比如him,history,high等等。用hi来查找的话，这里边的hi也会被找出来。如果要精确地查找hi这个单词的话，我们应该使用"bhi"b。</p>
<p>"b是正则表达式规定的一个特殊代码（好吧，某些人叫它元字符，metacharacter），代表着单词的开头或结尾，也就是单词的分界处。虽然通常英文的单词是由空格，标点符号或者换行来分隔的，但是"b并不匹配这些单词分隔字符中的任何一个，它<strong>只匹配一个位置</strong>。</p>
<p>如果需要更精确的说法，"b匹配这样的位置：它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)"w。</p>
<p>假如你要找的是hi后面不远处跟着一个Lucy，你应该用"bhi"b.*"bLucy"b。</p>
<p>这里，.是另一个元字符，匹配除了换行符以外的任意字符。*同样是元字符，不过它代表的不是字符，也不是位置，而是数量——它指定*前边的内容可以连续重复出现任意次以使整个表达式得到匹配。因此，.*连在一起就意味着任意数量的不包含换行的字符。现在"bhi"b.*"bLucy"b的意思就很明显了：先是一个单词hi,然后是任意个任意字符(但不能是换行)，最后是Lucy这个单词。</p>
<p>换行符就是'"n',ASCII编码为10(十六进制0x0A)的字符。</p>
<p>如果同时使用其它元字符，我们就能构造出功能更强大的正则表达式。比如下面这个例子：</p>
<p>0"d"d-"d"d"d"d"d"d"d"d匹配这样的字符串：以0开头，然后是两个数字，然后是一个连字号&#8220;-&#8221;，最后是8个数字(也就是中国的电话号码。当然，这个例子只能匹配区号为3位的情形)。</p>
<p>这里的"d是个新的元字符，匹配一位数字(0，或1，或2，或&#8230;&#8230;)。-不是元字符，只匹配它本身——连字符或者减号。</p>
<p>为了避免那么多烦人的重复，我们也可以这样写这个表达式：0"d{2}-"d{8}。
这里"d后面的{2}({8})的意思是前面"d必须连续重复匹配2次(8次)。</p>
<h2 id="testing">测试正则表达式</h2>
<div>
<p>其它可用的测试工具:</p>
<ul>
    <li><a href="http://www.regexbuddy.com/">RegexBuddy</a></li>
    <li><a href="http://regexpal.com/">Javascript正则表达式在线测试工具</a></li>
</ul>
</div>
<p>如果你不觉得正则表达式很难读写的话，要么你是一个天才，要么，你不是地球人。正则表达式的语法很令人头疼，即使对经常使用它的人来说也是如此。由于难于读写，容易出错，所以找一种工具对正则表达式进行测试是很有必要的。</p>
<p>由于在不同的环境下正则表达式的一些细节是不相同的，本教程介绍的是微软 .Net Framework 2.0下正则表达式的行为，所以，我向你介绍一个.Net下的工具<a title="转到RegexTester的官方网站（英文）" href="http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,13bce26d-7755-441e-92b3-1eb5f9e859f9.aspx">Regex
Tester</a>。首先你确保已经安装了<a href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&amp;FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5" title="转到下载.Net Framework 2.0的页面">.Net Framework 2.0</a>，然后<a href="http://www.unibetter.com/deerchao/downloads/RegexTester.zip" title="从www.unibetter.com下载Regex Tester, 75KB">下载Regex Tester</a>。这是个绿色软件，下载完后打开压缩包,直接运行RegexTester.exe就可以了。</p>
<p>下面是Regex Tester运行时的截图：</p>
<p><img src="http://unibetter.com/deerchao/images/RegexTester.jpg" alt="Regex Tester运行时的截图" /></p>
<h2 id="metacode">元字符</h2>
<p>现在你已经知道几个很有用的元字符了，如"b,.,*，还有"d.正则表达式里还有更多的元字符，比如"s匹配任意的空白符，包括空格，制表符(Tab)，换行符，中文全角空格等。"w匹配字母或数字或下划线或汉字等。</p>
<p>对中文/汉字的特殊处理是由.Net提供的正则表达式引擎支持的，其它环境下的具体情况请查看相关文档。</p>
<p>下面来看看更多的例子：</p>
<p>"ba"w*"b匹配以字母a开头的单词——先是某个单词开始处("b)，然后是字母a,然后是任意数量的字母或数字("w*)，最后是单词结束处("b)。</p>
<p>好吧，现在我们说说正则表达式里的单词是什么意思吧：就是多于一个的连续的"w。不错，这与学习英文时要背的成千上万个同名的东西的确关系不大 :)</p>
<p>"d+匹配1个或更多连续的数字。这里的+是和*类似的元字符，不同的是*匹配重复任意次(可能是0次)，而+则匹配重复1次或更多次。</p>
<p>"b"w{6}"b 匹配刚好6个字母/数字的单词。</p>
<table cellspacing="0">
    <caption>表1.常用的元字符</caption>
    <thead>
        <tr>
            <th scope="col">代码</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>.</td>
            <td>匹配除换行符以外的任意字符</td>
        </tr>
        <tr>
            <td>"w</td>
            <td>匹配字母或数字或下划线或汉字</td>
        </tr>
        <tr>
            <td>"s</td>
            <td>匹配任意的空白符</td>
        </tr>
        <tr>
            <td>"d</td>
            <td>匹配数字</td>
        </tr>
        <tr>
            <td>"b</td>
            <td>匹配单词的开始或结束</td>
        </tr>
        <tr>
            <td>^</td>
            <td>匹配字符串的开始</td>
        </tr>
        <tr>
            <td>$</td>
            <td>匹配字符串的结束</td>
        </tr>
    </tbody>
</table>
<p>元字符^（和数字6在同一个键位上的符号）和$都匹配一个位置，这和"b有点类似。^匹配你要用来查找的字符串的开头，$匹配结尾。这两个代码在验证输入的内容时非常有用，比如一个网站如果要求你填写的QQ号必须为5位到12位数字时，可以使用：^"d{5,12}$。</p>
<p>这里的{5,12}和前面介绍过的{2}是类似的，只不过{2}匹配只能不多不少重复2次，{5,12}则是重复的次数不能少于5次，不能多于12次，否则都不匹配。</p>
<p>因为使用了^和$，所以输入的整个字符串都要用来和"d{5,12}来匹配，也就是说整个输入必须是5到12个数字，因此如果输入的QQ号能匹配这个正则表达式的话，那就符合要求了。</p>
<p>和忽略大小写的选项类似，有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项，^和$的意义就变成了匹配行的开始处和结束处。</p>
<h2 id="escape">字符转义</h2>
<p>如果你想查找元字符本身的话，比如你查找.,或者*,就出现了问题：你没办法指定它们，因为它们会被解释成别的意思。这时你就得使用"来取消这些字符的特殊意义。因此，你应该使用".和"*。当然，要查找"本身，你也得用"".</p>
<p>例如：unibetter".com匹配unibetter.com，C:""Windows匹配C:"Windows。</p>
<h2 id="repeat">重复</h2>
<p>你已经看过了前面的*,+,{2},{5,12}这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码，例如*,{5,12}等)：</p>
<table cellspacing="0">
    <caption>表2.常用的限定符</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>*</td>
            <td>重复零次或更多次</td>
        </tr>
        <tr>
            <td>+</td>
            <td>重复一次或更多次</td>
        </tr>
        <tr>
            <td>?</td>
            <td>重复零次或一次</td>
        </tr>
        <tr>
            <td>{n}</td>
            <td>重复n次</td>
        </tr>
        <tr>
            <td>{n,}</td>
            <td>重复n次或更多次</td>
        </tr>
        <tr>
            <td>{n,m}</td>
            <td>重复n到m次</td>
        </tr>
    </tbody>
</table>
<p>下面是一些使用重复的例子：</p>
<p>Windows"d+匹配Windows后面跟1个或更多数字</p>
<p>^"w+匹配一行的第一个单词(或整个字符串的第一个单词，具体匹配哪个意思得看选项设置)</p>
<h2 id="charclass">字符类</h2>
<p>要想查找数字，字母或数字，空白是很简单的，因为已经有了对应这些字符集合的元字符，但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办？</p>
<p>很简单，你只需要在方括号里列出它们就行了，像[aeiou]就匹配任何一个英文元音字母，[.?!]匹配标点符号(.或?或!)。</p>
<p>我们也可以轻松地指定一个字符范围，像[0-9]代表的含意与"d就是完全一致的：一位数字；同理[a-z0-9A-Z_]也完全等同于"w（如果只考虑英文的话）。</p>
<p>下面是一个更复杂的表达式："(?0"d{2}[) -]?"d{8}。</p>
<p>&#8220;(&#8221;和&#8220;)&#8221;也是元字符，后面的<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#grouping">分组节</a>里会提到，所以在这里需要使用<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#escape">转义</a>。</p>
<p>这个表达式可以匹配几种格式的电话号码，像(010)88886666，或022-22334455，或02912345678等。我们对它进行一些分析吧：首先是一个转义字符"(,它能出现0次或1次(?),然后是一个0，后面跟着2个数字("d{2})，然后是)或-或空格中的一个，它出现1次或不出现(?)，最后是8个数字("d{8})。</p>
<h2 id="alternative">分枝条件</h2>
<p>不幸的是，刚才那个表达式也能匹配010)12345678或(022-87654321这样的&#8220;不正确&#8221;的格式。要解决这个问题，我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则，如果满足其中任意一种规则都应该当成匹配，具体方法是用|把不同的规则分隔开。听不明白？没关系，看例子：</p>
<p>0"d{2}-"d{8}|0"d{3}-"d{7}这个表达式能匹配两种以连字号分隔的电话号码：一种是三位区号，8位本地号(如010-12345678)，一种是4位区号，7位本地号(0376-2233445)。</p>
<p>"(0"d{2}")[- ]?"d{8}|0"d{2}[- ]?"d{8}这个表达式匹配3位区号的电话号码，其中区号可以用小括号括起来，也可以不用，区号与本地号间可以用连字号或空格间隔，也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。</p>
<p>"d{5}-"d{4}|"d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字，或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题：<strong>使用分枝条件时，要注意各个条件的顺序</strong>。如果你把它改成"d{5}|"d{5}-"d{4}的话，那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时，将会从左到右地测试每个条件，如果满足了某个分枝的话，就不会去再管其它的条件了。</p>
<h2 id="grouping">分组</h2>
<p>我们已经提到了怎么重复单个字符（直接在字符后面加上限定符就行了）；但如果想要重复多个字符又该怎么办？你可以用小括号来指定子表达式(也叫做分组)，然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作(后面会有介绍)。</p>
<p>("d{1,3}".){3}"d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式，请按下列顺序分析它："d{1,3}匹配1到3位的数字，("d{1,3}".){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次，最后再加上一个一到三位的数字("d{1,3})。</p>
<p>IP地址中每个数字都不能大于255，大家千万不要被《24》第三季的编剧给忽悠了...</p>
<p>不幸的是，它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话，或许能简单地解决这个问题，但是正则表达式中并不提供关于数学的任何功能，所以只能使用冗长的分组，选择，字符类来描述一个正确的IP地址：((2[0-4]"d|25[0-5]|[01]?"d"d?)".){3}(2[0-4]"d|25[0-5]|[01]?"d"d?)。</p>
<p>理解这个表达式的关键是理解2[0-4]"d|25[0-5]|[01]?"d"d?，这里我就不细说了，你自己应该能分析得出来它的意义。</p>
<h2 id="negation">反义</h2>
<p>有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外，其它任意字符都行的情况，这时需要用到反义：</p>
<table cellspacing="0">
    <caption>表3.常用的反义代码</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>"W</td>
            <td>匹配任意不是字母，数字，下划线，汉字的字符</td>
        </tr>
        <tr>
            <td>"S</td>
            <td>匹配任意不是空白符的字符</td>
        </tr>
        <tr>
            <td>"D</td>
            <td>匹配任意非数字的字符</td>
        </tr>
        <tr>
            <td>"B</td>
            <td>匹配不是单词开头或结束的位置</td>
        </tr>
        <tr>
            <td>[^x]</td>
            <td>匹配除了x以外的任意字符</td>
        </tr>
        <tr>
            <td>[^aeiou]</td>
            <td>匹配除了aeiou这几个字母以外的任意字符</td>
        </tr>
    </tbody>
</table>
<p>例子："S+匹配不包含空白符的字符串。</p>
<p>&lt;a[^&gt;]+&gt;匹配用尖括号括起来的以a开头的字符串。</p>
<h2 id="backreference">后向引用</h2>
<p>使用小括号指定一个子表达式后，<strong>匹配这个子表达式的文本</strong>(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下，每个分组会自动拥有一个组号，规则是：从左向右，以分组的左括号为标志，第一个出现的分组的组号为1，第二个为2，以此类推。</p>
<p>后向引用用于重复搜索前面某个分组匹配的文本。例如，"1代表分组1匹配的文本。难以理解？请看示例：</p>
<p>"b("w+)"b"s+"1"b可以用来匹配重复的单词，像go go, 或者kitty kitty。这个表达式首先是一个单词，也就是单词开始处和结束处之间的多于一个的字母或数字("b("w+)"b)，这个单词会被捕获到编号为1的分组中，然后是1个或几个空白符("s+)，最后是分组1中捕获的内容（也就是前面匹配的那个单词）("1)。</p>
<p>你也可以自己指定子表达式的组名。要指定一个子表达式的组名，请使用这样的语法：(?&lt;Word&gt;"w+)(或者把尖括号换成'也行：(?'Word'"w+)),这样就把"w+的组名指定为Word了。要反向引用这个分组捕获的内容，你可以使用"k&lt;Word&gt;,所以上一个例子也可以写成这样："b(?&lt;Word&gt;"w+)"b"s+"k&lt;Word&gt;"b。</p>
<p>使用小括号的时候，还有很多特定用途的语法。下面列出了最常用的一些：</p>
<table cellspacing="0">
    <caption>表4.常用分组语法</caption>
    <tbody>
        <tr>
            <th scope="col">分类</th>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
        <tr>
            <th rowspan="3">捕获</th>
            <td>(exp)</td>
            <td>匹配exp,并捕获文本到自动命名的组里</td>
        </tr>
        <tr>
            <td>(?&lt;name&gt;exp)</td>
            <td>匹配exp,并捕获文本到名称为name的组里，也可以写成(?'name'exp)</td>
        </tr>
        <tr>
            <td>(?:exp)</td>
            <td>匹配exp,不捕获匹配的文本，也不给此分组分配组号</td>
        </tr>
        <tr>
            <th rowspan="4">零宽断言</th>
            <td>(?=exp)</td>
            <td>匹配exp前面的位置</td>
        </tr>
        <tr>
            <td>(?&lt;=exp)</td>
            <td>匹配exp后面的位置</td>
        </tr>
        <tr>
            <td>(?!exp)</td>
            <td>匹配后面跟的不是exp的位置</td>
        </tr>
        <tr>
            <td>(?&lt;!exp)</td>
            <td>匹配前面不是exp的位置</td>
        </tr>
        <tr>
            <th rowspan="1">注释</th>
            <td>(?#comment)</td>
            <td>这种类型的分组不对正则表达式的处理产生任何影响，用于提供注释让人阅读</td>
        </tr>
    </tbody>
</table>
<p>我们已经讨论了前两种语法。第三个(?:exp)不会改变正则表达式的处理方式，只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面，也不会拥有组号。</p>
<h2 id="lookaround">零宽断言</h2>
<p>地球人，是不是觉得这些术语名称太复杂，太难记了？我也和你一样。知道有这么一种东西就行了，它叫什么，随它去吧！&#8220;无名，万物之始...&#8221;</p>
<p>接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西，也就是说它们像"b,^,$那样用于指定一个位置，这个位置应该满足一定的条件(即断言)，因此它们也被称为零宽断言。最好还是拿例子来说明吧：</p>
<p>断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。</p>
<p>(?=exp)也叫零宽度正预测先行断言，它断言自身出现的位置的后面能匹配表达式exp。比如"b"w+(?=ing"b)，匹配以ing结尾的单词的前面部分(除了ing以外的部分)，如查找I'm singing while you're dancing.时，它会匹配sing和danc。</p>
<p>(?&lt;=exp)也叫零宽度正回顾后发断言，它断言自身出现的位置的前面能匹配表达式exp。比如(?&lt;="bre)"w+"b会匹配以re开头的单词的后半部分(除了re以外的部分)，例如在查找reading a book时，它匹配ading。</p>
<p>假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了)，你可以这样查找需要在前面和里面添加逗号的部分：((?&lt;="d)"d{3})*"b，用它对1234567890进行查找时结果是234567890。</p>
<p>下面这个例子同时使用了这两种断言：(?&lt;="s)"d+(?="s)匹配以空白符间隔的数字(再次强调，不包括这些空白符)。</p>
<h2 id="negativelookaround">负向零宽断言</h2>
<p>前面我们提到过怎么查找<strong>不是某个字符或不在某个字符类里</strong>的字符的方法(反义)。但是如果我们只是想要<strong>确保某个字符没有出现，但并不想去匹配它</strong>时怎么办？例如，如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样：</p>
<p>"b"w*q[^u]"w*"b匹配包含<strong>后面不是字母u的字母q</strong>的单词。但是如果多做测试(或者你思维足够敏锐，直接就观察出来了)，你会发现，如果q出现在单词的结尾的话，像<strong>Iraq</strong>,<strong>Benq</strong>，这个表达式就会出错。这是因为[^u]总要匹配一个字符，所以如果q是单词的最后一个字符的话，后面的[^u]将会匹配q后面的单词分隔符(可能是空格，或者是句号或其它的什么)，后面的"w*"b将会匹配下一个单词，于是"b"w*q[^u]"w*"b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题，因为它只匹配一个位置，并不<strong>消费</strong>任何字符。现在，我们可以这样来解决这个问题："b"w*q(?!u)"w*"b。</p>
<p>零宽度负预测先行断言(?!exp)，断言此位置的后面不能匹配表达式exp。例如："d{3}(?!"d)匹配三位数字，而且这三位数字的后面不能是数字；"b((?!abc)"w)+"b匹配不包含连续字符串abc的单词。</p>
<p>同理，我们可以用(?&lt;!exp),零宽度正回顾后发断言来断言此位置的前面不能匹配表达式exp：(?&lt;![a-z])"d{7}匹配前面不是小写字母的七位数字。</p>
<p>请详细分析表达式(?&lt;=&lt;("w+)&gt;).*(?=&lt;"/"1&gt;)，这个表达式最能表现零宽断言的真正用途。</p>
<p>一个更复杂的例子：(?&lt;=&lt;("w+)&gt;).*(?=&lt;"/"1&gt;)匹配不包含属性的简单HTML标签内里的内容。(&lt;?("w+)&gt;)指定了这样的前缀：被尖括号括起来的单词(比如可能是&lt;b&gt;)，然后是.*(任意的字符串),最后是一个后缀(?=&lt;"/"1&gt;)。注意后缀里的"/，它用到了前面提过的字符转义；"1则是一个反向引用，引用的正是捕获的第一组，前面的("w+)匹配的内容，这样如果前缀实际上是&lt;b&gt;的话，后缀就是&lt;/b&gt;了。整个表达式匹配的是&lt;b&gt;和&lt;/b&gt;之间的内容(再次提醒，不包括前缀和后缀本身)。</p>
<h2 id="commenting">注释</h2>
<p>小括号的另一种用途是通过语法(?#comment)来包含注释。例如：2[0-4]"d(?#200-249)|25[0-5](?#250-255)|[01]?"d"d?(?#0-199)。</p>
<p>要包含注释的话，最好是启用&#8220;忽略模式里的空白符&#8221;选项，这样在编写表达式时能任意的添加空格，Tab，换行，而实际使用时这些都将被忽略。启用这个选项后，在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如，我们可以前面的一个表达式写成这样：</p>
<pre>      (?&lt;=    # 断言要匹配的文本的前缀<br />
&lt;("w+)&gt; # 查找尖括号括起来的字母或数字(即HTML/XML标签)<br />
)       # 前缀结束<br />
.*      # 匹配任意文本<br />
(?=     # 断言要匹配的文本的后缀<br />
&lt;"/"1&gt;  # 查找尖括号括起来的内容：前面是一个"/"，后面是先前捕获的标签<br />
)       # 后缀结束</pre>
<h2 id="greedyandlazy">贪婪与懒惰</h2>
<p>当正则表达式中包含能接受重复的限定符时，通常的行为是（在使整个表达式能得到匹配的前提下）匹配<strong>尽可能多</strong>的字符。考虑这个表达式：a.*b，它将会匹配最长的以a开始，以b结束的字符串。如果用它来搜索aabab的话，它会匹配整个字符串aabab。这被称为贪婪匹配。</p>
<p>有时，我们更需要懒惰匹配，也就是匹配<strong>尽可能少</strong>的字符。前面给出的限定符都可以被转化为懒惰匹配模式，只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复，但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧：</p>
<p>a.*?b匹配最短的，以a开始，以b结束的字符串。如果把它应用于aabab的话，它会匹配aab（第一到第三个字符）和ab（第四到第五个字符）。</p>
<p>为什么第一个匹配是aab（第一到第三个字符）而不是ab（第二到第三个字符）？简单地说，因为正则表达式有另一条规则，比懒惰／贪婪规则的优先级更高：最先开始的匹配拥有最高的优先权——The match that begins earliest wins。</p>
<table cellspacing="0">
    <caption>表5.懒惰限定符</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>*?</td>
            <td>重复任意次，但尽可能少重复</td>
        </tr>
        <tr>
            <td>+?</td>
            <td>重复1次或更多次，但尽可能少重复</td>
        </tr>
        <tr>
            <td>??</td>
            <td>重复0次或1次，但尽可能少重复</td>
        </tr>
        <tr>
            <td>{n,m}?</td>
            <td>重复n到m次，但尽可能少重复</td>
        </tr>
        <tr>
            <td>{n,}?</td>
            <td>重复n次以上，但尽可能少重复</td>
        </tr>
    </tbody>
</table>
<h2 id="regexoptions">处理选项</h2>
<p>在C#中，你可以使用<a href="http://msdn2.microsoft.com/zh-cn/library/h5845fdz.aspx" title="MSDN 相关文档">Regex(String, RegexOptions)构造函数</a>来设置正则表达式的处理选项。如：Regex regex = new Regex(""ba"w{6}"b", RegexOptions.IgnoreCase);</p>
<p>上面介绍了几个选项如忽略大小写，处理多行等，这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项：</p>
<table cellspacing="0">
    <caption>表6.常用的处理选项</caption>
    <thead>
        <tr>
            <th scope="col">名称</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>IgnoreCase(忽略大小写)</td>
            <td>匹配时不区分大小写。</td>
        </tr>
        <tr>
            <td>Multiline(多行模式)</td>
            <td>更改^和$的含义，使它们分别在任意一行的行首和行尾匹配，而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配"n之前的位置以及字符串结束前的位置.) </td>
        </tr>
        <tr>
            <td>Singleline(单行模式)</td>
            <td>更改.的含义，使它与每一个字符匹配（包括换行符"n）。 </td>
        </tr>
        <tr>
            <td>IgnorePatternWhitespace(忽略空白)</td>
            <td>忽略表达式中的非转义空白并启用由#标记的注释。</td>
        </tr>
        <tr>
            <td>RightToLeft(从右向左查找)</td>
            <td>匹配从右向左而不是从左向右进行。</td>
        </tr>
        <tr>
            <td>ExplicitCapture(显式捕获)</td>
            <td>仅捕获已被显式命名的组。</td>
        </tr>
        <tr>
            <td>ECMAScript(JavaScript兼容模式)</td>
            <td>使表达式的行为与它在JavaScript里的行为一致。</td>
        </tr>
    </tbody>
</table>
<p>一个经常被问到的问题是：是不是只能同时使用多行模式和单行模式中的一种？答案是：不是。这两个选项之间没有任何关系，除了它们的名字比较相似（以至于让人感到疑惑）以外。</p>
<h2 id="balancedgroup">平衡组/递归匹配</h2>
<p note="">这里介绍的平衡组语法是由.Net Framework支持的；其它语言／库不一定支持这种功能，或者支持此功能但需要使用不同的语法。</p>
<p>有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构，这时简单地使用"(.+")则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式，懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等，比如( 5 / ( 3 + 2 ) ) )，那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的，配对的括号之间的内容呢？</p>
<p>为了避免(和"(把你的大脑彻底搞糊涂，我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx &lt;aa &lt;bbb&gt; &lt;bbb&gt; aa&gt; yy这样的字符串里，最长的配对的尖括号内的内容捕获出来？</p>
<p>这里需要用到以下的语法构造：</p>
<ul>
    <li>(?'group') 把捕获的内容命名为group,并压入堆栈(Stack)</li>
    <li>(?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容，如果堆栈本来为空，则本分组的匹配失败</li>
    <li>(?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话，继续匹配yes部分的表达式，否则继续匹配no部分</li>
    <li>(?!) 零宽负向先行断言，由于没有后缀表达式，试图匹配总是失败</li>
</ul>
<p>如
果你不是一个程序员（或者你自称程序员但是不知道堆栈是什么东西），你就这样理解上面的三种语法吧：第一个就是在黑板上写一个"group"，第二个就是
从黑板上擦掉一个"group"，第三个就是看黑板上写的还有没有"group"，如果有就继续匹配yes部分，否则就匹配no部分。</p>
<p>我们需要做的是每碰到了左括号，就在压入一个"Open",每碰到一个右括号，就弹出一个，到了最后就看看堆栈是否为空－－如果不为空那就证明左括号比右括号多，那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符)，尽量使整个表达式得到匹配。</p>
<pre>&lt;                         #最外层的左括号<br />
[^&lt;&gt;]*                #最外层的左括号后面的不是括号的内容<br />
(<br />
(<br />
(?'Open'&lt;)    #碰到了左括号，在黑板上写一个"Open"<br />
[^&lt;&gt;]*       #匹配左括号后面的不是括号的内容<br />
)+<br />
(<br />
(?'-Open'&gt;)   #碰到了右括号，擦掉一个"Open"<br />
[^&lt;&gt;]*        #匹配右括号后面不是括号的内容<br />
)+<br />
)*<br />
(?(Open)(?!))         #在遇到最外层的右括号前面，判断黑板上还有没有没擦掉的"Open"；如果还有，则匹配失败<br />
&gt;                         #最外层的右括号</pre>
<p>平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的&lt;div&gt;标签：&lt;div[^&gt;]*&gt;[^&lt;&gt;]*(((?'Open'&lt;div[^&gt;]*&gt;)[^&lt;&gt;]*)+((?'-Open'&lt;/div&gt;)[^&lt;&gt;]*)+)*(?(Open)(?!))&lt;/div&gt;.</p>
<h2 id="more">还有些什么东西没提到</h2>
<p>我已经描述了构造正则表达式的大量元素，还有一些我没有提到的东西。下面是未提到的元素的列表，包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN
Library,你也可以在里面找到关于.net下正则表达式详细的文档。</p>
<table cellspacing="0">
    <caption>表7.尚未详细讨论的语法</caption>
    <thead>
        <tr>
            <th scope="col">代码/语法</th>
            <th scope="col">说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>"a</td>
            <td>报警字符(打印它的效果是电脑嘀一声)</td>
        </tr>
        <tr>
            <td>"b</td>
            <td>通常是单词分界位置，但如果在字符类里使用代表退格</td>
        </tr>
        <tr>
            <td>"t</td>
            <td>制表符，Tab</td>
        </tr>
        <tr>
            <td>"r</td>
            <td>回车</td>
        </tr>
        <tr>
            <td>"v</td>
            <td>竖向制表符</td>
        </tr>
        <tr>
            <td>"f</td>
            <td>换页符</td>
        </tr>
        <tr>
            <td>"n</td>
            <td>换行符</td>
        </tr>
        <tr>
            <td>"e</td>
            <td>Escape</td>
        </tr>
        <tr>
            <td>"0nn</td>
            <td>ASCII代码中八进制代码为nn的字符</td>
        </tr>
        <tr>
            <td>"xnn</td>
            <td>ASCII代码中十六进制代码为nn的字符</td>
        </tr>
        <tr>
            <td>"unnnn</td>
            <td>Unicode代码中十六进制代码为nnnn的字符</td>
        </tr>
        <tr>
            <td>"cN</td>
            <td>ASCII控制字符。比如"cC代表Ctrl+C</td>
        </tr>
        <tr>
            <td>"A</td>
            <td>字符串开头(类似^，但不受处理多行选项的影响)</td>
        </tr>
        <tr>
            <td>"Z</td>
            <td>字符串结尾或行尾(不受处理多行选项的影响)</td>
        </tr>
        <tr>
            <td>"z</td>
            <td>字符串结尾(类似$，但不受处理多行选项的影响)</td>
        </tr>
        <tr>
            <td>"G</td>
            <td>当前搜索的开头</td>
        </tr>
        <tr>
            <td>"p{name}</td>
            <td>Unicode中命名为name的字符类，例如"p{IsGreek}</td>
        </tr>
        <tr>
            <td>(?&gt;exp)</td>
            <td>贪婪子表达式</td>
        </tr>
        <tr>
            <td>(?&lt;x&gt;-&lt;y&gt;exp)</td>
            <td>平衡组</td>
        </tr>
        <tr>
            <td>(?im-nsx:exp)</td>
            <td>在子表达式exp中改变处理选项</td>
        </tr>
        <tr>
            <td>(?im-nsx)</td>
            <td>为表达式后面的部分改变处理选项</td>
        </tr>
        <tr>
            <td>(?(exp)yes|no)</td>
            <td>把exp当作零宽正向先行断言，如果在这个位置能匹配，使用yes作为此组的表达式；否则使用no</td>
        </tr>
        <tr>
            <td>(?(exp)yes)</td>
            <td>同上，只是使用空表达式作为no</td>
        </tr>
        <tr>
            <td>(?(name)yes|no)</td>
            <td>如果命名为name的组捕获到了内容，使用yes作为表达式；否则使用no</td>
        </tr>
        <tr>
            <td>(?(name)yes)</td>
            <td>同上，只是使用空表达式作为no</td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/libin2722/aggbug/252901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-02-02 08:44 <a href="http://www.blogjava.net/libin2722/articles/252901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>将任意格式转换为JSON数据格式的工具类</title><link>http://www.blogjava.net/libin2722/articles/250005.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Mon, 05 Jan 2009 15:11:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/250005.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/250005.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/250005.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/250005.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/250005.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;package&nbsp;org.sjw.utils;import&nbsp;java.beans.IntrospectionException;import&nbsp;java.beans.Introspector;import&nbsp;java.beans.PropertyDescriptor;import&nbsp;java.util.List;im...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/250005.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/250005.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-01-05 23:11 <a href="http://www.blogjava.net/libin2722/articles/250005.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HTTP/1.1 Cache-Control的理解 </title><link>http://www.blogjava.net/libin2722/articles/250004.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Mon, 05 Jan 2009 15:06:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/250004.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/250004.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/250004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/250004.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/250004.html</trackback:ping><description><![CDATA[网页的缓存是由HTTP消息头中的&#8220;Cache-control&#8221;来控制的，常见的取值有private、no-cache、max-age、must-revalidate等，默认为private。其作用根据不同的重新浏览方式分为以下几种情况：<br />
<strong>（1） 打开新窗口</strong><br />
如果指定cache-control的值为private、no-cache、must-revalidate，那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值，那么在此值内的时间里就不会重新访问服务器，例如：<br />
<font face="Verdana, Geneva, Arial, Sans-serif" color="#000080">Cache-control: max-age=5</font><br />
表示当访问此网页后的5秒内再次访问不会去服务器<br />
<strong>（2） 在地址栏回车</strong><br />
如果值为private或must-revalidate（和网上说的不一样），则只有第一次访问时会访问服务器，以后就不再访问。如果值为no-cache，那么每次都会访问。如果值为max-age，则在过期之前不会重复访问。<br />
<strong>（3） 按后退按扭</strong><br />
如果值为private、must-revalidate、max-age，则不会重访问，而如果为no-cache，则每次都重复访问<br />
<strong>（4） 按刷新按扭<br />
</strong>无论为何值，都会重复访问 <br />
<img height="366" alt="" src="http://www.blogjava.net/images/blogjava_net/dashi99/a.jpg" width="515" border="0" /><br />
<br />
项目中使用过滤器来设置网页的缓存<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">FilterConfig&nbsp;fc;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doFilter(ServletRequest&nbsp;req,&nbsp;ServletResponse&nbsp;res,<br />
<img id="Codehighlighter1_153_583_Open_Image" onclick="this.style.display='none'; Codehighlighter1_153_583_Open_Text.style.display='none'; Codehighlighter1_153_583_Closed_Image.style.display='inline'; Codehighlighter1_153_583_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_153_583_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_153_583_Closed_Text.style.display='none'; Codehighlighter1_153_583_Open_Image.style.display='inline'; Codehighlighter1_153_583_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterChain&nbsp;chain)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;IOException,&nbsp;ServletException&nbsp;</span><span id="Codehighlighter1_153_583_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_153_583_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse&nbsp;response&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(HttpServletResponse)&nbsp;res;<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;set&nbsp;the&nbsp;provided&nbsp;HTTP&nbsp;response&nbsp;parameters</span><span style="color: #008000"><br />
<img id="Codehighlighter1_353_498_Open_Image" onclick="this.style.display='none'; Codehighlighter1_353_498_Open_Text.style.display='none'; Codehighlighter1_353_498_Closed_Image.style.display='inline'; Codehighlighter1_353_498_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_353_498_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_353_498_Closed_Text.style.display='none'; Codehighlighter1_353_498_Open_Image.style.display='inline'; Codehighlighter1_353_498_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(Enumeration&nbsp;e&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;fc.getInitParameterNames();&nbsp;e.hasMoreElements();)&nbsp;</span><span id="Codehighlighter1_353_498_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_353_498_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;headerName&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(String)&nbsp;e.nextElement();<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.addHeader(headerName,&nbsp;fc.getInitParameter(headerName));<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;pass&nbsp;the&nbsp;request/response&nbsp;on</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(req,&nbsp;response);<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span></div>
<br />
配置文件的配置：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">NoCache</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">filter.CacheFilter</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Cache-Control</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">no-cache,&nbsp;must-revalidate</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">CacheForWeek</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">filter.CacheFilter</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-class</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Cache-Control</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">max-age=604800</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">param-value</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">init-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">CacheForWeek</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">*.js</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">CacheForWeek</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">*.css</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;<br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">CacheForWeek</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-name</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">*.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">url-pattern</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">filter-mapping</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;</span></div>
<br />
上述设置保存了1周的缓存。<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/250004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2009-01-05 23:06 <a href="http://www.blogjava.net/libin2722/articles/250004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat下绑定JMS应用服务器的实例讲解</title><link>http://www.blogjava.net/libin2722/articles/249367.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 31 Dec 2008 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/249367.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/249367.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/249367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/249367.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/249367.html</trackback:ping><description><![CDATA[<p><span id="zoom">
<p>JMS做为J2EE的高级部分一直蒙着一层神秘的面纱，作为JMS的定制者SUN只规定了JMS规范，象很多其他SUN产品一样被多家厂商提供了具
体的实现。但是作为tomcat和RESIN（今年初宣布全部支持J2EE规范）。这些面向低端但却被广泛应用的服务器本身并不对JMS提供支持。庆幸的
是openjms和activeMQ两家开源软件提供了插件式的支持。 </p>
<p>在应用了一些开发框架如spring的项目里如果要使用到JMS，虽然SPRING提供了部分对JMS的支持但经过我一段时间的应用发
现，OO的封装在某些地方反而成为开发过程中的障碍。在实现诸如监听之类的代码段里使人非常的懊恼，即使用callback(回调)有些东西仍然不能够很
好的被取到。 </p>
<p>下面就一些TOMCAT上面JMS的支持既实现做一下整理。
</p>
<p>1.很自然的你需要下载JMS实现,如:opnerJMS或者activeMQ .下载地址www.jmsopen.com 或www.activeMQ.com
</p>
<p>2.服务器下载以后的具体配置在以上两个网站上都有很详细的说明，就不再列举了。
</p>
<p>3.和WEB服务器的整合，首先要配置应用的web.xml这个文件配置如下：
</p>
<center><ccid_nobr>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td style="font-size: 9pt;" bgcolor="#e6e6e6">
            <pre><ccid_code>1  &lt;context-param&gt;<br />
            2  &lt;param-name&gt;brokerURI&lt;/param-name&gt;<br />
            3  &lt;param-value&gt;/WEB-INF/activemq.xml&lt;/param-value&gt;<br />
            4  &lt;/context-param&gt;<br />
            5<br />
            6  &lt;listener&gt;<br />
            7  &lt;listener-class&gt;org.activemq.web.SpringBrokerContextListener&lt;/listener-class&gt;<br />
            8  &lt;/listener&gt;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr></center>
<p>将这一段代码放到web.xml里。注意到activemq.xml文件，是jms服务器的具体配置：
</p>
<center><ccid_nobr>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td style="font-size: 9pt;" bgcolor="#e6e6e6">
            <pre><ccid_code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
            &lt;!DOCTYPE beans PUBLIC <br />
            "-//ACTIVEMQ//DTD//EN" <br />
            "http://activemq.org/dtd/activemq.dtd"&gt;<br />
            &lt;beans&gt;<br />
            <br />
            &lt;!-- ===================== --&gt;<br />
            &lt;!-- ActiveMQ Broker Configuration --&gt;<br />
            &lt;!-- ===================== --&gt;<br />
            &lt;broker&gt;<br />
            &lt;connector&gt;<br />
            &lt;tcpServerTransport <br />
            uri="tcp://localhost:61616" <br />
            useAsyncSend="true"<br />
            maxOutstandingMessages="50"/&gt;<br />
            &lt;/connector&gt;<br />
            <br />
            &lt;!-- to enable Stomp support uncomment this<br />
            &lt;connector&gt;<br />
            &lt;serverTransport <br />
            uri="stomp://localhost:61626"/&gt;<br />
            &lt;/connector&gt;<br />
            --&gt;<br />
            <br />
            &lt;persistence&gt;<br />
            &lt;jdbcPersistence<br />
            dataSourceRef="oracle-ds"/&gt;<br />
            &lt;/persistence&gt;<br />
            &lt;/broker&gt;<br />
            <br />
            &lt;!-- ======================= --&gt;<br />
            &lt;!-- JDBC DataSource Configurations --&gt;<br />
            &lt;!-- ======================= --&gt;<br />
            <br />
            &lt;!-- The Derby Datasource <br />
            that will be used by the Broker --&gt;<br />
            &lt;bean id="derby-ds" class=<br />
            "org.apache.commons.dbcp.BasicDataSource"<br />
            destroy-method="close"&gt;<br />
            &lt;property name="driverClassName"&gt;<br />
            &lt;value&gt;<br />
            org.apache.derby.jdbc.EmbeddedDriver<br />
            &lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="url"&gt;<br />
            &lt;!-- Use a URL like <br />
            'jdbc:hsqldb:hsql://localhost:9001' <br />
            if you want to connect to a remote hsqldb --&gt;<br />
            &lt;value&gt;<br />
            jdbc:derby:derbydb;create=true<br />
            &lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="username"&gt;<br />
            &lt;value&gt;&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="password"&gt;<br />
            &lt;value&gt;&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;property name="poolPreparedStatements"&gt;<br />
            &lt;value&gt;true&lt;/value&gt;<br />
            &lt;/property&gt;<br />
            &lt;/bean&gt;<br />
            &lt;/beans&gt;</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</ccid_nobr></center>
<p>此时，在启动你的TOMCAT的时候会看到JMS服务器已经绑到了上面。</p>
</span></p>
<img src ="http://www.blogjava.net/libin2722/aggbug/249367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-31 18:07 <a href="http://www.blogjava.net/libin2722/articles/249367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(转载)将任意格式转换为JSON数据格式的工具类</title><link>http://www.blogjava.net/libin2722/articles/249077.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Tue, 30 Dec 2008 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/249077.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/249077.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/249077.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/249077.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/249077.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: package&nbsp;org.sjw.utils;import&nbsp;java.beans.IntrospectionException;import&nbsp;java.beans.Introspector;import&nbsp;java.beans.PropertyDescriptor;import&nbsp;java.util.List;import&nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/249077.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/249077.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-30 10:57 <a href="http://www.blogjava.net/libin2722/articles/249077.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA加密算法简介</title><link>http://www.blogjava.net/libin2722/articles/247019.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 18 Dec 2008 00:52:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/247019.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/247019.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/247019.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/247019.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/247019.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 通常,使用的加密算法&nbsp;比较简便高效,密钥简短，加解密速度快，破译极其困难。本文介绍了&nbsp;MD5/SHA1，DSA，DESede/DES，Diffie-Hellman的使用。　　第1章基础知识　　1.1.&nbsp;单钥密码体制　　单钥密码体制是一种传统的加密算法，是指信息的发送方和接收方共同使用同一把密钥进行加解密。　　通常,使用的加密算法比较简便高效,密钥简短，...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/247019.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/247019.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-18 08:52 <a href="http://www.blogjava.net/libin2722/articles/247019.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>url加密参数 （java版）</title><link>http://www.blogjava.net/libin2722/articles/247018.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 18 Dec 2008 00:51:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/247018.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/247018.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/247018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/247018.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/247018.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">**</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #000000;">*</span><span style="color: #000000;">加密解密类<br />
</span><span style="color: #000000;">*</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">*</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">*</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;com.abacus.common&nbsp;;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.security.&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.crypto.&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">;<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
*加密解密类<br />
<br />
</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Eryptogram&nbsp;<br />
{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;String&nbsp;Algorithm&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">DES</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">定义加密算法,可用DES,DESede,Blowfish</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;debug&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;*构造子注解.<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Eryptogram&nbsp;()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;*生成密钥<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@returnbyte[]返回生成的密钥<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@throwsexception扔出异常.<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]getSecretKey&nbsp;()</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyGenerator&nbsp;keygen&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">KeyGenerator.getInstance&nbsp;(Algorithm&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecretKey&nbsp;deskey&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">keygen.generateKey&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(debug&nbsp;)System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">生成密钥:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">byte2hex&nbsp;(deskey.getEncoded&nbsp;()));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;deskey.getEncoded&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;*将指定的数据根据提供的密钥进行加密<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@paraminput需要加密的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@paramkey密钥<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@returnbyte[]加密后的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@throwsException<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]encryptData&nbsp;(</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]input&nbsp;,</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]key&nbsp;)</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecretKey&nbsp;deskey&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;javax.crypto.spec.SecretKeySpec&nbsp;(key&nbsp;,Algorithm&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(debug&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">加密前的二进串:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">byte2hex&nbsp;(input&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">加密前的字符串:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String&nbsp;(input&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cipher&nbsp;c1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">Cipher.getInstance&nbsp;(Algorithm&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c1.init&nbsp;(Cipher.ENCRYPT_MODE&nbsp;,deskey&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]cipherByte&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">c1.doFinal&nbsp;(input&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(debug&nbsp;)System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">加密后的二进串:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">byte2hex&nbsp;(cipherByte&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;cipherByte&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;*将给定的已加密的数据通过指定的密钥进行解密<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@paraminput待解密的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@paramkey密钥<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@returnbyte[]解密后的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@throwsException<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]decryptData&nbsp;(</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]input&nbsp;,</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]key&nbsp;)</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecretKey&nbsp;deskey&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;javax.crypto.spec.SecretKeySpec&nbsp;(key&nbsp;,Algorithm&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(debug&nbsp;)System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">解密前的信息:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">byte2hex&nbsp;(input&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cipher&nbsp;c1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">Cipher.getInstance&nbsp;(Algorithm&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c1.init&nbsp;(Cipher.DECRYPT_MODE&nbsp;,deskey&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]clearByte&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">c1.doFinal&nbsp;(input&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(debug&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">解密后的二进串:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">byte2hex&nbsp;(clearByte&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">解密后的字符串:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String&nbsp;(clearByte&nbsp;)));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;clearByte&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;*字节码转换成16进制字符串<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@parambyte[]b输入要转换的字节码<br />
&nbsp;&nbsp;&nbsp;&nbsp;*@returnString返回转换后的16进制字符串<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;String&nbsp;byte2hex&nbsp;(</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]b&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;hs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">""</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;stmp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">""</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;n&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;;n&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">b.length&nbsp;;n&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stmp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">(java.lang.Integer.toHexString&nbsp;(b&nbsp;[n&nbsp;]</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">0XFF</span><span style="color: #000000;">&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(stmp.length&nbsp;()</span><span style="color: #000000;">==</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;)hs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">hs&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">0</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">stmp&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;hs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">hs&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">stmp&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(n&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">b.length&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;)hs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">hs&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;hs.toUpperCase&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main&nbsp;(String&nbsp;[]args&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&nbsp;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eryptogram&nbsp;etg&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Eryptogram&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]key&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">etg.getSecretKey&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">key=</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">key&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;aa&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">1234567</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]data&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">aa.getBytes&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(data&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]en&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">etg.encryptData&nbsp;(data&nbsp;,key&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">encryptData=</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String&nbsp;(en&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">&nbsp;[]de&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">etg.decryptData&nbsp;(en&nbsp;,key&nbsp;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println&nbsp;(</span><span style="color: #000000;">"</span><span style="color: #000000;">decryptData=</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String&nbsp;(de&nbsp;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(Exception&nbsp;e&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<img src="http://www.blogjava.net/Images/dot.gif"  alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace&nbsp;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<img src ="http://www.blogjava.net/libin2722/aggbug/247018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-18 08:51 <a href="http://www.blogjava.net/libin2722/articles/247018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FreeMarker学习笔记</title><link>http://www.blogjava.net/libin2722/articles/245700.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 11 Dec 2008 06:34:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/245700.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/245700.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/245700.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/245700.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/245700.html</trackback:ping><description><![CDATA[１.	模板＋数据模型＝输出
<br />
２.	数据模型
<br />
a)	类似目录的变量称为hashes,包含保存下级变量的唯一的查询名字,充当其它对象的容器,每个都关联唯一的查询名字
<br />
b)	类似文件的变量称为scalars,保存单值,有两种类型
<br />
i.	字符串:用引号括起,单引号or双引号
<br />
ii.	数字:不用引号
<br />
iii.	日期:可以是日期,时间或日期-时间
<br />
iv.	布尔值:true或false,通常在&lt;#if &#8230;&gt;标记中使用
<br />
v.	对scalars的访问从root开始,各部分用&#8221;.&#8221;分隔,如 animals.mouse.price
<br />
c)	另外一种变量是sequences,和hashes类似,充当其它对象的容器,按次序访问,只是不使用变量名字,而使用数字索引,如animals[0].name,索引值从0开始
<br />
d)	通常每个变量具有上述的一种能力,但一个变量可以具有多种上述能力
<br />
e)	方法
<br />
i.	${avg(3,5,20)}	${avg(student.zhangyaang.age,student.situ.age)}
<br />
f)	宏和变换器:用户自定义的指令(FTL标记)
<br />
g)	节点:树形结构中的一个节点,常用于xml处理中
<br />
３.	模板
<br />
a)	文本:直接输出
<br />
b)	${&#8230;}:称为interpolations,FreeMarker会在输出时用实际值代替,或#{},只用于文本中
<br />
c)	FTL标记:类似于HTML,为了与HTML区分,用#开始,有的以@开始,不会输出,区分大小写,FTL标记不能位于另一个FTL标记内部
<br />
d)	注释:&lt;#--和--&gt;,不会输出
<br />
e)	多余的空白字符会在模板输出时移除
<br />
f)	指令
<br />
i.	使用FTL标记引用指令,有三种FTL标记
<br />
1.	开始标记:&lt;#name prarm&gt;
<br />
2.	结束标记:&lt;/#name&gt;
<br />
3.	空内容指令标记:&lt;#name param /&gt;
<br />
ii.	有两种类型的指令:预定义指令和用户定义指令,用户定义指令要用@替换#
<br />
iii.	FTL标记不能够交叉,应该正确嵌套
<br />
iv.	如果使用不存在的指令,FreeMarker会产生错误消息
<br />
v.	&lt; , &lt;/ 和指令间不允许有空白字符
<br />
g)	表达式
<br />
i.	字符串
<br />
1.	使用单引号或双引号限定
<br />
2.	特殊字符要转义
<br />
3.	raw字符串,可以认为是文本,其中的$和{等不具有特殊含义,该类字符串在引号前面加r,如${r&#8221;${foo}&#8221;}	${r&#8221;c:"foo"bar&#8221;}
<br />
ii.	数字
<br />
1.	直接输入,不需要引号
<br />
2.	精度数字使用&#8221;.&#8221;分隔,不能使用分组符号
<br />
3.	不支持科学计数法
<br />
4.	不能省略小数点前面的0
<br />
5.	数字8 ,+8 ,08和8.00 都是相同的
<br />
iii.	布尔值:true 和 false, 不使用引号
<br />
iv.	序列
<br />
1.	有逗号分隔的子变量列表,有方括号限定,如:
<br />
&lt;#list [&#8220;winter&#8221;, &#8221;spring&#8221;, &#8221;summer&#8221;, &#8221;autumn&#8221;] as x&gt;
<br />
${x}
<br />
&lt;/#list&gt;
<br />
2.	列表的项目是表达式,如:
<br />
[2+2, [1,2,3,4], &#8221;whatnot&#8221;]
<br />
3.	可以使用数字范围定义数字序列,如:
<br />
2..5等同于[2,3,4,5]	注意:数字范围没有方括号	如:5..2
<br />
4.	散列(hash)	由逗号的键/值列表,有大括号限定,键和值之间用冒号分隔
<br />
{&#8220;name&#8221;:&#8221;zhangyang&#8221;,&#8221;age&#8221;:23}	键和值都是表达式,但键必须是字符串
<br />
v.	获取变量
<br />
1.	顶层变量:${variable}, 变量名只能是字母, 数字, 下划线, $, @ 和# 的组合, 不能以数字开头
<br />
2.	从散列中获取数据
<br />
a)	school.student.name
<br />
b)	school.[&#8220;student&#8221;].name
<br />
c)	school[&#8220;student&#8221;][&#8220;name&#8221;]
<br />
说明:使用点语法,变量名有顶层变量一样的限制, 方括号语法没有该限制
<br />
3.	从序列获(sequences)得数据: 和散列的方括号语法一样, 只是方括号的表达式值必须是数字; 注意: 第一个项目的索引是0
<br />
4.	序列片段: 使用[startIndex..endIndex]语法, 从序列中获得片段(也是序列)
<br />
5.	特殊变量: FreeMarker内定义的变量, 使用 .variablenae 语法访问
<br />
vi.	字符串操作
<br />
1.	Interpolation(或连接操作)
<br />
a)	可以使用${..} 或#{..} 在文本部分插入表达式的值,
<br />
如${&#8220;Hello ${user}&#8221;} 等于 ${&#8220;Hello&#8221;+user}
<br />
b)	${..} 只能用于文本部分, 不用于FTL表达式中
<br />
2.	子串
<br />
假设user的值为&#8221;tom cat&#8221;
<br />
${user[0]}${user[4]}  tc
<br />
${user[1..4]}  om c
<br />
vii.	序列操作
<br />
连接操作: 和字符串一样, 用&#8221;+&#8221;
<br />
&lt;#list [&#8220;joe&#8221;,&#8221;fred&#8221;] + [&#8220;julia&#8221;,&#8221;kate&#8221;] as user&gt;
<br />
${user}
<br />
&lt;/#list&gt;
<br />
viii.	散列操作
<br />
连接操作: 和字符串一样, 用&#8221;+&#8221;, 如果有相同的key, 右边的值替换左边的值(后面的替换前面的), 如
<br />
&lt;#assign ages = {&#8220;joe&#8221;:23,&#8221;fred&#8221;:25} + {&#8220;joe&#8221;:30,&#8221;julia&#8221;:23}&gt;
<br />
&lt;/#assign&gt;	结果: joe的值为30
<br />
ix.	算术运算
<br />
1.	+, -- , *, /, %
<br />
${x / 2}
<br />
2.	操作符两边必须是数字
<br />
3.	使用 &#8220;+&#8221; 操作符时,如果一边是数字, 一边是字符串, 就会自动将数字转换为字符串, 如: ${3+&#8221;4&#8221;} 结果 34
<br />
4.	使用内建的 int 获得整数部分
<br />
${1.1?int} 1
<br />
${1.999?int} 1
<br />
${(5/2)?int} 2
<br />
5.	比较操作符
<br />
a)	使用=(或==,完全相等)测试两个值是否相等, 使用!=测试两个值是否不相等
<br />
b)	= 和!= 两边必须是相同类型的值
<br />
c)	FreeMarker是精确比较,&#8221;x&#8221;,&#8221;x &#8220;和&#8221;x&#8221;是不等的
<br />
d)	对数字和日期可以使用&lt;, &lt;=, &gt;, 和&gt;=, 但不用用于字符串
<br />
e)	由于FreeMarker 会将&gt;解释成FTL标记的结束字符, 所以对于&gt;和&gt;=可以使用括号来避免这种情况, 如&lt;#if (x &gt; y)&gt;
<br />
f)	e)的一种替代方法, 使用lt, lte, gt 和gte来替代
<br />
6.	逻辑操作符
<br />
a)	&amp;&amp;(and), ||(or), !(not), 只能用于布尔值
<br />
&lt;#if x &lt; 13 &amp;&amp; color = &#8220;green&#8221;&gt;
<br />
&#8230;
<br />
&lt;/#if&gt;
<br />
&lt;#if ! man&gt;
<br />
woman
<br />
&lt;/#if&gt;
<br />
7.	内建函数
<br />
a)	内建函数的用法类似访问散列的子变量, 只是用&#8221;?&#8221;|替代&#8221;,&#8221;
<br />
b)	用于字符串
<br />
i.	html: 对字符串进行html编码
<br />
ii.	cap_first: 将字符串转换成第一个字母大写
<br />
iii.	lower_case: 小写
<br />
iv.	upper_case: 大写
<br />
v.	trim: 去掉字符串前后的空白字符
<br />
c)	用于序列
<br />
i.	size: 获得序列中元素的数目
<br />
d)	用于数字
<br />
i.	int: 取得数字的整数部分
<br />
e)	例子:
<br />
test = &#8220;tom &amp; jerry&#8221;
<br />
${test?html}  tom &amp;amp; jerry
<br />
${test?upper_case?html}  TOM &amp;amp; JERRY
<br />
8.	操作符优先顺序
<br />
h)	Interpolation(只用于文本部分)
<br />
i.	Interpolation有两种类型
<br />
1.	通用Interpolation: ${expr}
<br />
a)	插入字符串值: 直接输出表达式结果
<br />
b)	插入数字值: 根据缺省格式(由#setting指令设置)将表达式转换成文本输出; 可以使用内建函数string格式化单个Interpolation
<br />
c)	例子
<br />
&lt;#setting number_format=&#8221;currency&#8221;/&gt; 金额
<br />
&lt;#assign answer=43/&gt;
<br />
${answer}  $43.00
<br />
${answer?string} $43.00
<br />
${answer?string.number} 43
<br />
${answer?string.currency} $43.00
<br />
${answer?string.percent} 4,300%
<br />
2.	数字Interpolation: ${expr} 或#{expr ; format}
<br />
3.	插入日期: 根据缺省格式(#setting) 将表达式结果转换成文本输出; 可以使用内建的函数string 格式化单个Interpolation, 例子:
<br />
${update?string(&#8220;yyyy-MM-dd HH:mm:ss zzzz&#8221;)}
<br />
4.	插入布尔值: 说明同上
<br />
&lt;#assign foo = true/&gt;
<br />
${foo?string(&#8220;yes&#8221;,&#8221;no&#8221;)}	yes
<br />
5.	数字Interpolation的#{expr ; format}形式可以用来格式化数字, format可以是
<br />
a)	mX: 小数部分最小X位
<br />
b)	MX: 小数部分最大X位
<br />
c)	例子
<br />
&lt;#assign x=2.364/&gt;
<br />
&lt;#assign y=4/&gt;
<br />
#{x; M2}	2.36
<br />
#{y; M2} 4
<br />
#{x; m1}	2.4
<br />
#{y; m1} 4.0
<br />
i)	例子
<br />
i.	if指令
<br />
&lt;#if zhangyang.age &lt; situ.age&gt;
<br />
Situ is order
<br />
&lt;#else&gt;
<br />
Zhangyang is order
<br />
&lt;/#if&gt;
<br />
ii.	list指令		&lt;#list students[0..5] as s_list&gt;&lt;/#list&gt;取list的前5条记录
<br />
&lt;table border = &#8220;1&#8221;&gt;
<br />
&lt;tr&gt;
<br />
&lt;td&gt;name&lt;/td&gt;&lt;td&gt;age&lt;/td&gt;
<br />
&lt;#list students as s_list&gt;
<br />
&lt;td&gt;${s_list.name}&lt;/td&gt;&lt;td&gt;${s_list.age}&lt;/td&gt;
<br />
&lt;/#list&gt;
<br />
&lt;/tr&gt;
<br />
&lt;/table&gt;
<br />
iii.	include指令
<br />
&lt;#include &#8220;/all/header.html&#8221;&gt;
<br />
&#8230;
<br />
&lt;#include &#8220;/all/footer.html&#8221;&gt;
<br />
iv.	应用
<br />
&lt;table&gt;
<br />
&lt;#list students as s_list&gt;
<br />
&lt;tr&gt;
<br />
&lt;td&gt;
<br />
&lt;#if s_list.sex =&#8221;man&#8221;&gt;&lt;img src=&#8221;/img/boy.gif&#8221;/&gt;
<br />
&lt;#else&gt;&lt;img src=&#8221;/img/girl.gif/&gt;
<br />
&lt;/#if&gt;
<br />
${s_list.name}
<br />
&lt;/td&gt;
<br />
&lt;td&gt;${s_list.age}&lt;/td&gt;
<br />
&lt;/tr&gt;
<br />
&lt;/#list&gt;
<br />
&lt;/table&gt;
<br />
４.	用户自定义指令
<br />
a)	宏和变换器
<br />
b)	模板中定义变量
<br />
c)	名字空间(命名空间)
<br />
５.	应用
<br />
a)	List
<br />
i.	例子1
<br />
List scalarList = new ArrayList();
<br />
scalarList.add("red");
<br />
scalarList.add("green");
<br />
scalarList.add("blue");
<br />
scalarList.add("yellow");
<br />
root.put("scList", scalarList);
<br />
<br />
&lt;#list scList as the_value&gt;
<br />
Scalar List值:${the_value}
<br />
&lt;/#list&gt;
<br />
ii.	例子2
<br />
public class User {
<br />
private String userId;
<br />
private String userName;
<br />
}
<br />
<br />
User u1 = new User();
<br />
u1.setUserId("100");
<br />
u1.setUserName("郜司徒");
<br />
<br />
User u2 = new User();
<br />
u2.setUserId("200");
<br />
u2.setUserName("张宇伟");
<br />
<br />
User u3 = new User();
<br />
u3.setUserId("300");
<br />
u3.setUserName("冯钰凯");
<br />
<br />
User u4 = new User();
<br />
u4.setUserId("400");
<br />
u4.setUserName("苗先杰");
<br />
<br />
SimpleSequence userList = new SimpleSequence(ObjectWrapper.BEANS_WRAPPER);
<br />
userList.add(u1);
<br />
userList.add(u2);
<br />
userList.add(u3);
<br />
userList.add(u4);
<br />
<br />
root.put("userList", userList);
<br />
<br />
&lt;#list userList as list&gt;
<br />
List对象user的值:${list.userId}
<br />
List的value:${list.userName}
<br />
&lt;/#list&gt;
<br />
b)	Map
<br />
i.	例子1
<br />
SimpleHash scalarMap = new SimpleHash(ObjectWrapper.BEANS_WRAPPER);
<br />
scalarMap.put("anotherString", "aaaaaaaa");
<br />
scalarMap.put("anotherNumber", new Double(2.5555));
<br />
<br />
root.put("scMap", scalarMap);
<br />
<br />
&lt;#list scMap?keys as myKey&gt;
<br />
Map key is:${myKey}
<br />
map value is:${scMap[myKey]}
<br />
&lt;/#list&gt;
<br />
ii.	例子2
<br />
SimpleHash userMap = new SimpleHash(ObjectWrapper.BEANS_WRAPPER);
<br />
userMap.put("1", u1);
<br />
userMap.put("2", u2);
<br />
userMap.put("3", u3);
<br />
userMap.put("4", u4);
<br />
root.put("user", userMap);
<br />
<br />
&lt;#list user?keys as key1&gt;
<br />
${key1}
<br />
${user[key1].userId}
<br />
${user[key1].userName}
<br />
<br />
&lt;#assign u = "${user[key1]}"&gt;
<br />
User is :${u}
<br />
&lt;/#list&gt;
<br />
c)	List和Map
<br />
SimpleHash root = new SimpleHash(/*ObjectWrapper.BEANS_WRAPPER*/);
<br />
//			Map&lt;String,String&gt; my_map = new HashMap&lt;String,String&gt;();
<br />
SimpleHash my_map = new SimpleHash();
<br />
my_map.put("1", "ehow");
<br />
my_map.put("2", "laomiao");
<br />
my_map.put("3", "yukai");
<br />
my_map.put("zt", "北京中天诺士达");
<br />
<br />
SimpleHash my_map2 = new SimpleHash();
<br />
my_map2.put("1", "ehow2");
<br />
my_map2.put("2", "laomiao2");
<br />
my_map2.put("3", "yukai2");
<br />
my_map2.put("zt", "北京中天诺士达2");
<br />
<br />
SimpleHash my_map3 = new SimpleHash();
<br />
my_map3.put("1", "ehow3");
<br />
my_map3.put("2", "laomiao3");
<br />
my_map3.put("3", "yukai3");
<br />
my_map3.put("zt", "北京中天诺士达3");
<br />
<br />
SimpleHash my_map4 = new SimpleHash();
<br />
my_map4.put("1", "ehow4");
<br />
my_map4.put("2", "laomiao4");
<br />
my_map4.put("3", "yukai4");
<br />
my_map4.put("zt", "北京中天诺士达4");
<br />
<br />
//			List&lt;Map&gt; userList = new ArrayList&lt;Map&gt;();
<br />
<br />
SimpleSequence userList=new SimpleSequence(/*ObjectWrapper.BEANS_WRAPPER*/);
<br />
userList.add(my_map);
<br />
userList.add(my_map2);
<br />
userList.add(my_map3);
<br />
<br />
SimpleSequence userList2 = new SimpleSequence();
<br />
userList2.add(my_map4);
<br />
userList2.add(my_map4);
<br />
userList2.add(my_map4);
<br />
<br />
root.put("the_list", userList);
<br />
root.put("other_list", userList2);
<br />
<br />
&lt;div id="Layer1"&gt;
<br />
&nbsp; &lt;table border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#FF0000"&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;tr&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" height="30" align="center" bgcolor="#FFFFFF"&gt;代号&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;代号2&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;代号3&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="405" height="30" align="center" bgcolor="#FFFFFF"&gt;明细&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;/tr&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;#list the_list as list&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;tr&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" height="30" align="center" bgcolor="#FFFFFF"&gt;${list["1"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;${list["2"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;${list["3"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td height="30" align="center" bgcolor="#FFFFFF"&gt;${list.zt}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;/tr&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;/#list&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;#list other_list as list2&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;tr&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" height="30" align="center" bgcolor="#FFFFFF"&gt;${list2["1"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;${list2["2"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td width="100" align="center" bgcolor="#FFFFFF"&gt;${list2["3"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;td height="30" align="center" bgcolor="#FFFFFF"&gt;${list2["zt"]}&lt;/td&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;/tr&gt;
<br />
&nbsp;&nbsp;&nbsp; &lt;/#list&gt;
<br />
&nbsp; &lt;/table&gt;
<br />
&lt;/div&gt;
<br />
<br />
<br />
d)	与Hibernate结合
<br />
DAO
<br />
String hql = "select new map(s.s_name as s_n,s.s_addr as
s_a,h.h_addr as h_a,u.u_name as u_n) from User_school as s,User_home as
h,User_info as u where u.id=h.id and h.id=s.id";
<br />
//		String hql = "select new map(s.s_name as s_n,s.s_addr as s_a) from User_school as s";
<br />
List my = session.createQuery(hql).list();
<br />
Hello hello = new Hello();
<br />
hello.sayHello(my);
<br />
<br />
<br />
通用方法
<br />
public void sayHello(List info){
<br />
...
<br />
root.put("from_db", info);
<br />
...
<br />
}
<br />
<br />
FTL
<br />
&lt;#list from_db as db&gt;
<br />
${db.s_n}
<br />
${db.s_a}
<br />
${db.h_a}
<br />
${db.u_n}
<br />
&lt;/#list&gt;
<br />
e)	我们的项目
<br />
&lt;#assign n = list5?size /&gt;	//定义n的值为list5的大小
<br />
&lt;#if n gt 6&gt;	//如果n大于6,页面中可能要求只显示6条
<br />
&lt;#assign n = 6 /&gt;	//把n重定义为6
<br />
&lt;/#if&gt;
<br />
&lt;#if n!=0&gt;		//防止n的值为0,也可以写成&lt;#if n gt 0 &gt;
<br />
&lt;#list 0..(n-1) as i&gt;	//把前 n 条 记录赋值给 i,如果i=3,则[0,1,2]
<br />
&lt;#assign ls5 = list5[i] /&gt;	//把list5的第i个元素赋值给ls5
<br />
&lt;#assign isNew = list5Istrue[i] /&gt;
<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;tr&gt;
<br />
&lt;td height='25' class='z3'&gt;.&lt;a href='#' onclick="zw('${ls5.CIid}','905','活动展示','');"&gt;
<br />
&lt;#if ls5.CTitle?length lt 15&gt;		//如果Ctitle的长度小于15,就
<br />
${ls5.CTitle}				//就正常显示该标题
<br />
&lt;#else&gt;							//如果大于15
<br />
${ls5.CTitle[0..15]}...		//就截取前15个,并加上&#8230;
<br />
&lt;/#if&gt;
<br />
&lt;#if isNew="true"&gt;
<br />
&lt;img src='/model/img/new-111.gif' width='27' height='11' border='0' /&gt;
<br />
&lt;/#if&gt;
<br />
&lt;/a&gt;&lt;/td&gt;
<br />
&lt;/tr&gt;
<br />
&lt;/#list&gt;
<br />
&lt;/#if&gt;
<br />
<div>
<ul>
    <li><a href="http://www.javaeye.com/topics/download/19aa6654-c7e7-3816-9465-ef7b68291c9b">FreeMarker学习笔记.rar</a> (212.9 KB)</li>
    <li>描述: 这是格式良好的pdf</li>
    <li>下载次数: 67</li>
</ul>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/245700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-11 14:34 <a href="http://www.blogjava.net/libin2722/articles/245700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>压缩/解压缩zip包处理</title><link>http://www.blogjava.net/libin2722/articles/244841.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 07 Dec 2008 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/244841.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/244841.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/244841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/244841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/244841.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;package&nbsp;com.newegg.lab.util;import&nbsp;java.io.BufferedOutputStream;import&nbsp;java.io.File;import&nbsp;java.io.FileInputStream;import&nbsp;java.io.FileNotFoundException;imp...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/244841.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/244841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-12-07 11:03 <a href="http://www.blogjava.net/libin2722/articles/244841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UUIDGenerator 主键产生器</title><link>http://www.blogjava.net/libin2722/articles/229506.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 17 Sep 2008 10:34:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/229506.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/229506.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/229506.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/229506.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/229506.html</trackback:ping><description><![CDATA[<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.newegg.lib;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.safehaus.uuid.UUIDGenerator;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_88_478_Open_Image" onclick="this.style.display='none'; Codehighlighter1_88_478_Open_Text.style.display='none'; Codehighlighter1_88_478_Closed_Image.style.display='inline'; Codehighlighter1_88_478_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_88_478_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_88_478_Closed_Text.style.display='none'; Codehighlighter1_88_478_Open_Image.style.display='inline'; Codehighlighter1_88_478_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;UUIDImpl&nbsp;</span><span id="Codehighlighter1_88_478_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_88_478_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;UUIDGenerator&nbsp;_uuidGenerator&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;UUIDGenerator.getInstance();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img id="Codehighlighter1_187_252_Open_Image" onclick="this.style.display='none'; Codehighlighter1_187_252_Open_Text.style.display='none'; Codehighlighter1_187_252_Closed_Image.style.display='inline'; Codehighlighter1_187_252_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_187_252_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_187_252_Closed_Text.style.display='none'; Codehighlighter1_187_252_Open_Image.style.display='inline'; Codehighlighter1_187_252_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;generate()&nbsp;</span><span id="Codehighlighter1_187_252_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_187_252_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_uuidGenerator.generateRandomBasedUUID().toString();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_256_279_Open_Image" onclick="this.style.display='none'; Codehighlighter1_256_279_Open_Text.style.display='none'; Codehighlighter1_256_279_Closed_Image.style.display='inline'; Codehighlighter1_256_279_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_256_279_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_256_279_Closed_Text.style.display='none'; Codehighlighter1_256_279_Open_Image.style.display='inline'; Codehighlighter1_256_279_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_256_279_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**&nbsp;*/</span><span id="Codehighlighter1_256_279_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@param</span><span style="color: #008000">&nbsp;args<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img id="Codehighlighter1_321_475_Open_Image" onclick="this.style.display='none'; Codehighlighter1_321_475_Open_Text.style.display='none'; Codehighlighter1_321_475_Closed_Image.style.display='inline'; Codehighlighter1_321_475_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_321_475_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_321_475_Closed_Text.style.display='none'; Codehighlighter1_321_475_Open_Image.style.display='inline'; Codehighlighter1_321_475_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span id="Codehighlighter1_321_475_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_321_475_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UUIDImpl&nbsp;impl&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;UUIDImpl();<br />
<img id="Codehighlighter1_425_469_Open_Image" onclick="this.style.display='none'; Codehighlighter1_425_469_Open_Text.style.display='none'; Codehighlighter1_425_469_Closed_Image.style.display='inline'; Codehighlighter1_425_469_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_425_469_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_425_469_Closed_Text.style.display='none'; Codehighlighter1_425_469_Open_Image.style.display='inline'; Codehighlighter1_425_469_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">10</span><span style="color: #000000">;&nbsp;i</span><span style="color: #000000">++</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_425_469_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_425_469_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(impl.generate());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
依赖：<br />
&lt;dependency&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;org.safehaus.jug&lt;/groupId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;artifactId&gt;jug&lt;/artifactId&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;version&gt;2.0.0&lt;/version&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/dependency&gt;
<img src ="http://www.blogjava.net/libin2722/aggbug/229506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-09-17 18:34 <a href="http://www.blogjava.net/libin2722/articles/229506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBOSS只能用localhost或127.0.0.1访问的解决办法</title><link>http://www.blogjava.net/libin2722/articles/211413.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 28 Jun 2008 12:28:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/211413.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/211413.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/211413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/211413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/211413.html</trackback:ping><description><![CDATA[今天配置了一下新版本的<span class="hilite1">JBOSS</span>，启动后发现只能使用<span class="hilite2">localhost</span>访问了，<span class="hilite3">ip</span>访问不到，查找了一下发现，4.2以上的版本不对所有本机<span class="hilite3">ip</span>进行监听了，解决办法是增加启动参数-b 192.168.x.x或-b 0.0.0.0，或者增加D<span class="hilite1">jboss</span>.bind.address=0.0.0.0参数，或者修改<span class="hilite1">jboss</span>\server\default\deploy\<span class="hilite1">jboss</span>-web.deployer\server.xml里的Connector 下面的address，把变量改成对应的<span class="hilite3">IP</span>或者0.0.0.0。 
<img src ="http://www.blogjava.net/libin2722/aggbug/211413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-06-28 20:28 <a href="http://www.blogjava.net/libin2722/articles/211413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jboss 和 JMS</title><link>http://www.blogjava.net/libin2722/articles/211412.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 28 Jun 2008 12:22:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/211412.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/211412.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/211412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/211412.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/211412.html</trackback:ping><description><![CDATA[1、介绍<br />
本章介绍在Jboss中使用Java Messageing Service (JMS). 不是JMS指南，而是JBoss和JMS如何一起使用，如果你想看JMS的介绍，请参考 JMS Specification 或 JMS turorial.<br />
最近随着JBoss版本不断更新，对JMS支持越来越成熟，也造成JBoss各个版本之间的不同。在这里我主要介绍JBoss3.0.X版本。<br />
本章给出的例子比较简单，并指出了如何使用JMS的原理。所有的例子可以通过ant build file 来建立。<br />
为了能建立和运行此例子。我们使用两种方式来进行：一是使用Ant命令，二是使用JAR和JAVA基本命令。必须有下面的环境变量：<br />
w JAVA_HOME 安装JDK1.4的目录。<br />
w JBOSS_DIST 安装JBoss的目录。<br />
你必须安装JDK, 如果使用Ant必须安装 Ant。可以参考我前面文档的介绍。<br />
2、概述<br />
1） 什么是JMS<br />
JMS是Java API, 允许应用程序来建立、接收和读取消息。程序依靠这些API, 在运行时需要一个JMS实现接口，来提供管理和控制，这被称为JMS provider, 现在有几种不同的JMS Provider; 在JBoss中的叫做JbossMQ。<br />
2） JMS 和J2EE<br />
JMS是在EJB和J2EE框架开发之前进行开发的，所以在JMS说明书中没有涉及到EJB或J2EE。<br />
EJB 和J2EE第一代版本中也没有涉及到JMS，一直到EJB1.1，在生成一个可用Beand的容器provider中JMS也不是必须的API。在J2EE1.2中JMS接口是必需的情况，但并不是非得要包含一个JMS Provider；在EJB2.0和J2EE1.3中又进行改变，应用服务器包含了一个JMS Provider，自从J2EE1。3需要EJB2.0，增加了以下两个JMS特性：<br />
w 一种新Bean类型定义， 也就是消息驱动Beam (MDB), 这种bean做为JMS消息监听者，可以异步地处理JMS消息。<br />
w JMS处理作为资源，来自一个Bean 的JMD 发布（发送）必须能和其他bean的全局事务环境共享。这个需要把JMS认为是一个容器管理资源，象JDBC的连接。<br />
3） JMS 和JBoss<br />
JBoss从2.0版本以后都支持JMS。 在2.1中增加了MDB，从2.4版本开始JMS作为一个事务资源。<br />
JBoss中JMS的体系结构如下：<br />
w JMS Provider, 叫做JbossMQ 。 是JBoss实现JMS 1.0.2规范的一部分，包括可选部分，象ASF（Application Service Facvility）。 JbossMQ处理和普遍JMS一样：建立 queues (队列)或topic(标题)，持久性等。 <br />
w MDB (Message Driven Beans), <br />
w 资源适配器。<br />
<br />
3、JMS Provider<br />
JBoss有它自己的JMS Provider 叫做JbossMQ。 适合与JMS 1.0.2 的JMS Provider，并且能用在所有平常的JMS程序中。为了清楚在JBoss中JMS是如何工作的，首先要清楚在JMS中涉及到的概念和术语，最好的办法是阅读JMS规范，下面给出了简单的JMS介绍。<br />
1) JMS的简单介绍<br />
当你发送一个消息，你不能直接发送到对此消息感兴趣的接受者。而是你发送到一个目的地。对此消息感兴趣的接受者必须连接到目的地，得到此消息或在目的地设置订阅。<br />
在JMS中有两种域：topics 和queues 。<br />
w 一个消息发送到一个topics ，可以有多个客户端。用topic发布允许一对多，或多对多通讯通道。消息的产生者被叫做publisher, 消息接受者叫做subscriber。<br />
w queue 是另外一种方式，仅仅允许一个消息传送给一个客户。一个发送者将消息放在消息队列中，接受者从队列中抽取并得到消息，消息就会在队列中消失。第一个接受者抽取并得到消息后，其他人就不能在得到它。<br />
为了能发送和接收消息，必须得到一个JMS连接。该连接是使用JMS Provider得到连接的，在得到连接之后，建立一个会话(Session)。然后再建立publisher/sender 来发送消息或subscriber/receiver来接收消息。<br />
运行时，如果使用topic 那么publisher 或subscriber 通过一个topic来关联，如果使用queue ，则sender 或receiver通过queue来关联起来。<br />
通常，在JMS框架中运转的方法如下：<br />
(1) 得到一个JNDI初始化上下文(Context)；<br />
(2) 根据上下文来查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两种连接工厂，根据是topic/queue来使用相应的类型)；<br />
(3) 从连接工厂得到一个连接(Connect 有两种[TopicConnection/ QueueConnection]);<br />
(4) 通过连接来建立一个会话(Session);<br />
(5) 查找目的地(Topic/ Queue);<br />
(6) 根据会话以及目的地来建立消息制造者(TopicPublisher/QueueSender)和消费者(TopicSubscriber/ QueueReceiver).<br />
为了得到一个连接和得到一个目的地（用来关联publisher/sender 或subscriber/receiver），必须用provider-specific参数。<br />
通过JNDI来查找相应的连接工厂或目的地，JNDI适合于任何JMS Provider。但是查找用的名字是provider使用的。因此，在你使用的JMS Provider（其中包括JBossMQ），必须学会如何进行指定。JMS Provider中的任何设置，象连接特性，用到目的地等，在用到的Provider都有明确描述。<br />
2) 配置<br />
当使用一个JMS Provider时，有三个Provider-specific因素：<br />
w 得到一个JNDI初始化上下文<br />
w 用到的连接工厂的名字。<br />
w 对目的地的管理和命名协定。<br />
JBoss同它的JNDI一起执行。为了简单的JMS client， 配置和查找初始化上下文，同实现其他J2EE客户端一样。<br />
JMS-specific 来约束JBoss 的JMS provider (JBossMQ)。JbossMQ是通过xml 文件jbossmq-service.xml进行配置的，该文件放在在serverdefaultdeploy下。<br />
在xml文件中最基本的三件事情：<br />
w 增加一个新的目的地<br />
w 配置用户<br />
w 获得可用连接工厂的名字。<br />
(1) 增加新的目的地<br />
w 在目的地的xml文件在jboss 3.x中是jbossmq-destinations-service.xml（server/../deploy）。在文件中已经存在几个缺省的目的地，所以你比较容易明白怎样增加到文件中。在例子中你需要一个topic目的地 spool，所以增加下面的语句到jbossmq-destinations-service.xml中。这种方式是长久存在的，不随着JBoss服务器关闭而消失。<br />
&lt;mbean code="org.jboss.mq.server.jmx.Topic"<br />
name="jboss.mq.destination:service=Topic,name=spool"&gt;<br />
&lt;depends optional-attribute-name="DestinationManager"&gt;jboss.mq:service=DestinationManager&lt;/depends&gt;<br />
&lt;/mbean&gt;<br />
w 另外一种方法是可以通过JMX HTML管理界面。通过http://localhost:8080/jmx-console 来访问。在jboss.mq 下查找service=DestinationManager 的连接。然后在createTopic()或createQueue()来建立，这种方法建立的目的地是临时性的，随着服务器开始存在，当当JBoss 服务器重新启动时，动态建立的目的地将会不存在。在JbossMQ中所有目的地都有一个目的地类型的前缀。对于topic前缀是topic ,对于queues前缀是queue。例如查找一个testTopic目的地，需要查找名字为&#8220;topic/testTopic&#8221;。<br />
在此种方法中有createTopic()或createQueue()分别有两种方法：一是有两个参数，二是有一个参数的。两个参数分别是：建立的目的地名称和JNDI名称。一个参数的只是目的地名称，对于JNDI名称默认是：[目的地类型(topic/queue) ]/目的地名称。<br />
在这里我们使用的是第一种方法。直接修改jbossmq-destinations-service.xml文件。<br />
(2) 管理用户<br />
在JMS中可能关联一个连接和一个用户，不幸的是没有明确的方法来限制访问JbossMQ或访问特殊的目的地到一个给定的用户。为了给大部分角色，在JbossMQ中不需要建立用户，除非想有一个持久topic订阅者。在这个例子中，用户是必须的。<br />
用户可以直接在文件jbossmq-state.xml（server/../conf）中添加。同样也可以使用JMX HTML管理界面来增加（jboss.mq-&gt;service=StateManager-&gt;addUser()）。<br />
&lt;User&gt;<br />
&lt;Name&gt;jacky&lt;/Name&gt;<br />
&lt;Password&gt;jacky&lt;/Password&gt;<br />
&lt;Id&gt;DurableSubscriberExample&lt;/Id&gt;<br />
&lt;/User&gt;&gt;<br />
<br />
(3) 连接工厂<br />
JBossMQ 包括为topic和queue几个不同的连接工厂，每个连接工厂有自己特性。当通过JNDI来查找一个连接工厂时，需要知道此连接工厂的名称。所有可用连接工厂和它们的属性，名称都会在文件jbossmq-service.xml中。<br />
有三种类型连接工厂，依赖的通讯协议如下：<br />
OIL<br />
快速双向scoket通讯协议。它是缺省的。<br />
UIL<br />
超过一个socket协议，可以使用在通过防火墙访问，或者当客户端不能正确的查找到服务器的IP地址。<br />
RMI<br />
最早的协议，是稳定的，但是比较慢。<br />
JVM<br />
在JBoss 2.4之后增加的一个新的连接工厂类型。不需要用socket，当客户端和JbossMQ使用同样虚拟机时，可以使用。<br />
在JBoss2.4.1以后版本中，对于topic- 和 queue-目的地，连接工厂使用同样的名字。下表列出了在JBoss中JMS连接工厂：<br />
目的地类型 JNDI名字 连接工厂类型<br />
Topic/Queue java:/ConnectionFactory JVM<br />
Topic/Queue java:/XAConnectionFactory JVM支持XA事务<br />
Topic/Queue RMIConnectionFactory RMI<br />
Topic/Queue RMIXAConnectionFactory RMI支持XA事务<br />
Topic/Queue ConnectionFactory OIL<br />
Topic/Queue XAConnectionFactory OIL支持XA事务<br />
Topic/Queue UILConnectionFactory UIL<br />
Topic/Queue UILXAConnectionFactory UIL支持XA事务<br />
<br />
3） JBoss中高级JMS配置<br />
在上边段落主要描述了和JbossMQ一起实行的基本配置工作。在本段来描述JMS其他配置。<br />
(1) JMS持久性管理<br />
JMS持久性管理(PM)负责存储消息，并且将消息标记为持久，如果服务器发生故障时，能保证消息不会丢失，并允许恢复持久性消息。持久性JMS消息可以使用不同的方法来完成。每个方法有自己优点和缺陷：<br />
PM 名字 优点 缺点<br />
File 比较稳定 速度慢<br />
Rollinglogged 速度比较快 此方法比较新，有些地方需要完善<br />
JDBC 对于稳定性和可量测性比较好 必须有JDBC<br />
Logged 速度快 Log files grow without bound, memory management problems during recovery<br />
在JBoss中缺省的持久性消息管理是File持久性管理。可以改变它，但必须对于一个JMS <br />
Server有且仅有一个持久性管理配置。所以你在JBoss管理界面的jboss.mq ? &gt;<br />
service=PersistenceManager 只是看到一个。<br />
持久性管理的配置文件是jbossmq-service.xml。在server..deploy下。<br />
为了让大家了解持久性管理的各种方法，我下面来逐个介绍如何配置。<br />
w File持久性管理<br />
File持久性管理的概念就是为每一个持久性消息建立一个文件。消息持久性方法不是全部都能使用，但它是比较稳定的。<br />
File持久性管理在JBoss发布时，作为一个缺省的持久性管理。如果你打开jbossmq-service.xml文件，你会看到下面的XML：<br />
&lt;mbean code="org.jboss.mq.pm.file.PersistenceManager"<br />
name="jboss.mq:service=PersistenceManager"&gt;<br />
&lt;attribute name="DataDirectory"&gt;db/jbossmq/file&lt;/attribute&gt;<br />
&lt;depends optional-attribute-name="MessageCache"&gt;jboss.mq:service=MessageCache&lt;/depends&gt;<br />
&lt;/mbean&gt;<br />
当设置Mbean配置时，File持久性管理允许你指定下面的属性：<br />
DataDircetory 是存放持久性消息的路径，会把生成的数据文件放在此目录下。<br />
<br />
w 设置Rollinglogged持久性管理<br />
Rollinglogged持久性管理是比较新的一种持久性消息管理方法，因为它使用日志文件来持续多个消息，所以当建立一个文件时，不需要许多的I/O。<br />
定义Rollinglogged持久性管理：<br />
&lt;mbean code="org.jboss.mq.pm.rollinglogged.PersistenceManager"<br />
name="jboss.mq:service=PersistenceManager"&gt;<br />
&lt;attribute name="DataDirectory"&gt;db/jbossmq/file&lt;/attribute&gt;<br />
&lt;depends optional-attribute-name="MessageCache"&gt;jboss.mq:service=MessageCache&lt;/depends&gt;<br />
&lt;/mbean&gt;<br />
Rollinglogged持久性管理中DataDirctory 存放持久性消息的路径，会把生成的数据文件放在此目录下。<br />
<br />
w 设置JDBC持久性管理<br />
JDBC持久性管理使用数据库表来存储消息。需要一个JBoss配置的数据源来访问数据库。具体内容参考jbossmq-service.xml文件中的内容。<br />
w 设置Logged持久性管理<br />
Logged持久性管理是比较早的一个，在JBoss2.4.1以后版本中不在建议使用。现在有其他更好的办法。<br />
4、举例说明<br />
当我们清楚了以后内容后，现在我们来用JBoss实现一个例子来加深对JBoss和JMS的了解。<br />
在上面叙述中，我们知道明确使用JMS provider有三个基本的事情要做：配置JNDI初始化上下文，连接工厂的名字和使用目的地的名字。<br />
当编写产品的最好的事情是不受provider-specific 影响，使代码能在不同的JMS provider之间容易移植。在此这个例子没有聚焦在开发产品上，而是解释如何使用JbossMQ来工作。<br />
1) 初始化上下文<br />
w 配置JNDI的一个方法是通过属性文件jndi.properties。在这个文件中使用正确的值，并且把它所在的路径包含到classpath中，它比较容获得正确初始化上下文。<br />
jndi.properties文件的内容如下：<br />
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory<br />
java.naming.provider.url=localhost:1099<br />
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces<br />
把该文件放置的路径成为你的classpath的一部分。如果你使用这种方法，在初始化上下文时，代码比较简单: Context context = new IntialContext();1<br />
w 在某些情景下，可能需要手工配置JNDI；例如当运行的类文件中环境已经配置了一个初始化上下文，但不是你想用的上下文时，需要手工来配置一个上下文。设置在哈希表中的几个属性值，并且使用此哈希表来实例化一个上下文。定义语法：<br />
Hashtable props = new Hashtable();<br />
props.put(Context.INITIAL_CONTEXT_FACTORY,<br />
"org.jnp.interfaces.NamingContextFactory");<br />
props.put(Context.PROVIDER_URL, "localhost:1099");<br />
props.put("java.naming.rmi.security.manager", "yes");<br />
props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");<br />
<br />
2) 查找连接工厂<br />
自有了上下文后，需要查找一个连接工厂。为了查找它，使用一个可用的名字。查找连接工厂的代码如下：<br />
对于一个topic目的地<br />
TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup (&#8220;ConnectionFactory&#8221;)<br />
Queue 目的地：<br />
QueueConnectionFactory queueFactory = (QueueConnectionFactory ) context.lookup (&#8220;ConnectionFactory&#8221;)<br />
3) 建立连接和会话<br />
在我们有了连接工厂后，建立一个连接，在此连接中建立一个会话。<br />
对于topic代码如下：<br />
//建立一个连接<br />
topicConnection = topicFactory.createTopicConnection();<br />
//建立一个会话<br />
topicSession = topicConnection.createTopicSession(false, //不需要事务<br />
Session.AUTO_ACKNOLEDGE //自动接收消息的收条。<br />
);<br />
对于queue代码如下：<br />
//建立一个连接<br />
queueConnection = queueFactory.createQueueConnection();<br />
//建立一个会话<br />
queueSession = queueConnection .createQueueSession(false, //不需要事务<br />
Session.AUTO_ACKNOLEDGE //自动接收消息的收条。<br />
);<br />
一个会话建立时，配置是否调用事务<br />
在事务Session中，当事务被提交后，自动接收，如果事务回滚，所有的被消费的消息将会被重新发送。<br />
在非事务Session中，如果没有调用事务处理，消息传递的方式有三种：<br />
Session.AUTO_ACKNOWLEDGE :当客户机调用的receive方法成功返回，或当MessageListenser 成功处理了消息，session将会自动接收消息的收条。<br />
Session.CLIENT_ACKNOWLEDGE ：客户机通过调用消息的acknowledge方法来接收消息。接收发生在session层。接收到一个被消费的消息时，将自动接收该session已经消费的所有消息。例如：如果消息的消费者消费了10条消息，然后接收15个被传递的消息，则前面的10个消息的收据都会在这15个消息中被接收。<br />
Session.DUPS_ACKNOWLEDGE ：指示session缓慢接收消息。<br />
<br />
4) 查找目的地<br />
现在我们来介绍建立publishes/sends 或subscribles/receives消息。<br />
下面的代码列出来查找一个目的地：<br />
对于topic 查找一个testTopic目的地<br />
Topic topic = (Topic) context.lookup(&#8220;topic/testTopic&#8221;);<br />
<br />
对于queue 查找一个testQueue目的地<br />
Queue queue= (Queue) context.lookup(&#8220;queue/testQueue&#8221;);<br />
注意：JbossM的前缀topic/ (queue/)通常被放在topic (queue)名字前面。<br />
在JMS中，当客户机扮演每种角色，象对于topic来将的publisher ,subscriber 或对于queue来将的sender, receiver， 都有自己不同类继承和不同函数。<br />
5) 建立一个消息制造者Message Producer (topic publisher/ queue sender)<br />
消息制造者是一个由session创建的对象，主要工作是发送消息到目的地。<br />
对于一个topic，需要通过TopicSession来创建一个TopicPublisher。代码如下：<br />
TopicPublisher topicPublisher = TopicSession.createPublisher(topic);<br />
<br />
对于一个queue，需要通过QueueSession来创建一个QueueSender。代码如下：<br />
QueuePublisher queuePublisher = queueSession.createSender(queue);<br />
6) 消息发送<br />
建立一个TestMessage并且publish 它， 代码：<br />
TextMessage message = topicSession.createTestMessage();<br />
message.setText(msg);<br />
topicPublishe.publish(topic, message);<br />
建立一个TestMessage并且send它， 代码：<br />
TextMessage message = queueSession.createTestMessage();<br />
message.setText(msg);<br />
queueSender.send(queue, message);<br />
<br />
7) 下面是一个完成的topic publisher 代码，文件名HelloPublisher.java ：<br />
import javax.naming.Context;<br />
import javax.naming.InitialContext;<br />
import javax.naming.NamingException;<br />
import javax.jms.TopicConnectionFactory;<br />
import javax.jms.TopicConnection;<br />
import javax.jms.TopicSession;<br />
import javax.jms.TopicPublisher;<br />
import javax.jms.Topic;<br />
import javax.jms.TextMessage;<br />
import javax.jms.Session;<br />
import javax.jms.JMSException;<br />
import java.util.Hashtable;<br />
public class HelloPublisher {<br />
<br />
TopicConnection topicConnection;<br />
TopicSession topicSession;<br />
TopicPublisher topicPublisher;<br />
Topic topic;<br />
<br />
public HelloPublisher(String factoryJNDI, String topicJNDI)<br />
throws JMSException, NamingException {<br />
Hashtable props=new Hashtable();<br />
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");<br />
props.put(Context.PROVIDER_URL, "localhost:1099");<br />
props.put("java.naming.rmi.security.manager", "yes");<br />
props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");<br />
Context context = new InitialContext(props);<br />
TopicConnectionFactory topicFactory =<br />
(TopicConnectionFactory)context.lookup(factoryJNDI);<br />
topicConnection = topicFactory.createTopicConnection();<br />
topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);<br />
<br />
topic = (Topic)context.lookup(topicJNDI);<br />
<br />
topicPublisher = topicSession.createPublisher(topic);<br />
<br />
}<br />
<br />
public void publish(String msg) throws JMSException {<br />
<br />
TextMessage message = topicSession.createTextMessage();<br />
message.setText(msg);<br />
topicPublisher.publish(topic, message);<br />
}<br />
<br />
public void close() throws JMSException {<br />
topicSession.close();<br />
topicConnection.close();<br />
}<br />
<br />
public static void main(String[] args) {<br />
try {<br />
HelloPublisher publisher = new HelloPublisher(<br />
"ConnectionFactory", "topic/testTopic");<br />
for (int i = 1; i &lt; 11; i++) {<br />
String msg = "Hello World no. " + i;<br />
System.out.println("Publishing message: " + msg);<br />
publisher.publish(msg);<br />
}<br />
publisher.close();<br />
} catch(Exception ex) {<br />
System.err.println(<br />
"An exception occurred while testing HelloPublisher25: " + ex);<br />
ex.printStackTrace();<br />
}<br />
}<br />
}<br />
我们知道，使用JMS不仅能发送（send）/发布（publish）消息，也能获得（send）/发布（publish）的消息。在时间方式有良种方法来做：<br />
w 同步（Synchronously）：需要手工的去得到消息，为了得到一个消息客户机调用方法得到消息，直到消息到达或在规定的时间内没有到达而超时。我们在例子中没有说明这部分，大家可以实验一下。<br />
w 异步（Asynchronously）：你需要定义一个消息监听器(MessageListener),实现该接口。当消息达到时，JMS provider通过调用该对象的 onMessage方法来传递消息。<br />
从原则来将，topic和queue都是异步的，但是在这两种目的地中有不同的类和方法。首先，必须定义一个MessageListener接口。 <br />
8) 建立一个MessageListener<br />
在建立了你需要的subscriber/receiver，并且登记了监听器后。就可以调用连接的start方法得到JMS provider 发送到的消息了。如果在登记监听器之前调用start方法，很可能会丢失消息。<br />
public void onMessage(Message m) {<br />
try {<br />
String msg = ((TextMessage)m).getText();<br />
System.out.println("HelloSubscriber got message: " + msg);<br />
} catch(JMSException ex) {<br />
System.err.println("Could not get text message: " + ex);<br />
ex.printStackTrace();<br />
}<br />
}<br />
9) 建立消息消费者<br />
对于topic来将：<br />
//建立一个订阅者<br />
topicSubscriber = topicSession.createSubscriber(topic);<br />
//设置消息监听器，<br />
topicSubscriber.setMessageListener(this)<br />
//连接开始<br />
topicConnection.start();<br />
对于queue来将：<br />
//建立一个订阅者<br />
queueReceiver = queueSession.createReceiver(queue);<br />
//设置消息监听器，<br />
queueReceiver .setMessageListener(this)<br />
//连接开始<br />
queueConnection.start();<br />
10) 完整的代码，放在文件HelloSubscriber.java中，如下：<br />
import javax.naming.Context;<br />
import javax.naming.InitialContext;<br />
import javax.naming.NamingException;<br />
<br />
import javax.jms.TopicConnectionFactory;<br />
import javax.jms.TopicConnection;<br />
import javax.jms.TopicSession;<br />
import javax.jms.TopicSubscriber;<br />
import javax.jms.Topic;<br />
import javax.jms.Message;<br />
import javax.jms.TextMessage;<br />
import javax.jms.Session;<br />
import javax.jms.MessageListener;<br />
import javax.jms.JMSException;<br />
<br />
public class HelloSubscriber implements MessageListener {<br />
TopicConnection topicConnection;<br />
TopicSession topicSession;<br />
TopicSubscriber topicSubscriber;<br />
Topic topic;<br />
public HelloSubscriber(String factoryJNDI, String topicJNDI)<br />
throws JMSException, NamingException<br />
{<br />
Context context = new InitialContext();<br />
TopicConnectionFactory topicFactory =<br />
(TopicConnectionFactory)context.lookup(factoryJNDI);<br />
topicConnection = topicFactory.createTopicConnection();<br />
topicSession = topicConnection.createTopicSession(<br />
false, Session.AUTO_ACKNOWLEDGE);<br />
topic = (Topic)context.lookup(topicJNDI);<br />
topicSubscriber = topicSession.createSubscriber(topic);<br />
topicSubscriber.setMessageListener(this);<br />
System.out.println(<br />
"HelloSubscriber subscribed to topic: " + topicJNDI);<br />
topicConnection.start();<br />
}<br />
public void onMessage(Message m) {<br />
try {<br />
String msg = ((TextMessage)m).getText();<br />
System.out.println("HelloSubscriber got message: " + msg);<br />
} catch(JMSException ex) {<br />
System.err.println("Could not get text message: " + ex);<br />
ex.printStackTrace();<br />
}<br />
}<br />
public void close() throws JMSException {<br />
topicSession.close();<br />
topicConnection.close();<br />
}<br />
public static void main(String[] args) {<br />
try {<br />
HelloSubscriber subscriber = new HelloSubscriber(<br />
"TopicConnectionFactory",<br />
"topic/testTopic");<br />
} catch(Exception ex) {<br />
System.err.println(<br />
"An exception occurred while testing HelloSubscriber: " + ex);<br />
ex.printStackTrace();<br />
}<br />
}<br />
}<br />
<br />
11) 编辑、运行程序<br />
直接使用命令（java） <br />
w 开启命令操作符。设置classpath : <br />
set classpath=C:jboss-3.0.6_tomcat-4.1.18clientjbossall-client.jar;C:jboss-3.0.6_tomcat-4.1.18clientjboss-j2ee.jar;C:jboss-3.0.6_tomcat-4.1.18clientjnp-client.jar;C:jboss-3.0.6_tomcat-4.1.18clientlog4j.jar;.<br />
w 首先运行订阅消息端：java HelloSubscriber<br />
w 再开启另外一个命令窗口设置classpath : <br />
set classpath=C:jboss-3.0.6_tomcat-4.1.18clientjbossall-client.jar;C:jboss-3.0.6_tomcat-4.1.18clientjboss-j2ee.jar;C:jboss-3.0.6_tomcat-4.1.18clientjnp-client.jar;C:jboss-3.0.6_tomcat-4.1.18clientlog4j.jar;.<br />
w 运行发布消息端：java HelloPublisher<br />
5、补充<br />
在最后我们解释JBoss-specific特性：如何用代码来管理目的地。JBoss各个版本可能不同，但是差别不大。我使用的是jboss3.0.6。<br />
实现这个目的有两种不同的方法，依赖于是否代码是在和JBoss同样的虚拟机还是独立独立的。它们都包括调用一个通过service=DestinationManager 登记的JMX Bean。这个Mbean 有四个方法来管理目的地：createTopic()，createQueue()，destroyTopic()，destroyQueue()。<br />
在代码中实现管理目的地在影射怎样调用MBean有不同的地方。如果程序虚拟机和Mbean服务器一样，可以直接调用。<br />
建立一个topic 目的地的代码如下：<br />
MBeanServer server = (MBeanServer)<br />
MBeanServerFactory.findMBeanServer(null).iterator().next();<br />
server.invoke(new ObjectName("JBossMQ", "service", "DestinationManager"),<br />
method,<br />
new Object[] { &#8220;myTopic&#8221; },<br />
new String[] { "java.lang.String" });<br />
<br />
如果程序和Mbean服务器的虚拟机不同，需要通过一个JMX adapter。一个JMX adapter是一个HTML GUI。用程序通过URL来调用Mbean。代码如下：<br />
import java.io.InputStream;<br />
import java.net.URL;<br />
import java.net.HttpURLConnection;<br />
import javax.management.MBeanServerFactory;<br />
import javax.management.MBeanServer;<br />
import javax.management.ObjectName;<br />
import javax.jms.Topic;<br />
import javax.jms.Queue;<br />
public class DestinationHelper {<br />
static final String HOST = "localhost";<br />
static final int PORT = 8080;<br />
static final String BASE_URL_ARG = "/jmx-console/HtmlAdaptor?"; <br />
public static void createDestination(Class type, String name) <br />
throws Exception<br />
{<br />
String method = null;<br />
if (type == Topic.class) { method = "createTopic"; }<br />
else if (type == Queue.class) { method = "createQueue";}<br />
invoke(method, name); <br />
}<br />
<br />
public static void destroyDestination(Class type, String name) <br />
throws Exception<br />
{<br />
String method = null;<br />
if (type == Topic.class) { method = "destroyTopic"; }<br />
else if (type == Queue.class) { method = "destroyQueue";}<br />
invoke(method, name);<br />
}<br />
<br />
protected static void invoke(String method, String destName) <br />
throws Exception<br />
{<br />
try {<br />
MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null).iterator().next();<br />
invokeViaMBean(method, destName);<br />
}catch(Exception ex) { invokeViaUrl(method, destName);} <br />
}<br />
protected static void invokeViaUrl(String method, String destName) <br />
throws Exception<br />
{<br />
String action = "action=invokeOp&amp;methodIndex=6&amp;name=jboss.mq%3Aservice%3DDestinationManager&amp;arg0=" + destName;<br />
String arg = BASE_URL_ARG + action;<br />
URL url = new URL("http", HOST, PORT, arg);<br />
HttpURLConnection con = (HttpURLConnection)url.openConnection();<br />
con.connect();<br />
<br />
InputStream is = con.getInputStream();<br />
java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();<br />
byte[] buff = new byte[1024];<br />
for(;;) {<br />
int size = is.read( buff );<br />
if (size == -1 ) { break; }<br />
os.write(buff, 0, size);<br />
}<br />
os.flush();<br />
<br />
if (con.getResponseCode() != HttpURLConnection.HTTP_OK ) {<br />
throw new Exception ("Could not invoke url: " + con.getResponseMessage() );<br />
} else {<br />
System.out.println("Invoked URL: " + method + " for destination " + destName + "got resonse: " + os.toString());<br />
} <br />
}<br />
protected static void invokeViaMBean(String method, String destName) <br />
throws Exception<br />
{<br />
MBeanServer server = (MBeanServer)MBeanServerFactory.findMBeanServer(null).iterator().next();<br />
server.invoke(new ObjectName("JBossMQ", "service", "DestinationManager"),<br />
method,<br />
new Object[] { destName },<br />
new String[] { "java.lang.String" });<br />
}<br />
public static void main(String[] args) {<br />
try {<br />
if (args.length &gt;0){<br />
destroyDestination(Topic.class,"myCreated");<br />
}else {<br />
createDestination(Topic.class,"myCreated");<br />
}<br />
}catch(Exception ex) {<br />
System.out.println("Error in administering destination: " + ex);<br />
ex.printStackTrace();<br />
}<br />
}<br />
<br />
}<br />
编辑命令：<br />
javac -classpath C:jboss-3.0.6_tomcat-4.1.18clientjbossall-client.jar;C:jboss-3.0.6_tomcat-4.1.18libjboss-jmx.jar;. DestinationHelper.java<br />
运行命令<br />
java -classpath C:jboss-3.0.6_tomcat-4.1.18clientjbossall-client.jar;C:jboss-3.0.6_tomcat-4.1.18libjboss-jmx.jar;. DestinationHelper<br />
当运行完后查看http://localhost:8080/jmx-console下面的jboss.mq.destination中有name=myCreated,service=Topic <br />
表明你建立成功。当JBoss关闭重新启动时。该目的地不会在存在
<img src ="http://www.blogjava.net/libin2722/aggbug/211412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-06-28 20:22 <a href="http://www.blogjava.net/libin2722/articles/211412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jboss 作为window的服务</title><link>http://www.blogjava.net/libin2722/articles/210580.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Wed, 25 Jun 2008 07:57:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/210580.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/210580.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/210580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/210580.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/210580.html</trackback:ping><description><![CDATA[<p><font style="background-color: #c7edcc">首先下载 javaservice<br />
<br />
<font color="#000080">http://multiplan.co.uk/software/javaservice/downloads.html</font><br />
<br />
</font></p>
<br />
<p><font style="background-color: #c7edcc">&nbsp;-- install windows service<br />
&nbsp;JavaService.exe -install JBossEM %JAVA_HOME%\jre\bin\server\jvm.dll -Djava.class.path=%JAVA_HOME%\lib\tools.jar;%JBOSS_HOME%\bin\run.jar -start org.jboss.Main -stop org.jboss.Main -method systemExit -current %JBOSS_HOME%\bin -auto -overwrite</font></p>
<p><font style="background-color: #c7edcc">-- -uninstall jboss service<br />
javaservice -uninstall JBossEM</font></p>
<p><font style="background-color: #c7edcc">-- JBossEM&nbsp; is&nbsp; service name</font></p>
<p><font style="background-color: #c7edcc"></font>&nbsp;</p>
<img src ="http://www.blogjava.net/libin2722/aggbug/210580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-06-25 15:57 <a href="http://www.blogjava.net/libin2722/articles/210580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 国际化-资源文件的使用 (i18n)</title><link>http://www.blogjava.net/libin2722/articles/207836.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 14 Jun 2008 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/207836.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/207836.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/207836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/207836.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/207836.html</trackback:ping><description><![CDATA[<h3>Java国际化——资源包的使用</h3>
<br />
<u>本文是由JR主持写作的《J2SE进阶》一书的部分章节整理而成，《J2SE进阶》正在写作、完善阶段。您阅读后，有任何建议、批评，请<a class="l2" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#111;&#107;&#95;&#119;&#105;&#110;&#110;&#101;&#114;&#98;&#111;&#121;&#64;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;" target="_blank">和我联系</a>，或在<a href="http://www.chinaitpower.com/A200507/2005-07-24/&nbsp;%3Ca%20href=%22http://www.javaresearch.org/forum/thread.jsp?column=376&amp;thread=7576"  ?>http://www.javaresearch.org/forum/thread.jsp?column=376&amp;thread=7576'</a> target='_blank' class='l2'&gt;这儿留言</a>。《J2SE进阶》写作项目组感谢您阅读本文。</u><br />
<br />
在当今这个信息社会，尤其是随着互联网的出现和普及，人们之间的距离比以往任何时候都更加接近，同时交往也更加频繁，时下最时髦的概念就是地球村，而我小时候只知道我出生的那个小乡村。距离近，交往频繁，人们就不得不考虑如何去与各个不同种族、不同区域的人们打交道。对人如此，对我们的软件亦是如此，你需要考虑如何让处于世界不同地方的使用者都能够很好地使用你的软件。于是，在每个软件开始之前，编写者都可能需要考虑这样一个问题——国际化。<br />
<br />
我们知道，在Java中可以通过java.util.Locale类来唯一地确定特定语言和国家的组合，即抽象最终用户的使用环境。同时将用户相关的一些信息置于资源包中，通过资源包来动态地获得最终的用户显示。资源包可以由资源文件或者资源子类来具体实现。<br />
<strong><br />
注意：本文只打算讨论国际化过程中资源包的使用技巧，更多更精彩的内容，请期待《J2SE进阶》一书。</strong><br />
<br />
<h4>资源包</h4>
<br />
在编写应用程序的时候，需要面对的一个问题是如何来处理与locale相关的一些信息。比如，页面上的一些静态文本就希望能够以用户习惯的语言显示。最原始的做法是将这些信息硬编码到程序中（可能是一大串判断语句），但是这样就将程序代码和易变的locale信息捆绑在一起，以后如果需要修改locale信息或者添加其它的locale信息，你就不得不重新修改代码。而资源包可以帮助你解决这个问题，它通过将可变的locale信息放入资源包中来达到两者分离的目的。应用程序可以自动地通过当前的locale设置到相应的资源包中取得所要的信息。资源包的概念类似于Windows编程人员使用的资源文件（rc文件）。<br />
<br />
一般来说，资源包需要完成两个功能：和具体的locale进行绑定以及读取locale相关信息。<br />
<br />
<h5>ResourceBundle类</h5>
<br />
你可以把资源包看作为一个由许多成员（子类）组成的大家庭，其中每个成员关联到不同的locale对象，那它是如何完成关联功能的呢？<br />
<br />
资源包中的每个成员共享一个被称作基名（base&nbsp;name）的名称，然后在此基础上根据一定的命名规范进行扩展。下面就列出了一些成员的名称：<br />
&nbsp;&nbsp;&nbsp;&nbsp;LabelResources<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de_CH<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LabelResources_de_CH_UNIX<br />
可见这些子类依据这样的命名规范：baseName_language_country_variant，其中language等几个变量就是你在构造Locale类时所使用的。而资源包正是通过这个符合命名规范的名称来和locale进行关联的，比如LabelResource_de_CH就对应于由德语（de）和瑞士（CH）组成的locale对象。<br />
<br />
当你的应用程序需要查找特定locale对象关联的资源包时，它可以调用ResourceBundle的getBundle方法，并将locale对象作为参数传入。<br />
<div class="codeStyle">
<ol>
    <li>
    <li><font color="#ff0000">Locale</font>&nbsp;currentLocale&nbsp;=&nbsp;<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">Locale</font>(<font color="#ff33ff">"de"</font>,&nbsp;<font color="#ff33ff">"CH"</font>,&nbsp;<font color="#ff33ff">"UNIX"</font>);
    <li><font color="#ff0000">ResourceBundle</font>&nbsp;myResources&nbsp;=
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ResourceBundle</font>.getBundle(<font color="#ff33ff">"LabelResources"</font>,&nbsp;currentLocale); </li>
</ol>
</div>
<br />
如果该locale对象匹配的资源包子类找不到，getBundle将试着查找最匹配的一个子类。具体的查找策略是这样的：getBundle使用基名，locale对象和缺省的locale来生成一个候选资源包名称序列。如果特定locale对象的语言代码、国家代码和可选变量都是空值，则基名是唯一的候选资源包名称。否则的话，具体locale对象（language1，country1和variant1）和缺省locale（language2，country2和variant2）将产生如下的序列：<br />
<ul><br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;variant1<br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country1&nbsp;<br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language1&nbsp;<br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;variant2&nbsp;<br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;+&nbsp;"_"&nbsp;+&nbsp;country2&nbsp;<br />
    <li>baseName&nbsp;+&nbsp;"_"&nbsp;+&nbsp;language2&nbsp;<br />
    <li>baseName&nbsp;<br />
    </li>
</ul>
<br />
然后，getBundle方法按照产生的序列依次查找匹配的资源包子类并对结果子类初始化。首先，它将寻找类名匹配候选资源包名称的类，如果找到将创建该类的一个实例，我们称之为结果资源包。否则，getBundle方法将寻找对应的资源文件，它通过候选资源包名称来获得资源文件的完整路径（将其中的&#8220;.&#8221;替换为&#8220;/&#8221;，并加上&#8220;.properties&#8221;后缀），如果找到匹配文件，getBundle方法将利用该资源文件来创建一个PropertyResourceBundle实例，也就是最终的结果资源包。与此同时，getBundle方法会将这些资源包实例缓存起来供以后使用。<br />
<br />
如果没有找到结果资源包，该方法将抛出MissingResourceException异常。所以为了防止异常的抛出，一般来说都需要至少实现一个基名资源包子类。<br />
<br />
<strong>注意：基名参数必须是一个完整的类名称（比如LabelResources，resource.LabelResources等），就相当于你引用一个类时需要指定完整的类路径。但是，为了和以前的版本保持兼容，在使用PropertyResourceBundles时也允许使用&#8220;/&#8221;来代替&#8220;.&#8221;表示路径。</strong><br />
<br />
比如你有以下这些资源类和资源文件：MyResources.class，&nbsp;MyResources_fr_CH.properties，&nbsp;MyResources_fr_CH.class，&nbsp;MyResources_fr.properties，&nbsp;MyResources_en.properties，&nbsp;MyResources_es_ES.class。你利用以下的locale设置来调用getBundle方法，你将会得到不同的结果资源包（假设缺省locale为Locale(&#8220;en&#8221;,&nbsp;&#8220;UK&#8221;)），请参考表13.4。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表13.4&nbsp;locale设置与结果资源包<br />
locale设置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;结果资源包<br />
Locale("fr",&nbsp;"CH")&nbsp;&nbsp;&nbsp;&nbsp;MyResources_fr_CH.class<br />
Locale("fr",&nbsp;"FR")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_fr.properties<br />
Locale("de",&nbsp;"DE")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_en.properties<br />
Locale("en",&nbsp;"US")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_en.properties<br />
Locale("es",&nbsp;"ES")&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyResources_es_ES.class<br />
<br />
创建了具体的资源包子类实例以后，就需要获得具体的信息。信息在资源包中是以键值对的方式存储的，表13.5列出的是LabelResources.properties文件的内容。<br />
<br />
表13.5&nbsp;LabelResources.properties<br />
<div class="codeStyle">
<ol>
    <li>
    <li>#&nbsp;This&nbsp;is&nbsp;LabelResources.properties&nbsp;file
    <li>greetings&nbsp;=&nbsp;您好！
    <li>farewell&nbsp;=&nbsp;再见。
    <li>inquiry&nbsp;=&nbsp;您好吗？ </li>
</ol>
</div>
<br />
其中等号左边的字符串表示主键，它们是唯一的。为了获得主键对应的值，你可以调用ResourceBundle类的getString方法，并将主键作为参数。此外，文件中以&#8220;#&#8221;号开头的行表示注释行。<br />
<br />
<h5>ListResourceBundle和PropertyResourceBundle子类</h5>
<br />
抽象类ResourceBundle具有两个子类：ListResourceBundle和PropertyResourceBundle，它们表示资源包子类两种不同的实现方式。<br />
<br />
PropertyResourceBundle是和资源文件配对使用的，一个属性文件就是一个普通的文本文件，你只需要为不同的locale设置编写不同名称的资源文件。但是，在资源文件中只能包含字符串，如果需要存储其它类型对象，你可以使用ListResourceBundle。<br />
<br />
ListResourceBundle是将键值对信息保存在类中的列表中，而且你必须实现ListResourceBundle的具体子类。<br />
<br />
如果ListResourceBundle和PropertyResourceBundle不能够满足你的需要，你可以实现自己的ResourceBundle子类，你的子类必须覆盖两个方法：handleGetObject和getKeys。<br />
<br />
<h5>使用资源文件</h5>
<br />
使用资源包最简单的方法就是利用资源文件，利用资源文件一般需要以下几个步骤：<br />
1、创建一个缺省的资源文件<br />
为了防止找不到资源文件，你最好实现一个缺省的资源文件，该文件的名称为资源包的基名加上.properties后缀。<br />
2、创建所需的资源文件<br />
为你准备支持的locale设置编写对应的资源文件。<br />
3、设置locale<br />
你必须在程序中的某个地方提供locale的设置或者切换功能，或者将其放入配置文件中。<br />
4、根据locale设置创建资源包<br />
ResourceBundle&nbsp;resource&nbsp;=<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResourceBundle.getBundle("LabelBundle",currentLocale);<br />
5、通过资源包获取locale相关信息<br />
String&nbsp;value&nbsp;=&nbsp;resource.getString("welcome");<br />
<br />
<strong>注意：在使用基名的时候，特别要注意给出完整的类名（或者路径名），比如你的应用程序所在的类包为org.javaresearch.j2seimproved.i18n，而你的资源文件在你的应用程序下的resource子目录中，那你的基名就应该是org.javaresearch.j2seimproved.i18n.resource.LabelBundleBundle而不是resource.LabelBundleBundle。<br />
</strong><br />
<br />
<h5>使用ListResourceBundle</h5>
<br />
使用ListResourceBundle和使用资源文件的步骤基本上一样，只不过你需要用ListResourceBundle子类来替换相应的资源文件。比如你的应用程序的基名是LabelBundle，而且准备支持Locale("en","US")和Locale("zh","CN")，那你需要提供以下几个Java文件，注意类名和locale的对应关系。<br />
LabelBundle_en_US.java<br />
LabelBundle_zh_CN.java<br />
LabelBundle.java（缺省类）<br />
<br />
代码13.3列出的是LabelBundle_zh_CN.java的源代码，相对于资源文件中&#8220;key&nbsp;=&nbsp;value&#8221;的写法，在此文件中你首先利用键值对来初始化一个二维数组，并在getContents方法中返回该数组。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
代码13.3：LabelBundle_zh_CN.java<br />
<div class="codeStyle">
<ol>
    <li>
    <li><strong><font color="#0000ff">package</font></strong>&nbsp;org.javaresearch.j2seimproved.i18n;<strong><font color="#0000ff">import</font></strong>&nbsp;
    <li>
    <li>java.util.<strong><a href="http://www.chinaitpower.com/source/jdk142/java/util/ListResourceBundle.java.html" target="_blank"><font class="classLink"><u>ListResourceBundle</u></font></a></strong>;
    <li>
    <li><strong><font color="#0000ff">public</font></strong>&nbsp;<strong><font color="#0000ff">class</font></strong>&nbsp;LabelBundle_zh_CN&nbsp;<strong><font color="#0000ff">extends</font></strong>&nbsp;<font color="#ff0000">ListResourceBundle</font>&nbsp;{&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;<strong><font color="#0000ff">public</font></strong>&nbsp;<strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/Object.java.html" target="_blank"><font class="classLink"><u>Object</u></font></a></strong>[][]&nbsp;getContents()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><font color="#0000ff">return</font></strong>&nbsp;contents;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;
    <li>
    <li>&nbsp;&nbsp;<strong><font color="#0000ff">private</font></strong>&nbsp;<strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/Object.java.html" target="_blank"><font class="classLink"><u>Object</u></font></a></strong>[][]&nbsp;contents&nbsp;=&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{<font color="#ff33ff">"title"</font>,&nbsp;<font color="#ff33ff">"称谓"</font>},&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{<font color="#ff33ff">"surname"</font>,&nbsp;<font color="#ff33ff">"姓"</font>},&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{<font color="#ff33ff">"firstname"</font>,&nbsp;<font color="#ff33ff">"名"</font>},&nbsp;&nbsp;&nbsp;
    <li>&nbsp;&nbsp;};
    <li>} </li>
</ol>
</div>
<br />
<br />
创建完资源类以后，同样需要设置locale以及根据locale来创建资源包。在通过资源包获取具体值的时候，你不能再使用getString方法，而应该调用getObject方法，而且由于getObject方法返回一个Object对象，你还需要进行正确的类型转换。其实，为了你的程序通用性，我们建议在使用资源文件的时候你也应该调用getObject方法，而不是getString方法。<br />
<div class="codeStyle">
<ol>
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink"><u>String</u></font></a></strong>&nbsp;title&nbsp;=&nbsp;(<strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink"><u>String</u></font></a></strong>)resource.getObject(<font color="#ff33ff">"title"</font>); </li>
</ol>
</div>
<br />
关于ListResourceBundle的详细使用，可以参考本书所附代码中国际化一节的ListResourceBundleSample.java程序。<br />
<br />
<h5>MessageFormat类</h5>
<br />
上面我们讲到利用资源文件来分离代码和可变的信息。但是在实际过程中，有些信息并不能够完全事先定义好，其中可能会用到运行时的一些结果，最典型例子的就是错误提示代码，比如提示某个输入必须在一定范围内。利用上面所讲的资源文件并不能够很好地解决这个问题，所以Java中引入了MessageFormat类。<br />
<br />
MessageFormat提供一种语言无关的方式来组装消息，它允许你在运行时刻用指定的参数来替换掉消息字符串中的一部分。你可以为MessageFormat定义一个模式，在其中你可以用占位符来表示变化的部分，比如你有这样一句话：<br />
<br />
您好，<u>peachpi</u>！欢迎来到Java研究组织网站！当前时间是：<u>2003-8-1&nbsp;16:43:12。</u><br />
<br />
其中斜体带下划线的部分为可变化的，你需要根据当前时间和不同的登录用户来决定最终的显示。我们用占位符来表示这些变化的部分，可以得到下面这个模式：<br />
<br />
您好，{0}！欢迎来到Java研究组织网站！当前时间是：{1,date}&nbsp;{1,time}。<br />
<br />
占位符的格式为{&nbsp;ArgumentIndex&nbsp;,&nbsp;FormatType&nbsp;,&nbsp;FormatStyle&nbsp;}，详细说明可以参考MessageFormat的API说明文档。这里我们定义了两个占位符，其中的数字对应于传入的参数数组中的索引，{0}占位符被第一个参数替换，{1}占位符被第二个参数替换，依此类推。<br />
最多可以设置10个占位符，而且每个占位符可以重复出现多次，而且格式可以不同，比如{1,date}和{1,time}。而通过将这些模式定义放到不同的资源文件中，就能够根据不同的locale设置，得到不同的模式定义，并用参数动态替换占位符。<br />
<br />
下面我们就以MessageFormatSample.java程序（源文件见本书所附代码）为例，来详细说明其中的每个步骤。<br />
1、找出可变的部分，并据此定义模式，将模式放入不同的资源文件中。<br />
比如针对上面的模式，定义了下面两个资源文件：<br />
MessagesBundle_en_US.properties<br />
Welcome&nbsp;=&nbsp;Hi,&nbsp;{0}!&nbsp;Welcome&nbsp;to&nbsp;Java&nbsp;Research&nbsp;Organization!<br />
MessagesBundle_zh_CN.properties<br />
Welcome&nbsp;=&nbsp;您好，{0}！欢迎来到Java研究组织网站！<br />
<br />
2、创建MessageFormat对象，并设置其locale属性。<br />
<div class="codeStyle">
<ol>
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">MessageFormat</font>&nbsp;formatter&nbsp;=&nbsp;<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">MessageFormat</font>(<font color="#ff33ff">""</font>);
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatter.setLocale(currentLocale); </li>
</ol>
</div>
<br />
3、从资源包中得到模式定义，以及设置参数。<br />
<div class="codeStyle">
<ol>
    <li>
    <li>messages&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000">ResourceBundle</font>.getBundle(
    <li>&nbsp;&nbsp;<font color="#ff33ff">"org.javaresearch.j2seimproved.i18n.resource.MessagesBundle"</font>,currentLocale);
    <li><strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/Object.java.html" target="_blank"><font class="classLink"><u>Object</u></font></a></strong>[]&nbsp;testArgs&nbsp;=&nbsp;{<font color="#ff33ff">"peachpi"</font>,<strong><font color="#0000ff">new</font></strong>&nbsp;<font color="#ff0000">Date</font>()}; </li>
</ol>
</div>
<br />
4、利用模式定义和参数进行格式化。<br />
<div class="codeStyle">
<ol>
    <li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong><a href="http://www.chinaitpower.com/source/jdk142/java/lang/System.java.html" target="_blank"><font class="classLink"><u>System</u></font></a></strong>.out.println(formatter.format(messages.getString(<font color="#ff33ff">"welcome"</font>),testArgs)); </li>
</ol>
</div>
<br />
<br />
<h5>关于资源包的组织</h5>
<br />
一般来说，你是按照资源的用途来组织资源包的，比如会把所有的页面按钮的信息放入一个名为ButtonResources的资源包中。在实际的应用过程中，以下几个原则可以帮你决定如何组织资源包：<br />
1、要易于维护。<br />
2、最好不要将所有的信息都放入一个资源包中，因为这样资源包载入内存时将会很耗时。<br />
3、最好将一个大的资源包分为几个小的资源包，这样可以在使用的时候才导入必须的资源，减少内存消耗。
<img src ="http://www.blogjava.net/libin2722/aggbug/207836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-06-14 11:01 <a href="http://www.blogjava.net/libin2722/articles/207836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>提升JSP页面响应速度的七大秘籍绝招</title><link>http://www.blogjava.net/libin2722/articles/192507.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 13 Apr 2008 01:02:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/192507.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/192507.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/192507.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/192507.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/192507.html</trackback:ping><description><![CDATA[你时常被客户抱怨JSP页面响应速度很慢吗？你想过当客户访问次数剧增时，你的WEB应用能承受日益增加的访问量吗？本文讲述了调整JSP和
servlet的一些非常实用的方法，它可使你的servlet和JSP页面响应更快，扩展性更强。而且在用户数增加的情况下，系统负载会呈现出平滑上长
的趋势。在本文中，我将通过一些实际例子和配置方法使得你的应用程序的性能有出人意料的提升。<br />
<br />
其中，某些调优技术是在你的编程工作中实现的。而另一些技术是与应用服务器的配置相关的。在本文中，我们将详细地描述怎样通过调整servlet和JSP页面，来提高你的应用程序的总体性能。在阅读本文之前，假设你有基本的servlet和JSP的知识。<br />
<br />
<strong>方法一：在servlet的init()方法中缓存数据<br />
</strong><br />
当应用服务器初始化servlet实例之后，为客户端请求提供服务之前，它会调用这个servlet的init()方法。在一个servlet的生命周
期中，init()方法只会被调用一次。通过在init()方法中缓存一些静态的数据或完成一些只需要执行一次的、耗时的操作，就可大大地提高系统性能。<br />
<br />
例如，通过在init()方法中建立一个JDBC连接池是一个最佳例子，假设我们是用jdbc2.0的DataSource接口来取得数据库连接，在通
常的情况下，我们需要通过JNDI来取得具体的数据源。我们可以想象在一个具体的应用中，如果每次SQL请求都要执行一次JNDI查询的话，那系统性能将
会急剧下降。解决方法是如下代码，它通过缓存DataSource，使得下一次SQL调用时仍然可以继续利用它：<br />
<br />
<center>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td class="code">
            <pre>public class ControllerServlet extends HttpServlet<br />
            <br />
            {<br />
            <br />
            private javax.sql.DataSource testDS = null; <br />
            <br />
            public void init(ServletConfig config) throws ServletException<br />
            <br />
            {<br />
            <br />
            super.init(config); <br />
            <br />
            Context ctx = null;<br />
            <br />
            try<br />
            <br />
            { <br />
            <br />
            ctx = new InitialContext();<br />
            <br />
            testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS");<br />
            <br />
            }<br />
            <br />
            catch(NamingException ne)<br />
            <br />
            {<br />
            <br />
            ne.printStackTrace(); <br />
            <br />
            }<br />
            <br />
            catch(Exception e)<br />
            <br />
            {<br />
            <br />
            e.printStackTrace();<br />
            <br />
            }<br />
            <br />
            }<br />
            <br />
            public javax.sql.DataSource getTestDS()<br />
            <br />
            {<br />
            <br />
            return testDS;<br />
            <br />
            }<br />
            <br />
            ...<br />
            <br />
            ... <br />
            <br />
            }</pre>
            </td>
        </tr>
    </tbody>
</table>
</center>
<p>　　<strong>方法 2:禁止servlet和JSP 自动重载(auto-reloading)</strong> <br />
<br />
Servlet/JSP提供了一个实用的技术，即自动重载技术，它为开发人员提供了一个好的开发环境，当你改变servlet和JSP页面后而不必重启应
用服务器。然而，这种技术在产品运行阶段对系统的资源是一个极大的损耗，因为它会给JSP引擎的类装载器(classloader)带来极大的负担。因此
关闭自动重载功能对系统性能的提升是一个极大的帮助。</p>
<p>　　<strong>方法 3: 不要滥用HttpSession</strong> <br />
<br />
在很多应用中，我们的程序需要保持客户
端的状态，以便页面之间可以相互联系。但不幸的是由于HTTP具有天生无状态性，从而无法保存客户端的状态。因此一般的应用服务器都提供了session
来保存客户的状态。在JSP应用服务器中，是通过HttpSession对像来实现session的功能的，但在方便的同时，它也给系统带来了不小的负
担。因为每当你获得或更新session时，系统者要对它进行费时的序列化操作。你可以通过对HttpSession的以下几种处理方式来提升系统的性
能。<br />
<br />
如果没有必要，就应该关闭JSP页面中对HttpSession的缺省设置。 如果你没有明确指定的话，每个JSP页面都会缺省地创建一个HttpSession。如果你的JSP中不需要使用session的话，那可以通过如下的JSP页面指示符来禁止它：</p>
<center>
<table bordercolordark="#ffffff" bordercolorlight="black" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
    <tbody>
        <tr>
            <td class="code">
            <pre>＜%@ page session="false"%＞</pre>
            </td>
        </tr>
    </tbody>
</table>
</center>
<p>　　不要在HttpSession中存放大的数据对像：如果你在HttpSession中存放大的数据对像的话，每当对它进行读写时，应用服务器都
将对其进行序列化，从而增加了系统的额外负担。你在HttpSession中存放的数据对像越大，那系统的性能就下降得越快。 <br />
<br />
当
你不需要HttpSession时，尽快地释放它：当你不再需要session时，你可以通过调用HttpSession.invalidate()方法
来释放它。尽量将session的超时时间设得短一点：在JSP应用服务器中，有一个缺省的session的超时时间。当客户在这个时间之后没有进行任何
操作的话，系统会将相关的session自动从内存中释放。超时时间设得越大，系统的性能就会越低，因此最好的方法就是尽量使得它的值保持在一个较低的水
平。 <br />
<br />
方法 4: 将页面输出进行压缩 <br />
<br />
压缩是解决数据冗余的一个好的方法，特别是在网络带宽不够发达的今天。有的浏
览器支持gzip(GNU
zip)进行来对HTML文件进行压缩，这种方法可以戏剧性地减少HTML文件的下载时间。因此，如果你将servlet或JSP页面生成的HTML页面
进行压缩的话，那用户就会觉得页面浏览速度会非常快。但不幸的是，不是所有的浏览器都支持gzip压缩，但你可以通过在你的程序中检查客户的浏览器是否支
持它。下面就是关于这种方法实现的一个代码片段： </p>
<ccid_nobr>
</ccid_nobr>
<pre>public void doGet(HttpServletRequest request, <br />
<br />
HttpServletResponse response)<br />
<br />
throws IOException, ServletException <br />
<br />
{<br />
<br />
OutputStream out = null<br />
<br />
String encoding = request.getHeader("Accept-Encoding"); <br />
<br />
if (encoding != null &amp;&amp; encoding.indexOf("gzip") != -1)<br />
<br />
{<br />
<br />
request.setHeader("Content-Encoding" , "gzip");<br />
<br />
out = new GZIPOutputStream(request.getOutputStream());<br />
<br />
}<br />
<br />
else if (encoding != null &amp;&amp; encoding.indexOf("compress") != -1)<br />
<br />
{<br />
<br />
request.setHeader("Content-Encoding" , "compress");<br />
<br />
out = new ZIPOutputStream(request.getOutputStream());<br />
<br />
} <br />
<br />
else<br />
<br />
{<br />
<br />
out = request.getOutputStream();<br />
<br />
}<br />
<br />
...<br />
<br />
... <br />
<br />
}</pre>
<img src ="http://www.blogjava.net/libin2722/aggbug/192507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-04-13 09:02 <a href="http://www.blogjava.net/libin2722/articles/192507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对ibatis分页功能的改进  </title><link>http://www.blogjava.net/libin2722/articles/192504.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 13 Apr 2008 00:51:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/192504.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/192504.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/192504.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/192504.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/192504.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 今天无意间看到了一篇关于这方面的文章，觉得是网上改进ibatis分页方面比较好的文章，这里转摘一下，希望能让更多的人用的到，也希望别人能把更好的解决方案贡献出来！function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.g...&nbsp;&nbsp;<a href='http://www.blogjava.net/libin2722/articles/192504.html'>阅读全文</a><img src ="http://www.blogjava.net/libin2722/aggbug/192504.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2008-04-13 08:51 <a href="http://www.blogjava.net/libin2722/articles/192504.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp 70 问答</title><link>http://www.blogjava.net/libin2722/articles/158058.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sun, 04 Nov 2007 04:59:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/158058.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/158058.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/158058.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/158058.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/158058.html</trackback:ping><description><![CDATA[jsp问答７０问：<br />
1. 问：在JAVA与JSP中要调用一个LINUX上的脚本程序,或WINDOWS上的脚本程序,该怎么写？<br />
答：System.getRuntime().exec("bash &lt; aaa.sh");<br />
<br />
2. 问：java中用什么表示双引号<br />
答："""<br />
<br />
3. 问：如何在JSP程序里另起一个线程？<br />
答：<br />
JSP本身就是独立线程运行而不象CGI都是独立进程.<br />
一般:<br />
Thread t = new Thread("你的对象");<br />
t.start();就可以了.<br />
要求你这个对象要实现runnable接口或继承thread.<br />
<br />
4. 问：jsp如何获得客户端的IP地址？<br />
答：<br />
request.getRemoteAddr()<br />
看看各个webserver的API文档说明，一般都有自带的，resin和tomcat都有<br />
<br />
5. 问：程序终止与输出终止<br />
答：<br />
程序中止:return;<br />
输出中止out.close();这一句相当于ASP的response.end<br />
<br />
6. 问：jsp中如何得到上页的URL？<br />
答：request.getHeader("referer");<br />
<br />
7. 问：提交网页的网页过期功能是怎么做的？<br />
答：response.setHader("Expires","0");<br />
<br />
8. 问：在JSP网页中如何知道自已打开的页面的名称<br />
答：<br />
request.getRequestURI() ;//文件名<br />
request.getRequestURL() ;//全部ＵＲＬ<br />
<br />
9. 问：提交表单后验证没有通过，返回提交页面，如何使原提交页面中的数据保留？<br />
答：javascript的go(-1)可以把上页的表单内容重新显示出来,但password域没有<br />
<br />
10. 问：如何取得http的头信息？<br />
答：request.getHader(headerName);<br />
<br />
11. 问：&amp;&amp;和&amp;的区别？<br />
答：<br />
&amp;&amp;是短路的与操作，也就是当地一个条件是false的时候，第二个条件不用执行<br />
&amp;相反，两个条件总是执行。<br />
<br />
12. 问：将*以正弦曲线的一个周期显示出来<br />
答：<br />
public void paint(Graphics g)<br />
{<br />
for(int i=0;i&lt;200;i++)<br />
g.drawString("*",i,(int)(Math.sin(i)*20)+50);<br />
}<br />
}<br />
<br />
13. 问：浮点数相乘后结果不精确如100.0 * 0.6 结果等于 60.0004<br />
答：<br />
这不叫错误,float和double是这样实现的.如果要精确计算，java提供了一个strictfp,它的计算遵循IEEE 754标准.而普通的float和double是<br />
<br />
由地平台浮点格式或硬件提供的额外精度或表示范围。<br />
<br />
14. 问：如何获得当前用的cursors的位置？<br />
答：<br />
int row = rs.getRow()就是当前指针行数,还有isFrist();isBeforeFist();isLast();isAfterLast();可以测试是不是在方法名所说的位置<br />
<br />
15. 问：表单成功提交了，点后退显示网页过期<br />
答：<br />
在&lt;head&gt;&lt;/head&gt;里面加以下代码<br />
&lt;META HTTP-EQUIV="Pragma" CONTENT="no-cache"&gt; <br />
&lt;META HTTP-EQUIV="Cache-Control" CONTENT="no-cache"&gt; <br />
&lt;META HTTP-EQUIV="Expires" CONTENT="0"&gt; <br />
或者在表单页中加上<br />
&lt;% <br />
response.setHeader("Pragma","no-cache"); <br />
response.setHeader("Cache-Control","no-cache"); <br />
response.setDateHeader("Expires",0); <br />
%&gt;<br />
<br />
16. 问：接口的简单理解<br />
答：接口为了规范,比如我在接口中定义了一个方法:<br />
getData()<br />
这是用来从不同的数据库中取数据的,就是JDBC的实现对于用户,我不要知道每种数据库是如何做的,但我知道如何它们要实现这个接口就一定有<br />
<br />
这个方法可以供我调用.这样SUN就把这个接口给各个数据库开发商,让他们自己实现. 但为什么不用继承而用接口哩,因为继承只能从一个你类<br />
<br />
继承,而接口可以实现多个,就是说我实现的子类有多个规定好的接口中的功能. 这只是简单的理解,等你深入理解抽象的时候就知道抽象到抽象<br />
<br />
类时为什么还要再抽象到接口.<br />
<br />
17. 问：怎样编写一个取消按钮（怎样返回上一个页面，象工具栏的后退按钮）？<br />
答：<br />
javascript把每次浏览过的location都压到了一个栈中,这个栈就是history,然后你如果要回到第几个页面它就做几次POP操作,把最后POP出来<br />
<br />
的那个LOCATION给你. 这就是JAVASCRIPT在实现history.go(-x)的原理.<br />
<br />
18. 问：什么是回调？<br />
答：<br />
简单说,回调用不是让你去监听谁做完了什么事,而是谁做完了什么事就报告给你. 这就是回调用的思想.例子太多了,AWT的事件,SWING事件模型<br />
<br />
都是这样有. 还有多线程中,如果要控制线程数,不能总是查询每个线程是否结束,要在每个线程结束时让线程自己告诉主线程我结束了,你可以<br />
<br />
开新的线程了.<br />
<br />
19. 问：简要介绍一下compareTo方法<br />
答：<br />
compareTo方法是Comparable 接口必需实现的方法,只要实现Comparable <br />
<br />
就可以用Arrays.srot()排序就象实现Runnable接口的run就能Thread()一样.<br />
<br />
20. 问：如何可以从别的Web服务器检索页, 然后把检索到的网页的HTML代码储存在一个变量中返回过来<br />
答：这是一个简单的WEB ROBOT实现,用URL类实现从网页中抓内容,然后自己写一个分析程序从中找出新的URL,不断递归下去就行了.<br />
<br />
21. 问：applet中如何获得键盘的输入<br />
答：application的System.in是当前系统的标准输入,applet因为安全的原因不可能读取当前系统(客户端)的标准输入,只能从它的ROOT组件的<br />
<br />
事件中,比如键盘事件中取得键值.<br />
<br />
22. 问：怎样计算代码执行所花费的时间？<br />
答：<br />
代码开始取时间，结束后取时间，相减<br />
long t1 = System.currentTimeMillis();<br />
///////////////// your code<br />
long t2 = System.currentTimeMillis() ;<br />
long time = t2-t1;<br />
<br />
23. 问：如何获在程序中获得一个文件的ContentType？<br />
答：<br />
URL u = new URL("file:///aaa.txt");<br />
URLConnection uc = u.openConnection();<br />
String s = uc.getContentType();<br />
<br />
24. 问：连接池的使用是建立很多连接池，还是一个连接池里用多个连接？<br />
答：<br />
只有在对象源不同的情况下才会发生多个池化,如果你只连一结一个数据源,永远不要用多个连结池. 所以连结池的初始化一定要做成静态的,而<br />
<br />
且应该在构造对象之前,也就是只有在类LOAD的时候,别的时候不应该有任何生成新的连结池的时候。<br />
<br />
25. 问：JavaMail要怎么安装？<br />
答：下载两个包，一个是javamail包，另一个是jaf包。下载完直接把这两个包不解压加到CLASSPATH。<br />
<br />
26. 问：怎样把地址栏里的地址锁定？<br />
答：把你的服务器的可访问目录索引选项关闭就行了,任何服务器都有一个conf文件,里面都有这个选项。<br />
<br />
27. 问：在JAVA中怎么取得环境变量啊。比如： TEMP = C：TEMP ？<br />
答：String sss = System.getProperty(key)<br />
<br />
28. 问：怎样实现四舍五入，保留小数点后两位小数？<br />
答：<br />
import java.text.*;<br />
...<br />
NumberFormat nf=NumberFormat.getNumberInstance();<br />
nf.setMaximumFractionDigits(2);<br />
nf.setMinimumFractionDigits(2);<br />
nf.format(numb);<br />
<br />
29. 问：Applet和form如何通信？<br />
答：<br />
取得的参数传到param里面<br />
&lt;% <br />
String xxx = request.getParameter("xxx"); <br />
%&gt; <br />
&lt;applet&gt; <br />
&lt;param value="&lt;%=xxx%&gt;"&gt; <br />
&lt;/applet&gt;<br />
<br />
<br />
30. 问：java-plug-in是什么？<br />
答：Java Runtime Environment的插件。用来运行java程序。不需要什么特别的设置。等于你的机器里面有了jvm。<br />
<br />
31. 问：WEB上面怎么样连接上一个EXCEL表格？<br />
答：<br />
定义页面得contentType="application/vnd.ms-excel"，让页面以excel得形式打开。同样也可以以word得形式打开：application/msword。<br />
<br />
32. 问：怎样才能避免textarea字数限制？<br />
答：是使用了FORM的默认方法的缘故,如果什么也不写默认是GET改用Post即可，在Form中定义mothod="post"。<br />
<br />
33. 问：为什么加了&lt;%@page contentType="text/html;charset=gb2312" %&gt;插入数据库的中文，依然是乱码？<br />
答：<br />
这要从环境看,能显示说明你的JSP引擎没有问题,但写入数据库时你的JDBC能不能处理中文,同一公司不同版本的JDBC都有支持中文和不支持中<br />
<br />
文的情况,RESIN自带的MYSQL JDBC就不支持,MM的就支持,还有你的数据库类型是否支持中文?CHAR的一般支持,但是否用binary存储双字节码<br />
<br />
34. 问：对于JFrame，hide()，show()与setVisibel()有什么区别吗？<br />
答：<br />
setVisible()从Component继承过来，而hide(),show()从Window里面继承过来。<br />
Makes the Window visible. If the Window and/or its owner are not yet displa yable, both are made displayable. The Window will <br />
<br />
be validated prior to being made visible. If t he Window is already visible, this will bring the Window to the front. 区别在<br />
<br />
这。<br />
36. 问：sendRedirect为什么不可以转到mms协议的地址的？response.sendRedirect("mms://missiah.adsldns.org:9394");<br />
答：java平台目前实现的protocol中并没有mms,你可以取系统属性java.protocol.handler.pkgs看看它的值中有没有mms,所以如果要想重定向<br />
<br />
到mms://host这样和URL,只有生成客户端的JAVASCRIPT让它来重定向<br />
<br />
37. 问：JTable中怎样定义各个Columns和Width和怎样设置表格的内容靠做靠右或居中？<br />
答：<br />
TableColumn tc = table.getColumn("Name");//取得列名为"Name"的列Handle<br />
int currentWidth = tc.getPreferredWidth(); //取得该列当前的宽度<br />
tc.setPreferredWidth(200); //设置当前列宽<br />
tc.setMaxWidth(200); //设置该列最大宽度<br />
tc.setMinWidth(50); //设置该列最小宽度<br />
<br />
38. 问：批操作是否可用于select语句？<br />
答：批操作其实是指成批理更新的操作,绝对不可能用于select操作。<br />
<br />
39. 问：为什么jsp路径太深文件名太长就无法读取文件？<br />
答：path不能超过255长度,不然就找不到了.这是作业系统的事。<br />
<br />
40. 问：如何让页面不保留缓存？<br />
答：<br />
&lt;% <br />
response.setHeader("Pragma","No-cache"); <br />
response.setHeader("Cache-Control","no-cache"); <br />
response.setDateHeader("Expires", 0); <br />
%&gt;<br />
<br />
41. 问：我的applet code 中用到jbutton 时就出错是否由于ie不支持swing package 请问应怎么办？<br />
答：JBUTTON是SWING基本包啊,只要把jdk/jre/lib/rt.jar放在classpath就行了.不要加载任何别的库。<br />
<br />
42. 问：不知道java是否支持midi格式，如果支持，应该怎么把wave格式转换成midi格式？<br />
答：目前还不行,可以看一下JMF三个版中对MIDI的格式支持是read only,而WAVE是read/write,MIDI只能播放,不能生成。<br />
<br />
43. 问：在jsp里面防止用户直接输入url进去页面，应该怎么做呢？<br />
答：<br />
一是从web服务器控制,对某一目录的所有访问要通过验证.<br />
二是在要访问的页面中加入控制.这个一般用session,也可以用请求状态码实现<br />
<br />
44. 问：<br />
例如后台有一计算应用程序（此程序运算起来很慢，可持续几分钟到几小时，这不管，主要是能激活它），客户机讲任务提交后，服务器对任<br />
<br />
务进行检测无误后将向服务器后台程序发送信息，并将其激活。要求如下：<br />
1）首先将后台程序激活，让它执行此任务（比如，前台将计算的C代码提交上后，后台程序程序能马上调用，并将其运行）<br />
2）要在前台JSP页面中显示运行过程信息（由于运行时间长，希望让客户看到运行过程中产生的信息）如何完成？<br />
<br />
答：<br />
活是可以的,运行一个shell让它去运行后台就行,但不可能取出运行信息,因为HTTP的超时限制不可能永远等你后台运行的,而且信息如果要动态<br />
<br />
实时推出来就得用SERVER PUSH技术。<br />
<br />
45. 问：数据库是datetime 型 ，插入当前时间到数据库？<br />
答：<br />
java.sql.Date sqlDate = new java.sql.Date();<br />
PreparedStatement pstmt = conn.prepareStatement("insert into foo(time) values(?)");<br />
pstmt.setDate(1,sqlDate);<br />
pstmt.executeUpdate();<br />
<br />
46. 问：怎样去掉字符串前后的空格。<br />
答：String.trim()<br />
<br />
47. 问：session怎样存取int类型的变量？<br />
答：<br />
session.setAttribute("int", i+"");<br />
int i = Integer.parseInt(session.getAttribute("int"));<br />
<br />
48. 问：在javascript中如何使输出的float类型的数据保留两位小数。<br />
答：Math.round(aaaaa*100)/100。<br />
<br />
49. 问：在bean种如何调用session<br />
答：<br />
你可把session对象作为一个参数传给bean<br />
在BEAN中定义HttpServletRequest request;HttpSession session;<br />
然后<br />
session = request.getSession(false);<br />
false为如果session为空,不建立新的session<br />
将session作为参数传入.其实只要将request传入就可以<br />
<br />
50. 问：如何把txt或word文件按原格式显示在jsp页面或servlet上？<br />
答：<br />
其实一个非常简单的解决方法就是在服务器的MIME中指点定TEXT和WORD的解释方式,然后用JSP或SERVLET生成它就行了,客户端就会自动调用相<br />
<br />
应程序打开你的文档。<br />
如果是希望按原格式的显示在页面上，而不是调用其他程序打开那么你可以试试用WEBDEV协议,可以说这是MS的一个亮点.它是在WEB方式下打开<br />
<br />
文档,和共享一样.完全符合的要求。<br />
<br />
51. 问：object的clone方法为什么不能直接调用？<br />
答：<br />
这个方法在object中是protected<br />
为什么要把这个方法定义为protected,这是一个折中,它的目的是想知道你这个方法在Object里只是一个标记,而不是一个实现,比如<br />
<br />
public class Object<br />
{<br />
.............<br />
protected Object clone()<br />
{}<br />
}<br />
<br />
所以直接继承的clone()方法并不能做任何时,你要使用这个方法就要重载这个方法并放宽访问权限为public,或实现cloneable接口. 但它没法<br />
<br />
这样告诉你它没有真的实现,只好用protected 方法加以警示<br />
<br />
52. 问：一个页面中如何刷新另外一个页面？<br />
答：<br />
要求是这些面页必须有关联,一是它们都有一个共同的顶层帧,也就是说是一个帧内的分级页面,当然可以是任意级,帧内再分帧也可以,另一个可<br />
<br />
能是当前窗口弹出的窗口,如果没有联系,那就不可能用一个页面刷新另一个页面. 帧内只要一级一级引用就行了. <br />
<br />
比如在左帧中一个页面中写top.right.location.reload();那么名为right的右帧中的页面就会刷新. 弹出的一样,用open时的名称刷新子窗口,<br />
<br />
子窗口用opener刷新主窗口<br />
<br />
53. 问：如何在jsp中怎么样向客户端写cookies？<br />
答：<br />
Cookie coo = new Cookie(name, value);<br />
HttpServletResponse.addCookie(name);<br />
<br />
54. 问：为什么jTextField1.setText("aaabbb");jTextField2.setText("AAABBB"); 得到的字体宽度不一样？<br />
答：就是说如果不是指定为等宽字体,每个字体的宽度都是不一样的.因此JAVA中用FontMetrics 类来取字符宽度。<br />
<br />
55. 问：String kk=application/octet-stream; name="G:/SMBCrack.exe";如何得到SMBCrack.exe？<br />
答：<br />
这应该是解析上传时候的二进制流得到的这一行里面格式是固定的，取到name="后面的字符串，然后把";去掉。然后取最后一个/后面的所有字<br />
<br />
符组成一个新字符串就行了。<br />
<br />
56. 问：如何传值并不刷新页面？<br />
答：<br />
弹出一个页面进行值的选择或者输入，ok后使用将值传给原窗口，使用javascript关闭打开的窗口即可：<br />
window.close();opener.focus();<br />
<br />
57. 问：有一个字符串："EF0C114EA4"，如何变为a[0] = 0xEF a[1] = 0x0C a[2] = 0x11 a[3] = 0x4E a[4] = 0xA4？<br />
答：<br />
String str="EF0C114EA4F";<br />
out.print(str+"&lt;br&gt;");<br />
int l=str.length()/2+str.length()%2,j=0,k=0;<br />
String[] a=new String[l];<br />
for(int i=0;i&lt;l;i++){<br />
if(str.length()-j==1)<br />
k=str.length();<br />
else<br />
k=j+2;<br />
a="0x"+str.substring(j,k);<br />
out.print("a["+Integer.toString(i)+"]="+a+"&lt;br&gt;");<br />
j+=2;<br />
}<br />
<br />
58. 问：怎样将一个int转换成一个四字节的byte数组？<br />
答：<br />
int x = 1234567;<br />
byte[] b = new byte[4];<br />
for(int i=0;i&lt;b.length;i++)<br />
{<br />
b = (x &gt;&gt;( i*8)) &amp; 0xFF;<br />
}<br />
<br />
59. 问：indexOf()的使用需要注意什么？<br />
答：参数是指从第几位（1，2，3，...）开始搜索，而返回值是指搜索到的位置（0，1，2，3.......）注意是从零算起的。<br />
<br />
60. 问：在Java应用程序中如何动态的添加一个按钮？<br />
答：<br />
这里涉及一个组件重绘的问题,组件要先于panel被显示之处存在,如果一panel已经显示了,那么加在上面你能看到吗?但如果在同一个panel上, <br />
<br />
先有button A,假如按下它加了butt on B,这时你如果使整个panel重给,那么A本身要重绘,它的事件监听就没有了,当然也就加不成B了,所以如<br />
<br />
果要先有另一个panel,当按A时把B加在这个panel上并重绘这个paenl,其实更好的方法是先把B加在panel中,同一个也行.把它setVisiable(flas<br />
<br />
e),按A时设为 true。<br />
<br />
61. 问：book mybook=new book(bookid);book是servlet,出错。<br />
答：<br />
book是servlet,能book mybook=new book(bookid);<br />
说明自己实现了servlet容器?不然,servlet能让你自己去调用? servlet如果调用其实和EJB连1%的区别都没有,它们都是自己继承或实现一些接<br />
<br />
口,在这些父类或接口中实现了如果和容器"打交道"的方法,然后容器调用这些方法来管理它,让它生成实例,池化,钝化,销毁,再生等.所以这样<br />
<br />
写是错误的。<br />
<br />
62. 问：给定一个字符串5*(5+9)/7怎样计算出结果？<br />
答：<br />
可有两种方法<br />
1。用堆栈完成<br />
2。最简单的方法，不用编程，如果有任何一个数据库的化，用select (5*(5+9)/7) from oneTable<br />
<br />
63. 问：如何实现递交表单内容的加密解密？<br />
答：<br />
如果你用IE目前只能用SSL协议,这一层不要你考虑,否则只你用你自己的工具加密传输,接收后再解密友,至于如何加解,如果要和公认的系统结<br />
<br />
合,就用通用的MD5,RAS等公开算法,如果你只是自己传自己解,你随便按你的想法把数据加上一些东西,取回来按规则减掉这些东西,我敢保证除<br />
<br />
你自己没有任何人能知道解密方法.<br />
<br />
64. 问：为什么Integer.parseInt("+1");会抛出NumberFormatException的异常？<br />
答：因为"+"运行算在JAVA中被重载.系统无法确定你用的是算术加还是字符+。<br />
这一点可以在JAVASCRIPT中更好地理解:<br />
&lt;form name="t"&gt;&lt;input name=s value=1234&gt;&lt;/form&gt;<br />
var a = document.t.s.value+1;<br />
这时a = 12345,因为document.t.s.value作为字符串.但var a = document.t.s.value-1;<br />
a 就是1233,因为系统知道-运算肯定是算术运行.所以把document.t.s.value转换成数字.<br />
<br />
<br />
65. 问：hashCode() 有什么用为什么有时候需要覆盖Object里的hashcode()方法？<br />
答：这就是这个对象的身份证啊,要不如何区分哪个对象。<br />
<br />
66. 问：怎样在tomcat中实现一个定时执行的东东？<br />
答：<br />
在应用程序启动时自动运行。servlet2.3中定义了ServletListener,监听Servlet Con text的启动或则关闭（可在配置文件中配置），启动时<br />
<br />
触发一个守护程序的运行(可以实现java.util.Timer或则 javax.swing.Timer).<br />
<br />
67. 问：程序可以输出自己吗？<br />
答：孔德悖论这个非常有名的法则.就是说任何程序都不可能输出自己.<br />
<br />
68. 问：能够把字符转化成ASCII码？比如将 A 转化成 65？<br />
答：<br />
int a='A';<br />
out.println(a);<br />
<br />
69. 问：如何区分输入的文字中的全角与半角？<br />
答：由于不能分辨出全角和半角字符的值有什么规律,只好把全角符号牧举出来了.<br />
<br />
70. 问：用户注册后的自动发信程序该怎么做？<br />
答：<br />
这种发信程序不考虑性能,因为不可能1秒就有一个人注册,我们说的考虑性能的发信程序是指上百万封信在队列里要不停发送的那种,象你这个<br />
<br />
随便怎么写一个程序都行,没有必要用JAVAMAIL.只要指定一个发信的服务器然后用cocket连它的25口就行了.自己用SOCKET连SMTP的25口发一封<br />
<br />
信就好象两个邻居之间送一样东西,直接递过去得了,用JAVAMAIL,消息机制就是你把这个东西从邮局寄给你的邻居了.&nbsp;&nbsp;<br />
<img src ="http://www.blogjava.net/libin2722/aggbug/158058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-11-04 12:59 <a href="http://www.blogjava.net/libin2722/articles/158058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA的代理模式 </title><link>http://www.blogjava.net/libin2722/articles/147468.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 22 Sep 2007 13:20:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/147468.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/147468.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/147468.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/147468.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/147468.html</trackback:ping><description><![CDATA[<div style="margin-top: 5px; margin-left: 15px"><strong>关键字:</strong> 设计模式 &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; </div>
<div style="margin-top: 10px; margin-left: 15px; overflow: auto">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>代理模式：为其他对象提供一种代理以控制对这个对象的访问．说白了就是，在一些情况下客户不想或不能直接引一个对象，而代理对象可以在客户和目标对象之间起到中介作用．去掉客户不能看到的内容和服务或都增添客户需要的额外服务． <br />
            给大家举个比较简单的例子： <br />
            假如你买台IBM的笔记本，IBM产家是不提供鼠标的．但是我们如果从代理商的手里买就有鼠标和送． <br />
            很简单的例子，写几个类来实现一下吧． <br />
            首先设计一个购买的接口代码如下：（ComputerInterface.java） <br />
            package test.lyx; <br />
            publicinterface ComputerInterface { <br />
            publicvoid buy(); <br />
            } <br />
            建一个电脑类实现购买的接口代码如下：（Computer.java） <br />
            package test.lyx; <br />
            publicclass Computer implements ComputerInterface{ <br />
            private String pcName="IBMT60"; <br />
            privateintpcPrice=17800; <br />
            public String getPcName() { <br />
            returnpcName; <br />
            } <br />
            publicvoid setPcName(String pcName) { <br />
            this.pcName = pcName; <br />
            } <br />
            publicint getPcPrice() { <br />
            returnpcPrice; <br />
            } <br />
            publicvoid setPcPrice(int pcPrice) { <br />
            this.pcPrice = pcPrice; <br />
            } <br />
            publicvoid buy() { <br />
            System.out.print("获得笔记本电脑："+pcName+"一台"); <br />
            } <br />
            } <br />
            再建设一个代理商的类：用来完成买电脑和赠送鼠标：（ComputerProxy.java） <br />
            package test.lyx; <br />
            publicclass ComputerProxy { <br />
            private ComputerInterface pci; <br />
            public ComputerInterface getPci() { <br />
            returnpci; <br />
            } <br />
            publicvoid setPci(ComputerInterface pci) { <br />
            this.pci = pci; <br />
            } <br />
            publicvoid buy(){ <br />
            pci.buy(); <br />
            System.out.println("赠送鼠标一个"); <br />
            } <br />
            } <br />
            建一个主函数测试一下吧：（TestDemo.java） <br />
            package test.lyx; <br />
            publicclass TestDemo { <br />
            publicstaticvoid main(String[] args) { <br />
            ComputerProxy c1=new ComputerProxy(); <br />
            c1.setPci(new Computer()); <br />
            c1.buy(); <br />
            } <br />
            } <br />
            运行结果如下： <br />
            获得笔记本电脑：IBMT60一台获得鼠标一个 <br />
            以上就是代理功能的实现，由代理商销售笔记本，并赠送鼠标．但是这样的程序只适合是销售ＩＢＭ笔记本．那么如果要是其它品牌呢．所以我们来更改一个代理类．来实现动态的代理． <br />
            建立一个类代码如下：（ComputerProxy2．java） <br />
            package test.lyx; <br />
            import java.lang.reflect.InvocationHandler; <br />
            import java.lang.reflect.Method; <br />
            import java.lang.reflect.Proxy; <br />
            publicclass ComputerProxy2 implements InvocationHandler{ <br />
            private Object delegate; <br />
            //描述是谁的代理，也就是与那个类有关系 <br />
            public Object bind(Object delegate){ <br />
            this.delegate=delegate; <br />
            return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(),this); <br />
            } <br />
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { <br />
            System.out.println("赠送鼠标一个！"); <br />
            Object result=method.invoke(delegate, args); <br />
            return result; <br />
            } <br />
            } <br />
            然后在主函数中加上： <br />
            ComputerProxy2 c2=new ComputerProxy2(); <br />
            ComputerInterface ci2=(ComputerInterface)c2.bind(new Computer()); <br />
            ci2.buy(); <br />
            就可以实现动态代理了． <br />
            [b][/b]</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div class="topic_summary">
<table width="100%">
    <tbody>
        <tr>
            <td valign="bottom" width="90%">最后更新：2007-07-06 19:12<br />
            14:46&nbsp;&nbsp;|&nbsp;&nbsp; <a href="javascript:Element.toggle('link53795');">永久链接</a>&nbsp;&nbsp;|&nbsp;&nbsp; 浏览&nbsp;(7023)&nbsp;&nbsp;|&nbsp;&nbsp; <a href="http://lyx.javaeye.com/blog/53795#comments">评论</a>&nbsp;(20)&nbsp;&nbsp;| &nbsp;&nbsp; <a href="http://lyx.javaeye.com/admin/favorite_blog/222215">收藏</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a href="http://lyx.javaeye.com/category/52617?category=9909">java</a>&nbsp;&nbsp;|&nbsp;&nbsp; <a href="http://lyx.javaeye.com/topic/53795">进入论坛</a>&nbsp;&nbsp;|&nbsp;&nbsp; </td>
            <td width="10%"></td>
        </tr>
    </tbody>
</table>
</div>
<div class="topic_link" id="link53795" style="display: none">
<table width="90%" align="center" border="0">
    <tbody>
        <tr>
            <td align="left" height="30"><span class="date_show">永久链接</span></td>
        </tr>
        <tr>
            <td align="left"><a href="http://lyx.javaeye.com/blog/53795">http://lyx.javaeye.com/blog/53795</a> </td>
        </tr>
    </tbody>
</table>
</div>
<div><a name="comments"></a>
<div style="border-top: gray 1px solid; margin-top: 15px">
<div id="comment-list" style="margin: 10px 20px 0px">
<div>
<table width="100%">
    <tbody>
        <tr valign="top">
            <td width="50%"><strong class="title">评论</strong> &nbsp;&nbsp;&nbsp;共 20 条 </td>
            <td align="right" width="50%"><a href="javascript:Field.focus('message');">发表评论</a> </td>
        </tr>
    </tbody>
</table>
</div>
<div style="margin-top: 10px">
<div id="post_222314">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://rubin.javaeye.com/">rubin</a> &nbsp;&nbsp;&nbsp; 2007-02-11 21:32 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>能否说下动态代理的原理？比如，ci2.buy(); 为什么就能执行，而ComputerProxy2 并没有这个函数？</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_222773">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://lyx.javaeye.com/">lyx_2709</a> &nbsp;&nbsp;&nbsp; 2007-02-12 16:09 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>动态代理一定要实现这个InvocationHandle接口．接口里面有两个方法．一个bind描述代理那个类，也就是与那个类有关系，主函数里我调用bind方法时给出Computer．也就是代理的Computer类．还有一个方法invoke就是代理与要执行的方法．</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_223890">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://rubin.javaeye.com/">rubin</a> &nbsp;&nbsp;&nbsp; 2007-02-14 18:57 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>哦，我看错了，现在明白了，多谢！</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_223935">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://lyx.javaeye.com/">lyx_2709</a> &nbsp;&nbsp;&nbsp; 2007-02-14 21:07 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>呵呵，客气什么．互相学习吧．</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_224952">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://weiqingfei.javaeye.com/">weiqingfei</a> &nbsp;&nbsp;&nbsp; 2007-02-20 09:47 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>按照代理模式的定义 <br />
            代理类和被代理类都要实现统一的一个接口， <br />
            也就是说Computer，和ComputerProxy都应该实现ComputerInterface， <br />
            既然这样，你的第一个实现里，厂商和代理上应该是可以随便组合的，怎么就只适合&#8220;IBM笔记本&#8221;了？</p>
            <p>你为什么有搞一个动态代理呢？有什么优点儿？</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_224983">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://lyx.javaeye.com/">lyx_2709</a> &nbsp;&nbsp;&nbsp; 2007-02-20 17:11 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>对啊，ＩＢＭ的本只送鼠标．如果现在ＳＯＮＹ的本送鼠标和包，静态的代理就实现不了了．只有改程序了．使用动态代理，我们只关注买的是什么品牌的本．送的是什么东西．</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_225024">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://weiqingfei.javaeye.com/">weiqingfei</a> &nbsp;&nbsp;&nbsp; 2007-02-21 08:27 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>
            <div class="quote_title">lyx_2709 写道</div>
            <div class="quote_div">对啊，ＩＢＭ的本只送鼠标．如果现在ＳＯＮＹ的本送鼠标和包，静态的代理就实现不了了．只有改程序了．使用动态代理，我们只关注买的是什么品牌的本．送的是什么东西．</div>
            <p>&nbsp;</p>
            <p>好，如果你让你这个动态代理去卖SONY的本子，他怎么送包？你还不是要修改invoke方法么？</p>
            <p>动态代理的好处并不是要动态处理不同的任务，而是动态处理不同的类型，我所说的类型，指的是接口类型。 <br />
            如果说你的IBM本和sony本继承的同样的接口，用动态代理一点儿意义都没有了。因为它和静态代理一样，只能完成一件附加任务。</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_225480">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://lyx.javaeye.com/">lyx_2709</a> &nbsp;&nbsp;&nbsp; 2007-02-23 14:51 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>嗯，也有道理， <br />
            为其他对象提供一种代理以控制对这个对象的访问，说白了就是，在一些情况下客户不想或都不能直接引用一个对象，而代理对象可以在客户和目标对象之间起到中介作用，去掉客户不能看到的内容和服务或都增添客户需要的额外服务． <br />
            无论是什么代理商本是肯定的卖的，我们就要实现ComputerInterface这个接口，而不同的代理商优惠的条件不同，在这里也就是说赠的东西不同，我们代理的目的，和现时一样，本本卖的基础上，各个代理商送的东西不同．invoke这个方法在这里就描述了我们送的是什么东西． <br />
            我是这样认为的． </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_225560">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://weiqingfei.javaeye.com/">weiqingfei</a> &nbsp;&nbsp;&nbsp; 2007-02-23 21:23 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>
            <div class="quote_title">lyx_2709 写道</div>
            <div class="quote_div">嗯，也有道理， <br />
            为其他对象提供一种代理以控制对这个对象的访问，说白了就是，在一些情况下客户不想或都不能直接引用一个对象，而代理对象可以在客户和目标对象之间起到中介作用，去掉客户不能看到的内容和服务或都增添客户需要的额外服务． <br />
            无论是什么代理商本是肯定的卖的，我们就要实现ComputerInterface这个接口，而不同的代理商优惠的条件不同，在这里也就是说赠的东西不同，我们代理的目的，和现时一样，本本卖的基础上，各个代理商送的东西不同．invoke这个方法在这里就描述了我们送的是什么东西． <br />
            我是这样认为的． <br />
            </div>
            <p>&nbsp;</p>
            <p>可能我们想的都一样，只是描述的不是很清楚吧。</p>
            <p>动态代理和静态代理的主要区别是，静态代理已经知道自己要代理什么类型的东西了，而动态代理却不知道。 <br />
            比如说，静态代理已经明确是代理买还是卖，还是修理。</p>
            <p>但是动态代理不知道，它可以代理一切，只要是有可代理的东西。</p>
            <p>但是在代理商自己的附加动作上，两种代理方式应该都是确定了的。 <br />
            如果一个代理商要送鼠标，那他只能送鼠标，不管他是卖什么东西。 <br />
            如果想送鼠标又要送键盘，那就得再找一个代理商，不管是静态的还是动态的。</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<div id="post_247830">
<div class="light_b" style="padding-right: 2px; margin-top: 10px; padding-left: 2px; padding-bottom: 2px; padding-top: 2px"><a href="http://qinysong.javaeye.com/">qinysong</a> &nbsp;&nbsp;&nbsp; 2007-03-24 12:58 </div>
<div style="margin-top: 5px">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <p>
            <div class="quote_title">lyx_2709 写道</div>
            <div class="quote_div">代理模式：为其他对象提供一种代理以控制对这个对象的访问．说白了就是，在一些情况下客户不想或不能直接引一个对象，而代理对象可以在客户和目标对象之间起到中介作用．去掉客户不能看到的内容和服务或都增添客户需要的额外服务． <br />
            给大家举个比较简单的例子： <br />
            假如你买台IBM的笔记本，IBM产家是不提供鼠标的．但是我们如果从代理商的手里买就有鼠标和送． <br />
            很简单的例子，写几个类来实现一下吧． <br />
            首先设计一个购买的接口代码如下：（ComputerInterface.java） <br />
            package test.lyx; <br />
            publicinterface ComputerInterface { <br />
            publicvoid buy(); <br />
            } <br />
            建一个电脑类实现购买的接口代码如下：（Computer.java） <br />
            package test.lyx; <br />
            publicclass Computer implements ComputerInterface{ <br />
            private String pcName="IBMT60"; <br />
            privateintpcPrice=17800; <br />
            public String getPcName() { <br />
            returnpcName; <br />
            } <br />
            publicvoid setPcName(String pcName) { <br />
            this.pcName = pcName; <br />
            } <br />
            publicint getPcPrice() { <br />
            returnpcPrice; <br />
            } <br />
            publicvoid setPcPrice(int pcPrice) { <br />
            this.pcPrice = pcPrice; <br />
            } <br />
            publicvoid buy() { <br />
            System.out.print("获得笔记本电脑："+pcName+"一台"); <br />
            } <br />
            } <br />
            再建设一个代理商的类：用来完成买电脑和赠送鼠标：（ComputerProxy.java） <br />
            package test.lyx; <br />
            publicclass ComputerProxy { <br />
            private ComputerInterface pci; <br />
            public ComputerInterface getPci() { <br />
            returnpci; <br />
            } <br />
            publicvoid setPci(ComputerInterface pci) { <br />
            this.pci = pci; <br />
            } <br />
            publicvoid buy(){ <br />
            pci.buy(); <br />
            System.out.println("赠送鼠标一个"); <br />
            } <br />
            } <br />
            建一个主函数测试一下吧：（TestDemo.java） <br />
            package test.lyx; <br />
            publicclass TestDemo { <br />
            publicstaticvoid main(String[] args) { <br />
            ComputerProxy c1=new ComputerProxy(); <br />
            c1.setPci(new Computer()); <br />
            c1.buy(); <br />
            } <br />
            } <br />
            运行结果如下： <br />
            获得笔记本电脑：IBMT60一台获得鼠标一个 <br />
            以上就是代理功能的实现，由代理商销售笔记本，并赠送鼠标．但是这样的程序只适合是销售ＩＢＭ笔记本．</div>
            <br />
            对于这个代理的例子，我觉得有两个问题：
            <p>&nbsp;</p>
            <p>第一，这个例子所表现的不是代理Proxy模式，而是装饰器Decorator模式，Decorator模式正是这个例子所表现的为对象动态的添加一些额外的功能或职责；</p>
            <p>第二，无论是Proxy模式还是Decorator模式，他们有一个相同的一点是他们与被代理和被装饰的对象具有相同的接口，以便为客户提供透明性，而这点上面的例子没有实现。</p>
            <p>对于Proxy和Decorator的比较，可以看看这篇帖子<a href="http://www.javaeye.com/topic/39053" target="blank">http://www.javaeye.com/topic/39053</a> <br />
            以上只是个人看法，共同探讨</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/147468.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-09-22 21:20 <a href="http://www.blogjava.net/libin2722/articles/147468.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>webwork视频目录</title><link>http://www.blogjava.net/libin2722/articles/147466.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 22 Sep 2007 13:06:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/147466.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/147466.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/147466.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/147466.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/147466.html</trackback:ping><description><![CDATA[<table cellspacing="1" cellpadding="1" width="591" align="center" summary="版权所有:未经本人允许不得转载，篡改。" border="1">
    <caption>webwork原创视频</caption>
    <tbody>
        <tr>
            <td>类型</td>
            <td>名称</td>
            <td>下载地址</td>
        </tr>
        <tr>
            <td><font face="Arial">webwork</font></td>
            <td><font face="Arial">webwork初体验</font></td>
            <td><font face="Arial"><a href="http://lyx.javaeye.com/blog/56547">http://lyx.javaeye.com/blog/56547</a>　</font></td>
        </tr>
        <tr>
            <td><font face="Arial">webwork</font></td>
            <td><font face="Arial">Model-Driven（模型驱动）、配置表单验证</font></td>
            <td><font face="Arial"><a href="http://lyx.javaeye.com/blog/55986">http://lyx.javaeye.com/blog/55986</a></font></td>
        </tr>
        <tr>
            <td><font face="Arial">webwork</font></td>
            <td>junit测试</td>
            <td><a href="http://lyx.javaeye.com/blog/57037" target="_blank">http://lyx.javaeye.com/blog/57037</a></td>
        </tr>
        <tr>
            <td><font face="Arial">webwork</font></td>
            <td>国际化</td>
            <td>&nbsp;<font face="Arial"><font face="Arial"><a href="http://lyx.javaeye.com/blog/57037" target="_blank">http://lyx.javaeye.com/blog/57838</a></font></font></td>
        </tr>
        <tr>
            <td><font face="Arial">webwork</font></td>
            <td>webwork集成spring</td>
            <td>&nbsp;<font face="Arial">&nbsp;<font face="Arial"><font face="Arial"><a href="http://lyx.javaeye.com/blog/57037" target="_blank">http://lyx.javaeye.com/blog/58242</a></font></font></font></td>
        </tr>
        <tr>
            <td>webwork</td>
            <td>webwork上传</td>
            <td><a href="http://lyx.javaeye.com/blog/68039"><font color="red">下载地址</font></a></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/libin2722/aggbug/147466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-09-22 21:06 <a href="http://www.blogjava.net/libin2722/articles/147466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Model-Driven（模型驱动）、配置表单验证 </title><link>http://www.blogjava.net/libin2722/articles/147463.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Sat, 22 Sep 2007 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/147463.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/147463.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/147463.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/147463.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/147463.html</trackback:ping><description><![CDATA[用登陆演示<strong><span>Model-Driven（模型驱动）</span></strong><strong><span>、配置表单验证</span></strong>
<div align="left"><span style="line-height: 150%">本文主要在<span>上一个视频（webwork初体验</span>）的基本进行改动，所以在看本文之前，请先浏览上一个视频。</span></div>
<div><span style="line-height: 150%">在</span><span>webwork</span><span>中</span><span>Action</span><span>根据</span><span>Form</span><span>的不同可分为二类：</span></div>
<div><span style="line-height: 150%">一种是</span><span>Field-Driven</span><span>（字段驱动）</span><span>Action</span><span>；就是</span><span> Action</span><span>用自己的字段来充当</span><span>Form</span><span>的角色，上一个视频给大家演示的例子就是采用了这种方式。<span style="color: #003366">本人感觉有点像</span></span><span>struts</span><span>中的动态</span><span>Form</span><span>。</span></div>
<div><span style="line-height: 150%">当然这只是我自己的一些看法。还有一种是</span><span>Model-Driven</span><span>（模型驱动）</span><span>Action</span><span>。它很像</span><span>Struts</span><span>的</span><span>Form,</span><span>但在</span><span>struts</span><span>中</span><span>Form</span><span>必须继承</span><span>org.apache.struts.action.ActionForm;</span><span>或是</span><span>org.apache.struts.validator</span><span>包下的几个</span><span>Form.</span><span>在</span><span>WebWork</span><span>中有所不同，<span style="color: red">只要普通</span></span><span>JavaBean</span><span>就可以充当模型部分</span><span>。只要我们在</span><span>Action</span><span>中实现</span><span>com.opensymphony.xwork. ModelDriven</span><span>接口就可以了，它有一个方法：</span><span>Object getModel();</span><span>，这个方法用于返回模型对象。</span></div>
<div><span style="line-height: 150%">我们改动上个视频的</span><span>LoginAction</span><span style="line-height: 150%">类。代码如下：
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.lyx.web.action; &nbsp;&nbsp;</span></span>
    <li class=""><span class="keyword">import</span><span>&nbsp;com.lyx.bo.User; &nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.Action; &nbsp;&nbsp;</span>
    <li class=""><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.ActionSupport; &nbsp;&nbsp;</span>
    <li class="alt"><span class="keyword">import</span><span>&nbsp;com.opensymphony.xwork.ModelDriven; &nbsp;&nbsp;</span>
    <li class=""><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;LoginAction&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Action,<font color="#ff0000">ModelDriven</font>&nbsp;{ &nbsp;&nbsp;</span>
    <li class="alt"><span class="comment">//注意这里的User一定要初始化 </span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;User&nbsp;user=</span><span class="keyword">new</span><span>&nbsp;User(); &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;User&nbsp;getUser()&nbsp;{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;String&nbsp;execute()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(user.getUserName().equals(</span><span class="string">"lyx"</span><span>)){ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.SUCCESS; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span class="keyword">else</span><span>{ &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.ERROR; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;<font color="#ff0000">&nbsp;&nbsp;&nbsp;</font></span><font color="#ff0000"><span class="keyword"><font color="#ff0000">public</font></span><span><font color="#ff0000">&nbsp;Object&nbsp;getModel()&nbsp;{</font> &nbsp;&nbsp;</span></font>
    <li class="alt"><font color="#ff0000"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub </span><span>&nbsp;&nbsp;</span></font>
    <li class=""><font color="#ff0000"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span></font>
    <li class="alt"><span><font color="#ff0000">&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</font></span>
    <li class=""><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
</span></div>
<div><span>红色字体部是我们后加部分。</span></div>
<div><span>然后我们就可以将</span><span>index.jsp</span><span>页面的代码修改如下：</span></div>
<div align="left"><span>&lt;</span><span>form </span><span>action</span><span>=</span><span>"login.action"</span><span>&gt;</span></div>
<div align="left">&nbsp;</div>
<div align="left"><span>username:</span><span>&lt;</span><span>input </span><span>type</span><span>=</span><span>"text" </span><span>name</span><span>=</span><span>"userName"</span><span>/&gt;</span></div>
<div align="left"><span>password:</span><span>&lt;</span><span>input </span><span>type</span><span>=</span><span>"password" </span><span>name</span><span>=</span><span>"userPwd"</span><span>/&gt;</span></div>
<div align="left"><span>&lt;</span><span>input </span><span>type</span><span>=</span><span>"submit" </span><span>value</span><span>=</span><span>"login"</span><span>/&gt;</span></div>
<div><span><span style="font-size: 10pt; color: #3f7f7f">form</span><span>&gt;</span></span></div>
<div><span>也就是我们去掉了原有的表达式语言。</span></div>
<div>然后我们修改xwork.xml配置文件如下：
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span>&lt;!--CTYPE&nbsp;xwork&nbsp;PUBLIC&nbsp;"-//OpenSymphony&nbsp;Group//XWork&nbsp;1.0//EN"&nbsp;"http://www.opensymphony.com/xwork/xwork-1.0.dtd"&lt;/sp--&gt;<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </span>
    <li class=""><span class="tag">&lt;</span><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">file</span><span>=</span><span class="attribute-value">"webwork-default.xml"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"default"</span><span>&nbsp;</span><span class="attribute">extends</span><span>=</span><span class="attribute-value">"webwork-default"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">action</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"login"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.lyx.web.action.LoginAction"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;&nbsp;登录成功后跳转到&nbsp;/success.jsp&nbsp;页面&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"success"</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"dispatcher"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"location"</span><span class="tag">&gt;</span><span>/success.jsp</span><span class="tag"><span class="tag-name">param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;&nbsp;登录失败后跳转到&nbsp;/error.jsp&nbsp;页面&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"error"</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"dispatcher"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"location"</span><span class="tag">&gt;</span><span>/error.jsp</span><span class="tag"><span class="tag-name">param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><font color="#ff0000"><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"model-driven"</span><span class="tag">/&gt;</span></font><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"params"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">action</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">package</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span class="tag"><span class="tag-name">xwork</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
</div>
<div>也就是在原有的基础上加了一行模型驱动的拦截器。作用就是将模型对象保存到值堆栈中。</div>
<div>就样就ＯＫ了。<span>这里要注意，</span><span>model-driven</span><span>拦截器要在</span><span>params</span><span>的上面</span>。可以测试一下看看。</div>
<div>整过过程，非常像struts中，Action与ActionForm的关系。</div>
<div>通过测试，功能和以前的一样。很简单吧。就不在多述了。</div>
<div><span>第二个重点我们来配置一个表单的验证：</span></div>
<div><span>在 src 目录下新建 </span><strong><span>validators.xml </span></strong><span style="font-size: 10pt">文件，文件内容如下：
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">validators</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"required"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.RequiredFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"requiredstring"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.RequiredStringValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"int"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.IntRangeFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"date"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.DateRangeFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"expression"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.ExpressionValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"fieldexpression"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.FieldExpressionValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"email"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.EmailValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"url"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.URLValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"visitor"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.VisitorFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"conversion"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">validator</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"stringlength"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.opensymphony.xwork.validator.validators.StringLengthFieldValidator"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span class="tag"><span class="tag-name">validators</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
</span></div>
<div><span style="font-size: 10pt">这个文件可以在网上下得到。也可以在</span><span>webwork</span><span>的源码中得到。不是不想起了</span><span>struts</span><span>中有个</span><span>valiator-rules.xml</span><span>文件。这个文件在</span><span>struts</span><span>中是描述着验证的规则，里面有好多已经写好了的验证，我们可以很方便的调用。这里的这个文件功能和</span><span>struts</span><span>中的类似。</span></div>
<div align="left"><strong><span>&nbsp;&nbsp; </span></strong><span>要启动表单验证</span><span>，</span><span>需要增加一个拦截器</span><span>，</span><span>还有就是我们在</span><span>struts</span><span>的</span><span>struts-config.xml</span><span>配置文件中Action的配置有个input属性，它是用来当验证失败时所在跳到的页，在这里如果登陆失败我们应该跳到index页，显示失败的原因，重新登陆。在webwork中我们也用<span style="color: red">input</span>来描述这个功能。在一个result.</span></div>
<div align="left"><span>对</span><span>xwork.xml </span><span>文件进行修改</span><span>，</span><span>增加</span><span>&lt;</span><span>interceptor-ref </span><span>name</span><span>=</span><span>"</span><span>validationWorkflowStack</span><span>" </span><span>/&gt;</span></div>
<div align="left"><span>修改后</span><span>xwork.xml</span><span style="font-size: 10pt; color: teal">代码如下：
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">include</span><span>&nbsp;</span><span class="attribute">file</span><span>=</span><span class="attribute-value">"webwork-default.xml"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">package</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"default"</span><span>&nbsp;</span><span class="attribute">extends</span><span>=</span><span class="attribute-value">"webwork-default"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">action</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"login"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"com.lyx.web.action.LoginAction"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;&nbsp;登录成功后跳转到&nbsp;/success.jsp&nbsp;页面&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"success"</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"dispatcher"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"location"</span><span class="tag">&gt;</span><span>/success.jsp</span><span class="tag"><span class="tag-name">param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comments">&lt;!--&nbsp;&nbsp;登录失败后跳转到&nbsp;/error.jsp&nbsp;页面&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"error"</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"dispatcher"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"location"</span><span class="tag">&gt;</span><span>/error.jsp</span><span class="tag"><span class="tag-name">param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">result</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"input"</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"dispatcher"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">param</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"location"</span><span class="tag">&gt;</span><span>/index.jsp</span><span class="tag"><span class="tag-name">param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">result</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"model-driven"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"params"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">interceptor-ref</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"validationWorkflowStack"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">action</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">package</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
</span></div>
<div align="left"><span>我们已经用到了</span><span>success</span><span>，他指成功所要跳到的页。</span><span>Error</span><span>是错误所要跳到的页。</span><span>Input</span><span>是指失败时所要返回来登陆的页。在</span><span>webwork</span><span>中还有几个。以后我们会看得到，用到的时候在详细讲解。</span></div>
<div align="left"><span>&nbsp;&nbsp; </span><span>建立验证规则</span></div>
<div align="left"><strong>&nbsp;</strong></div>
<div align="left"><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><span>对</span><span> <span style="color: blue">LoginAction </span></span><span>进行验证规则的配置</span><span>，</span><span>需要新建一个配置文件</span><span>，</span><span>文件名起名是以</span><span>Action </span><span>的名称开头以</span><span>validation</span><span>结尾，中间用</span><span>&#8221;</span><span>-</span><span>&#8221;</span><span>隔开.xml</span><span>并保存到</span><span> <span style="color: blue">LoginAction.java </span></span><span>文件所在的目录中</span></div>
<div align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></div>
<div align="left"><span>&nbsp;&nbsp; 代码如下：<span style="font-size: 10pt">&nbsp;<strong><span style="color: blue">LoginAction-validation.xml
<div class="code_title">
<div class="code_title">xml 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-xml">
    <li class="alt"><span><span>&lt;!--CTYPE&nbsp;validators&nbsp;PUBLIC&nbsp;"-//OpenSymphony&nbsp;Group//XWork&nbsp;Validator&nbsp;1.0//EN"&nbsp;"http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"&lt;/sp--&gt;<span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span> </span>
    <li class=""><span class="tag">&lt;</span><span class="tag-name">validators</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">field</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"userName"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">field-validator</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"requiredstring"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">message</span><span class="tag">&gt;</span><span>username&nbsp;is&nbsp;required!</span><span class="tag"><span class="tag-name">message</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">field-validator</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">field</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">field</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"userPwd"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">field-validator</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"requiredstring"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">message</span><span class="tag">&gt;</span><span>&nbsp;password&nbsp;is&nbsp;required!</span><span class="tag"><span class="tag-name">message</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">field-validator</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">field</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span>
    <li class="alt"><span class="tag"><span class="tag-name">validators</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </span></li>
</ol>
</div>
</div>
<span><span></span></span></span></strong></span></span></div>
<div align="left"><span>这个文件很像</span><span>struts</span><span>中的</span><span>validation.xml</span><span>。功能和他是一样的。配置表单的验证。这里我们只验证也用户名和密码为必须填写。注意：这个</span><span>name</span><span>的属性一定要和</span><span>User</span><span>类中的对应。规则是和</span><span>struts</span><span>中一样的。对应才能有交的验证。</span></div>
<div align="left"><span>为了能显示验证的信息再次修改</span><span>index</span><span>页面如下：</span></div>
<div align="left"><span>&lt;</span><span>ww:form&nbsp;</span><span>action</span><span>=</span><span>"login.action" </span><span>method</span><span>=</span><span>"POST"</span><span>&gt;</span></div>
<div align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username:&nbsp;&nbsp; </span><span>&lt;</span><span>ww:textfield </span><span>label</span><span>=</span><span>"Username" </span><span>name</span><span>=</span><span>"userName" </span><span>required</span><span>=</span><span>"true"</span><span>/&gt;</span></div>
<div align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password:&nbsp;</span><span>&lt;</span><span>ww:password </span><span>label</span><span>=</span><span>"Password" </span><span>name</span><span>=</span><span>"userPwd" </span><span>required</span><span>=</span><span>"true"</span><span>/&gt;</span></div>
<div align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&lt;</span><span>ww:submit </span><span>value</span><span>=</span><span>"Submit"</span><span>/&gt;</span></div>
<div align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span><span style="font-size: 10pt; color: #3f7f7f">ww:form</span><span>&gt;</span></span></div>
<div align="left"><span>这几行很简单，从字面上就可以看出，就不在多述了。</span></div>
<div align="left"><span>基本代码就这些，测试一下，看看吧。</span></div>
<div align="left"><span>哦，没有验证，还忘了一步，回头看看</span></div>
<div align="left"><span>除了上述的配置外，我们的</span><span>Action</span><span>还要继承</span><span>ActionSupport类，这个类存放着错误的信息，并能将错误的状态返回到页面</span></div>
<div align="left"><span>在改一下，试试</span></div>
<div align="left"><span>ＯＫ了。好用了。呵呵，刚是太急用了，忘了最关键的一步。大家在开发当中可以细心点啊。</span></div>
<div align="left"><span>因为，录这个视频是在公司，不能有声音讲解给大家听。请大家谅解。这段时间比较忙，过了这段时间，给大家录个有声音的。呵呵。</span></div>
<div align="left"><span>我的联系方式：</span></div>
<div align="left"><span>ＭＳＮ；<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#76;&#121;&#120;&#95;&#50;&#55;&#48;&#57;&#64;&#104;&#111;&#116;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">Lyx_2709@hotmail.com</a></span></div>
<div align="left"><span>Email:Lyx_happy@163.com</span></div>
<div align="left"><span>就到这里吧。希望大家能多提宝贵意见！</span></div>
<div style="padding-right: 10px; border-top: gray 1px solid; padding-left: 10px; padding-bottom: 10px; margin: 15px 0px 0px 10px; padding-top: 10px">
<table class="attach" cellspacing="0" cellpadding="2" width="95%" align="center" border="1">
    <tbody>
        <tr>
            <td class="attachrow" style="background: #d1d7dc" align="center" width="100%" colspan="3"><strong><span class="gen">webwork模型驱动与表单验证.part1.rar</span></strong></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;描述:</span></td>
            <td class="attachrow" width="75%">&nbsp;第一部分视频 </td>
            <td class="attachrow" align="center" width="10%" rowspan="4"><img alt="" src="http://lyx.javaeye.com/images/forum/icon_clip.gif" border="0" /><br />
            <a href="javascript:login_show();"><strong>下载</strong></a> </td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件名:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;webwork模型驱动与表单验证.part1.rar</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件大小:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;3 M</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;下载过的:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;文件被下载或查看 1277 次</span></td>
        </tr>
    </tbody>
</table>
</div>
<div style="padding-right: 10px; border-top: gray 1px solid; padding-left: 10px; padding-bottom: 10px; margin: 15px 0px 0px 10px; padding-top: 10px">
<table class="attach" cellspacing="0" cellpadding="2" width="95%" align="center" border="1">
    <tbody>
        <tr>
            <td class="attachrow" style="background: #d1d7dc" align="center" width="100%" colspan="3"><strong><span class="gen">webwork模型驱动与表单验证.part2.rar</span></strong></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;描述:</span></td>
            <td class="attachrow" width="75%">&nbsp;第二部分视频 </td>
            <td class="attachrow" align="center" width="10%" rowspan="4"><img alt="" src="http://lyx.javaeye.com/images/forum/icon_clip.gif" border="0" /><br />
            <a href="javascript:login_show();"><strong>下载</strong></a> </td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件名:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;webwork模型驱动与表单验证.part2.rar</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件大小:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;3 M</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;下载过的:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;文件被下载或查看 1101 次</span></td>
        </tr>
    </tbody>
</table>
</div>
<div style="padding-right: 10px; border-top: gray 1px solid; padding-left: 10px; padding-bottom: 10px; margin: 15px 0px 0px 10px; padding-top: 10px">
<table class="attach" cellspacing="0" cellpadding="2" width="95%" align="center" border="1">
    <tbody>
        <tr>
            <td class="attachrow" style="background: #d1d7dc" align="center" width="100%" colspan="3"><strong><span class="gen">webworkfirst.rar</span></strong></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;描述:</span></td>
            <td class="attachrow" width="75%">&nbsp;程序源码 </td>
            <td class="attachrow" align="center" width="10%" rowspan="4"><img alt="" src="http://lyx.javaeye.com/images/forum/icon_clip.gif" border="0" /><br />
            <a href="javascript:login_show();"><strong>下载</strong></a> </td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件名:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;webworkfirst.rar</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;文件大小:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;8 KB</span></td>
        </tr>
        <tr>
            <td class="attachrow" width="15%"><span class="genmed">&nbsp;下载过的:</span></td>
            <td class="attachrow" width="75%"><span class="genmed">&nbsp;文件被下载或查看 350 次</span></td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/libin2722/aggbug/147463.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-09-22 21:03 <a href="http://www.blogjava.net/libin2722/articles/147463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse 属性文件，自动转为Unicode编码</title><link>http://www.blogjava.net/libin2722/articles/146830.html</link><dc:creator>礼物</dc:creator><author>礼物</author><pubDate>Thu, 20 Sep 2007 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/libin2722/articles/146830.html</guid><wfw:comment>http://www.blogjava.net/libin2722/comments/146830.html</wfw:comment><comments>http://www.blogjava.net/libin2722/articles/146830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/libin2722/comments/commentRss/146830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/libin2722/services/trackbacks/146830.html</trackback:ping><description><![CDATA[<font size="4"><strong>[ INSTALLATION ]</strong></font><br />
<br />
<ol>
    <li>Please choose from the screen of Eclipse with "Help" -&gt;"Software Updates" -&gt; "Update Manager". An 'Update Manager' opens.<br />
    <br />
    <li>In the "Feature Updates" view at the lower left of an 'Update Manager', please carry out the right click of the "Sites to Visit", and create a site bookmark by "New" -&gt; "Site Bookmark...".<br />
    - The bookmark to create should input the following "URL" and should push an "Finish" button.<br />
    Name: Arbitrary input<br />
    URL : http://propedit.sourceforge.jp/eclipse/updates/<br />
    Bookmark type: Eclipse update site<br />
    <br />
    <li>If a site bookmark is created, the bookmark created at the bottom of "Feature Updates" will appear.<br />
    A click of "jp.gr.java_conf.ussiy.app.propedit.eclipse.feature.PropertiesEditorFeature x.x.x" displays a preview on a right window. Since the button "Install Now" is in around the lower right, please click.<br />
    <br />
    <li>Since an installation wizard starts, please click a "Next" button rapidly.<br />
    <br />
    <li>"You will need to restart the workbench for the changes to take effect. Would you like to restart now?" is displayed. Please reboot Eclipse according to a dialog.<br />
    <br />
    </li>
</ol>
<img src ="http://www.blogjava.net/libin2722/aggbug/146830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/libin2722/" target="_blank">礼物</a> 2007-09-20 17:21 <a href="http://www.blogjava.net/libin2722/articles/146830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>