久久精品天堂,中文一区在线,av在线天堂播放http://www.aygfsteel.com/alancxx/------簡(jiǎn)單就是美zh-cnTue, 29 Jul 2025 13:31:22 GMTTue, 29 Jul 2025 13:31:22 GMT60oracle jdbc 邪惡數(shù)字"65536" ---批量插入10萬條記錄引發(fā)的“血案”http://www.aygfsteel.com/alancxx/articles/369106.html蜂鳥蜂鳥Tue, 31 Jan 2012 12:17:00 GMThttp://www.aygfsteel.com/alancxx/articles/369106.htmlhttp://www.aygfsteel.com/alancxx/comments/369106.htmlhttp://www.aygfsteel.com/alancxx/articles/369106.html#Feedback1http://www.aygfsteel.com/alancxx/comments/commentRss/369106.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/369106.html1.   故事背景:

mysql數(shù)據(jù)遷移到oracle,其中有個(gè)表名叫“bil_vip”,有10萬條記錄,遷移后檢查發(fā)現(xiàn)oracle數(shù)據(jù)庫只插入34464條記錄,程序執(zhí)行過程沒有發(fā)現(xiàn)任何錯(cuò)誤。修改數(shù)據(jù)庫連接代碼向mysql插入10萬條記錄,結(jié)果都插入OK。

批量插入使用spring jdbctemplate.batchUpdate(sql, new BatchPreparedStatementSetter());方法,該方法的核心是PreparedStatement的executeBatch方法。

2.   繼續(xù)實(shí)驗(yàn):

新建一個(gè)Test表,只有一個(gè)name字段做實(shí)驗(yàn)。

拋棄jdbctemplate,直接使用PreparedStatement做實(shí)驗(yàn),結(jié)果和jdbcTemplate是一樣的,實(shí)驗(yàn)證明總是會(huì)丟失65536條記錄。

oracle 驅(qū)動(dòng)的問題?換了最新driver,還是不行。繼續(xù)探索....

3.   希望之光:

早上發(fā)了個(gè)消息向大家征求思路,繼中說了一句分批處理,點(diǎn)亮了我的思路。按照繼中提供思路,每1萬條記錄一批,分多批發(fā)送給Oracle。

結(jié)果喜出望外,10萬條記錄全部插入成功。但是"65536"這個(gè)數(shù)字是什么意思呢......     

在網(wǎng)上搜索文章發(fā)現(xiàn),這個(gè)65536是一個(gè)bug。當(dāng)PreparedStatement批量處理正好65536個(gè)記錄時(shí)候,程序會(huì)掛死。我試了一下真的掛死了,太嚇人了,這坑夠深的。

4.   解決方案:

spring jdbctemplate還是很好用的,而且業(yè)務(wù)已經(jīng)被我封裝了,如果使用PreparedStatement意味著多了一個(gè)處理分支,以后維護(hù)會(huì)很麻煩。

我新建一個(gè)MyJdbcTemplate類,繼承 jdbctemplate類,并覆蓋了batchUpdate方法。這下舒服了,系統(tǒng)又恢復(fù)了整潔。      

5.   ★ 結(jié)論和收獲:

ü  有事多思考,多請(qǐng)教身邊同事。

ü  堅(jiān)持Open-close原則(Open for extension, Closed for modification)會(huì)系統(tǒng)更好的擴(kuò)展,非常容易維護(hù),關(guān)鍵是要堅(jiān)持這個(gè)原則,如果我因?yàn)橐粋€(gè)特殊分支使用了PreparedStatement,這樣勢(shì)必破壞了這個(gè)原則,日后的維護(hù)必然會(huì)很麻煩。

ü  基于oracle數(shù)據(jù)如果使用jdbc批量,一定要分批發(fā)送數(shù)據(jù)oracle,否則正好發(fā)一個(gè)65536系統(tǒng)就掛死,大于65536數(shù)據(jù)就丟失,杯具呀......

6.   題目何以為“血案”:

周二打球回家就想這個(gè)問題,打開筆記本調(diào)試,不知不覺搞到很晚,影響媳婦睡覺(媳婦早上5:30上班),被痛罵一頓,趕緊上床睡覺,我媳婦氣的不行,手痛砸了一下床板(我們的床撤掉了床墊,只有床架和木板),床一下子塌了,把媳婦嚇壞了,把我腿弄傷了一塊,唉,“血案”呀。



蜂鳥 2012-01-31 20:17 發(fā)表評(píng)論
]]>
打jar把第三方的jar也打進(jìn)去http://www.aygfsteel.com/alancxx/articles/369033.html蜂鳥蜂鳥Mon, 30 Jan 2012 08:58:00 GMThttp://www.aygfsteel.com/alancxx/articles/369033.htmlhttp://www.aygfsteel.com/alancxx/comments/369033.htmlhttp://www.aygfsteel.com/alancxx/articles/369033.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/369033.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/369033.html     之前在我的blog中寫道,關(guān)于這個(gè)問題,以前是不知道怎么實(shí)現(xiàn)?地址.后來自己在網(wǎng)上查了,有各種不同的說法,感覺都不怎么實(shí)用.
     前幾天在看<<Eclipse從入門到精通>>一書,看到一節(jié)關(guān)于eclipse打包的介紹,感覺有方法了.
     大家都知道打java包,需要一個(gè)清單文件,MANIFEST.MF,內(nèi)容無非就是
Manifest-Version: 1.0
Main
-Class: awt.MyGuiImp
     實(shí)際上,清單文件中還有一個(gè)重要的,就是Class-Path,大家一看就知道這個(gè)是用來干什么的了.不錯(cuò),這個(gè)就是程序運(yùn)行的支持庫的路徑.后來上網(wǎng)查了一下,MANIFEST.MF的具體解釋是這樣:
      打包清單.它是打包的關(guān)鍵性文件,主要是設(shè)置執(zhí)行入口類和支持庫的路徑,在運(yùn)行java應(yīng)用程序時(shí)要根據(jù)此文件中給出的信息來查找入口類和支持庫.
      我們以前只注意了MANIFEST.MF中的入口類,也就是我們常說的主類(有main方法的類),卻忽視了支持庫.
      Class-Path:指定支持庫的路徑,"."指程序運(yùn)行目錄,即到處的jar包所在目錄.程序運(yùn)行時(shí)依據(jù)Class-Path項(xiàng)的設(shè)置路徑來查找支持庫.每一個(gè)支持庫之間用空格格開.
     后來我自己用到的jar,放一個(gè)文件夾lib,lib就放在和jar包一個(gè)文件夾下,清單文件這樣寫
Manifest-Version: 1.0
Main
-Class: awt.MyGuiImp
Class
-Path: ./lib/jacob.jar ./lib/jdom.jar ./lib/log4j.jar
    移到別的計(jì)算機(jī),運(yùn)行jar,就不會(huì)出現(xiàn)任何問題了,前提是該計(jì)算機(jī)必須裝jdk.

蜂鳥 2012-01-30 16:58 發(fā)表評(píng)論
]]>
linux 部署記錄http://www.aygfsteel.com/alancxx/archive/2011/10/26/362096.html蜂鳥蜂鳥Wed, 26 Oct 2011 06:23:00 GMThttp://www.aygfsteel.com/alancxx/archive/2011/10/26/362096.htmlhttp://www.aygfsteel.com/alancxx/comments/362096.htmlhttp://www.aygfsteel.com/alancxx/archive/2011/10/26/362096.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/362096.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/362096.html    1  ll
    2  cd Server/
    3  ll
    4  rpm -Uvh setarch-2*
    5  rpm -Uvh make-3*
    6  rpm -Uvh glibc-2*
    7  rpm -Uvh libaio-0*
    8  rpm -Uvh compat-libstdc++-33-3*
    9  rpm -Uvh compat-gcc-34-3*
   10  rpm -Uvh compat-gcc-34-c++-3*
   11  rpm -Uvh gcc-4*
   12  rpm -Uvh libXp-1*
   13  rpm -Uvh openmotif-2*
   14  rpm -Uvh compat-db-4*
   15  cd /opt
   16  ll
   17  mkdir u01
   18  ll
   19  ln -s /opt/u01/ /u01
   20  cd /
   21  ll
   22  cd u-1
   23  cd u01
   24  ll
   25  mkdir -p /u01/app/oracle/product/10.2.0/db_1
   26  chown -R oracle.oinstall /u01
   27  chown -R oracle.oinstall /opt/u01
   28  cd /etc
   29  ll
   30  vi redhat-release
   31  cd /home/oracle/.bash_profile
   32  vi /home/oracle/.bash_profile
   33  su - oracle
   34  /u01/app/oracle/product/10.2.0/db/root.sh
   35  ifconfig
   36  cd /opt
   37  ll
   38  mkdir u02
   39  ln -s /opt/u02 /u02
   40  cd /
   41  ll
   42  chown -R oracle:oinstall /opt/u02
   43  chown -R oracle:oinstall /u02
   44  su - oracle
   45  fdisk -l
   46  fdisk /dev/sdb
   47  fdisk -l
   48  partprobe
   49  mkfs.ext3 /dev/sdb1
   50  mkfs.ext2 /dev/sdb1
   51  mke2fs /dev/sdb1
   52  mkfs -t ext3 -j /dev/sdb1
   53  mkfs -t ext2 -j /dev/sdb1
   54  fdisk /dev/sdb
   55  fdisk /dev/sdb
   56  fdisk -l
   57  mkfs.ext3 /dev/sdb1
   58  mkdir /opt/newdis
   59  mount /dev/sdb1 /opt/newdis/
   60  vi /etc/fstab
   61  touch test /opt/newdis/
   62  cd /opt/newdis/
   63  ls
   64  ls
   65  touch test
   66  ls
   67  reboot
   68  df -lh
   69  cd /opt/newdis/
   70  ls
   71  su - oracle
   72  rm -rf u02
   73  ll
   74  cd /
   75  ll
   76  rm -rf u02
   77  ll
   78  ln -s /opt/newdis/u02 /u02
   79  ll
   80  chown -R oracle:oinstall /u02
   81  ll
   82  su - oracle
   83  chown -R oracle:oinstall /opt/newdis/
   84  su - oracle
   85  mount 192.168.6.138:/u02/dmp /u02/dmp/
   86  cd /u02/dmp/
   87  ll
   88  ll
   89  ll
   90  lsnrctl status
   91  su - oracle
   92  service syslog status
   93  netstat -tlnp |grep syslog
   94  netstat -an |grep syslog
   95  service syslog status
   96  clean
   97  clear
   98  netstat -an |grep syslog
   99  clear
  100  service syslog status
  101  service iptables status
  102  last
  103  who
  104  service iptables status
  105  service iptables start
  106  service iptables status
  107  cd /root/
  108  mkdir .ssh
  109  cd .ssh/
  110  rz
  111  cp /root/Identity ./id_rsa
  112  ssh-keygen
  113  sftp alan@192.168.50.42
  114  cd /root/.ssh/
  115  ls
  116  ssh-keygen
  117  ls
  118  vi id_rsa.pub
  119  ls
  120  rm -rf *
  121  cp /root/Identity ./id_rsa
  122  ls
  123  ls
  124  sftp alan@192.168.50.40
  125  sftp alan@192.168.50.42
  126  ls
  127  rm -rf known_hosts
  128  ls
  129  sftp root@192.168.50.42
  130  ssh-keygen
  131  sftp root@192.168.50.42
  132  ssh-keygen
  133  sftp root@192.168.50.42
  134  ssh-keygen
  135  sftp root@192.168.50.42
  136  ifconfig
  137  init 0
  138  ntpdate 192.168.191.240
  139  echo "ntpdate 192.168.191.240" >> /etc/rc.local
  140  echo "0 12 * * * ntpdate 192.168.191.240" >> /var/spool/cron/root
  141  at 18:01
  142  last
  143  last | less
  144  shutdown -h now
  145  exit
  146  mv ~/master_key ~/.ssh/authorized_keys
  147  chmod 600 ~/.ssh/authorized_keys
  148  gzip -d hadoop-0.21.0.tar.gz
  149  tar -xf hadoop-0.21.0.tar
  150  java
  151  ll
  152  ll /opt/
  153  ll /usr/
  154  ll
  155  ./jdk-6u5-linux-x64.bin
  156  chmod +w jdk-6u5-linux-x64.bin
  157  ./jdk-6u5-linux-x64.bin
  158  ll
  159  chmod +x jdk-6u5-linux-x64.bin
  160  ./jdk-6u5-linux-x64.bin
  161  ll
  162  rm jdk-6u5-linux-x64.bin
  163  ll
  164  java
  165  sudo gedit /etc/profile
  166  vi /etc/profile
  167  java
  168  export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC Java Home CLASSPATH JRE_HOME
  169  java
  170  vi /etc/profile
  171  export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC Java Home CLASSPATH JRE_HOME
  172  java
  173  export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC Java Home CLASSPATH JRE_HOME JAVA_HOME
  174  ll
  175  vi /etc/profile
  176  java
  177  reboot
  178  echo PATH
  179  export
  180  echo $PATH
  181  mv ~/master_key ~/.ssh/authorized_keys
  182  chmod 600 ~/.ssh/authorized_keys
  183  vi /etc/profile
  184  vi /etc/bashrc
  185  jps
  186  less /root/hadoop-0.21.0/bin/../logs/hadoop-root-namenode-tibcotest.alan.com.out
  187  ll hadoop-0.21.0/logs/hadoop-root-datanode-localhost.localdomain.log
  188  less hadoop-0.21.0/logs/hadoop-root-datanode-localhost.localdomain.log
  189  rm -rf hadoop-0.21.0/logs/*
  190  ll
  191  cd hadoop-0.21.0/logs
  192  ll
  193  less hadoop-root-datanode-localhost.localdomain.log
  194  less hadoop-root-tasktracker-localhost.localdomain.log
  195  jps
  196  less hadoop-root-tasktracker-localhost.localdomain.log
  197  cd ..
  198  vi conf/mapred-site.xml
  199  vi conf/mapred-site.xml
  200  jps
  201  less hadoop-root-tasktracker-localhost.localdomain.log
  202  cd logs
  203  less hadoop-root-tasktracker-localhost.localdomain.log
  204  cd ..
  205  vi conf/core-site.xml
  206  jps
  207  vi conf/mapred-site.xml
  208  jps
  209  jps
  210  ll /tmp/hadoop-root/dfs/data/current/finalized/
  211  vi ll /tmp/hadoop-root/dfs/data/current/finalized/blk_-6267353868788565174
  212  vi ll /tmp/hadoop-root/dfs/data/current/finalized/blk_-6267353868788565174_1102.meta
  213  less /tmp/hadoop-root/dfs/data/current/finalized/blk_-6267353868788565174_1102.meta
  214  less /tmp/hadoop-root/dfs/data/current/finalized/blk_-6267353868788565174
  215  cd hadoop-0.21.0
  216  ll
  217  vi conf/hdfs-site.xml
  218  cd /opt
  219  mkdir hadoop
  220  mkdir hadoop/data1
  221  mkdir hadoop/data2
  222  ll hadoop/data1/
  223  ll hadoop/data1/
  224  cd /root/hadoop-0.21.0/conf/
  225  ll
  226  vi hdfs-site.xml
  227  tail -fn500 /root/hadoop-0.21.0/bin/../logs/hadoop-root-tasktracker-localhost.localdomain.out
  228  cd ../logs
  229  ll
  230  tail -fn500 hadoop-root-datanode-localhost.localdomain.log
  231  jps
  232  vi ../conf/hdfs-site.xml
  233  tail -fn500 hadoop-root-datanode-localhost.localdomain.log
  234  vi ../conf/hdfs-site.xml
  235  tail -fn500 hadoop-root-datanode-localhost.localdomain.log
  236  ll /opt/hadoop/data2
  237  ll /opt/hadoop/data1
  238  rm rm -rf /opt/hadoop/data1/*
  239  rm rm -rf /opt/hadoop/data2/*
  240  tail -fn500 hadoop-root-datanode-localhost.localdomain.log
  241  vi ../conf/hdfs-site.xml
  242  mkdir /opt/hadoop/data3
  243  cd /root/hadoop-0.21.0
  244  cd bin
  245  ll
  246  less start-dfs.sh
  247  cd hadoop-0.21.0/conf
  248  vi excludes
  249  vi hdfs-site.xml
  250  vi excludes
  251  rm -rf /opt/hadoop/data/*
  252  jps
  253  cd hadoop-0.21.0/bin/
  254  ll
  255  ./hadoop-daemon.sh start datanode
  256  ./hadoop
  257  sh start-dfs.sh
  258  vi start-dfs.sh
  259  vi stop-dfs.sh
  260  ll
  261  vi hadoop-daemon.sh
  262  ll
  263  sh hadoop-daemon.sh start datanode
  264  jps
  265  sh hadoop-daemon.sh start datanode
  266  jps
  267  sh hadoop-daemon.sh stop datanode
  268  rm rm -rf /opt/hadoop/data1/*
  269  rm -rf /opt/hadoop/data2/*
  270  ll /opt/hadoop/
  271  ll /opt/hadoop/data3
  272  rm -rf /opt/hadoop/data3/*
  273  chown -fR hadoop /opt/hadoop
  274  su hadoop
  275  ll /opt
  276  vi /etc/bashrc
  277  vi /etc/profile
  278  vi /etc/bashrc
  279  ll
  280  cd /root
  281  ll
  282  cp -rf jdk1.6.0_05 /opt/
  283  cd /opt/
  284  ll
  285  vi /etc/profile
  286  su hadoop
  287  vi /etc/bashrc
  288  exit
  289  gzip -d hadoop-0.20.203.0rc1.tar.gz
  290  tar -xvf hadoop-0.20.203.0rc1.tar
  291  cd hadoop-0.20.203.0
  292  \cp -a ../hadoop-0.21.0/conf/core-site.xml conf/core-site.xml
  293  \cp -a ../hadoop-0.21.0/conf/hdfs-site.xml conf/hdfs-site.xml
  294  \cp -a ../hadoop-0.21.0/conf/mapred-site.xml conf/mapred-site.xml
  295  \cp -a ../hadoop-0.21.0/conf/masters conf/masters
  296  \cp -a ../hadoop-0.21.0/conf/slaves conf/slaves
  297  jps
  298  kill -9 3588
  299  cd ..
  300  cp -rf hadoop-0.20.203.0 /opt/hadoop
  301  useradd hadoop
  302  passwd hadoop
  303  mkdir ~/.ssh
  304  chmod 700 ~/.ssh
  305  mv ~/authorized_keys ~/.ssh/
  306  chmod 600 ~/.ssh/authorized_keys
  307  su hadoop
  308  java
  309  su hadoop
  310  less /etc/profile
  311  jps
  312  su hadoop
  313  cp zookeeper-3.3.3.tar.gz /opt/hadoop/
  314  su hadoop
  315  vi /etc/profile
  316  cd
  317  cp hbase-0.90.3.tar.gz /opt/hadoop/
  318  su hadoop
  319  \cp -a hbase-site.xml hdfs-site.xml hbase-env.sh regionservers /opt/hadoop/hbase/conf/
  320  chown -fR hadoop /opt/hadoop/
  321  df
  322  cd /opt
  323  ll
  324  rm -rf full.dmp
  325  jps
  326  ps -ef |grep 13026
  327  ps -ef |grep 13026
  328  cp /opt/hadoop/zookeeper-3.3.3/conf/zoo.cfg /opt/jdk1.6.0_05/lib
  329  zookeeper-3.3.3/bin/zkServer.sh stop
  330  su hadoop
  331  su hadoop
  332  cp hbase-*.xml /opt/hadoop/hbase/conf/
  333  rm -rf /opt/hadoop/hbase/conf/hbase-default.xml
  334  cp hbase-*.xml /opt/hadoop/hbase/conf/
  335  vi /etc/hosts
  336  less /etc/bashrc
  337  su hadoop
  338  su hadoop
  339  vi /etc/hosts
  340  vi /etc/hosts
  341  jps
  342  vi /etc/hosts
  343  vi etc/hosts
  344  vi /etc/hosts
  345  vi /opt/hadoop/hbase/conf/hbase-site.xml
  346  jps
  347  kill -9 23754
  348  vi /etc/hosts
  349  jps
  350  kill -9 23987
  351  jps
  352  kill -9 24355
  353  jps
  354  jps
  355  kill -9 24682 24585
  356  jps
  357  kill -9 24887 24984
  358  jps
  359  kill -9 HQuorumPeer HRegionServer
  360  kill -9 25286 25185
  361  vi /opt/hadoop/hbase/conf/hbase-site.xml
  362  jps
  363  kill -9 25582 25485
  364  su hadoop
  365  vi /etc/sysctl.conf
  366  reboot
  367  cat /proc/sys/net/ipv6/conf/all/disable_ipv6
  368  jps
  369  vi /etc/bashrc
  370  vi /etc/hosts
  371  jps
  372  kill -9 5014 5111
  373  su hadoop
  374  less /opt/hadoop/hadoop-0.20.203.0/conf/hdfs-site.xml
  375  less /opt/hadoop/hadoop-0.20.203.0/conf/core-site.xml
  376  jps
  377  kill -9 12414 12317
  378  vi /opt/hadoop/hadoop-0.20.203.0/conf/core-site.xml
  379  jps
  380  kill -9 19312
  381  vi /etc/profile
  382  jps
  383  kill -9 19563 19472
  384  su hadoop
  385  vi /etc/profile
  386  su hadoop
  387  jps
  388  su hadoop
  389  ll
  390  su hadoop
  391  jps
  392  vi /etc/profile
  393  vi /etc/profile
  394  exit
  395  jps
  396  kill -9 17930
  397  jps
  398  jps
  399  kill -9 20659
  400  jps
  401  jps
  402  kill -9 29834 29935
  403  su hadoop
  404  su hadoop
  405  su hadoop
  406  which java
  407  mkdir /opt/oracle
  408  mv apache-tomcat-6.0.30_V1.4.zip /opt/oracle/
  409  cd /opt/oracle/
  410  ll
  411  unzip apache-tomcat-6.0.30_V1.4.zip
  412  ll
  413  cd tomcatTemplate/
  414  ll
  415  cd bin
  416  ll
  417  chmod +x *.sh
  418  ./createInstance.sh
  419  ./createInstance.sh -h
  420  ll ../..
  421  cd ../../tomcat
  422  ll
  423  cd ..
  424  rm -rf tomcat
  425  cd tomcatTemplate/bin
  426  cd ../../
  427  cp tomcatTemplate/ tomact-sso
  428  cp -rf tomcatTemplate/ tomact-sso
  429  ll
  430  mv tomact-sso tomcat-sso
  431  ll
  432  cd tomcat-sso
  433  cd bin
  434  ll
  435  cd ..
  436  cd ..
  437  rm -rf tomcat-sso
  438  ll
  439  cd tomcatTemplate/bin
  440  sh createInstance.sh tomcatServer47-0
  441  cd ../..
  442  ll
  443  cd tomcat
  444  ll
  445  cd tomcatServer47-0/
  446  ll
  447  less conf/catalina.properties
  448  cd ..
  449  cd bin
  450  ll
  451  cd tomcatServer47-0/
  452  ll
  453  cd bin
  454  ll
  455  vi resource.properties
  456  ./createResource.sh
  457  cd
  458  mv if-sso-token-server.war /opt/oracle/tomcat/tomcatServer47-0/webapps/
  459  cd  /opt/oracle/tomcat/tomcatServer47-0/bin
  460  ./catalina.sh start
  461  tail -fn100 ../logs/catalina.out
  462  tail -fn100 ../logs/localhost.2011-09-07.log
  463  ./catalina.sh stop
  464  ./catalina.sh start
  465  ./catalina.sh stop
  466  ./catalina.sh start
  467  ./catalina.sh stop
  468  ./catalina.sh start
  469  mv if-sso-token-server.war /opt/oracle/tomcat/tomcatServer47-0/webapps/
  470  rm -rf /opt/oracle/tomcat/tomcatServer47-0/webapps/if-sso-token-server
  471  less /nfs/envconfig/pmd/jms.properties
  472  ll
  473  mkdir /nfs
  474  ll
  475  cd /nfs
  476  ll
  477  mkdir envconfig/pmd
  478  mkdir envconfig
  479  mkdir envconfig/pmd
  480  vi /nfs/envconfig/pmd/jms.properties
  481  vi /nfs/envconfig/pmd/jms.properties
  482  vi /nfs/envconfig/pmd/orm.properties
  483  tail -fn100 /opt/oracle/tomcat/tomcatServer47-0/logs/localhost.2011-09-07.log
  484  tail -fn100 /opt/log/sso.token.server.log
  485  ps -ef|grep tomcat
  486  ps -ef|grep tomcat
  487  cd /opt/oracle/tomcat/tomcatServer47-0/
  488  ll
  489  ll webapps/
  490  cd /opt/oracle/
  491  ls
  492  cd tomcat
  493  ls
  494  cd tomcatServer47-0/
  495  ls
  496  cd conf
  497  ls
  498  less context.xml
  499  cat /etc/redhat-release
  500  exit
  501  ls
  502  cd opt
  503  ls
  504  cd /opt/oracle/
  505  ls
  506  cd tomcat
  507  ls
  508  cd tomcatServer47-0/
  509  ls
  510  cd webapps/
  511  ls
  512  cd ..
  513  ls
  514  cd conf
  515  ls
  516  less context.xml
  517  cd ..
  518  ls
  519  cd /opt
  520  ls
  521  pwd
  522  cd /opt
  523  ls
  524  cd oracle/bea/
  525  cd oracle/
  526  ls
  527  cd ..
  528  cd bea
  529  cd /opt
  530  ls
  531  cd  oracle/
  532  ls
  533  cd tomcat
  534  ls
  535  cd tomcatServer47-0/
  536  ls
  537  cd webapps/
  538  ls
  539  cd ..
  540  ls
  541  cd conf
  542  ls
  543  less context.xml
  544  cd /opt/
  545  ls
  546  cd oracle/
  547  ls
  548  cd tomcat/tomcatServer47-0/
  549  cd webapps/
  550  ls
  551  ls ..
  552  history
  553  cd /opt/oracle/
  554  ls
  555  cd tomcat
  556  ls
  557  cd ..
  558  ls
  559  cd tomcatTemplate/
  560  ls
  561  cd bin
  562  ls
  563  sh createInstance.sh tomcatServer47-1
  564  cd ../../
  565  ls
  566  cd tomcat
  567  ls
  568  ll
  569  cd ..
  570  ls
  571  ll
  572  history



蜂鳥 2011-10-26 14:23 發(fā)表評(píng)論
]]>
Oracle 與 Mysql 常用命令對(duì)比http://www.aygfsteel.com/alancxx/articles/350284.html蜂鳥蜂鳥Sun, 15 May 2011 11:05:00 GMThttp://www.aygfsteel.com/alancxx/articles/350284.htmlhttp://www.aygfsteel.com/alancxx/comments/350284.htmlhttp://www.aygfsteel.com/alancxx/articles/350284.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/350284.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/350284.html
Oracle mysql
對(duì)比版本 Enterprise Oracle10g Release 10.2.0.1.0 mysql 4.1.21-nt
默認(rèn)安裝目錄 ..\oracle\product\10.2.0 ..\MySQL\MySQL Server 4.1
各種實(shí)用程序所在目錄 ..\oracle\product\10.2.0\db_1\BIN ..\MySQL\MySQL Server 4.1\bin
客戶程序 SQL*Plus mysql
安裝后系統(tǒng)默認(rèn)用戶(庫) sys
system
scott
mysql
test
顯示所有用戶(庫) SQL >select * from all_users; mysql> show databases;
退出命令 SQL> exit
SQL> quit
mysql> exit
mysql> quit
改變連接用戶(庫) SQL> conn 用戶名/密碼@主機(jī)字符串 mysql> use 庫名
查詢當(dāng)前所有的表 SQL> select * from tab;
SQL> select * from cat;
mysql> show tables;
F:MySQLbin>mysqlshow 庫名
顯示當(dāng)前連接用戶(庫) SQL> show user mysql> connect
查看幫助 SQL> ? mysql> help
顯示表結(jié)構(gòu) SQL> desc 表名
SQL> describe 表名
mysql> desc 表名;
mysql> describe 表名;
mysql> show columns from 表名;
F:MySQLbin>mysqlshow 庫名 表名
日期函數(shù) SQL> select sysdate from dual; mysql> select now();
mysql> select sysdate();
mysql> select curdate();
mysql> select current_date;
mysql> select curtime();
mysql> select current_time;
日期格式化 SQL> select to_char(sysdate,'yyyy-mm-dd') from dual;
SQL> select to_char(sysdate,'hh24-mi-ss') from dual;
mysql> select date_format(now(),'%Y-%m-%d');
mysql> select time_format(now(),'%H-%i-%S');
日期函數(shù)
(增加一個(gè)月)
SQL> select to_char(add_months(to_date('20000101','yyyymmdd'),1),'yyyy-mm-dd') from dual;
結(jié)果:2000-02-01
SQL> select to_char(add_months(to_date('20000101','yyyymmdd'),5),'yyyy-mm-dd') from dual;
結(jié)果:2000-06-01
mysql> select date_add('2000-01-01',interval 1 month);
結(jié)果:2000-02-01
mysql> select date_add('2000-01-01',interval 5 month);
結(jié)果:2000-06-01
別名 SQL> select 1 a from dual; mysql> select 1 as a;
字符串截取函數(shù) SQL> select substr('abcdefg',1,5) from dual;
SQL> select substrb('abcdefg',1,5) from dual;
結(jié)果:abcde
mysql> select substring('abcdefg',2,3);
結(jié)果:bcd
mysql> select mid('abcdefg',2,3);
結(jié)果:bcd
mysql> select substring('abcdefg',2);
結(jié)果:bcdefg
mysql> select substring('abcdefg' from 2);
結(jié)果:bcdefg
另有SUBSTRING_INDEX(str,delim,count)函數(shù)
返回從字符串str的第count個(gè)出現(xiàn)的分隔符delim之后的子串。
如果count是正數(shù),返回最后的分隔符到左邊(從左邊數(shù)) 的所有字符。
如果count是負(fù)數(shù),返回最后的分隔符到右邊的所有字符(從右邊數(shù))。
執(zhí)行外部腳本命令 SQL >@f:\sql\a.sql 1:mysql> source f:/sql/a.sql
2:F:MySQLbin>mysql 3:F:MySQLbin>mysql 庫名
改表名 SQL> rename a to b; mysql> alter table a rename b;
執(zhí)行命令 ;<回車>
/
r
run
;<回車>
go
ego
distinct用法 SQL> select distinct 列1 from 表1;
SQL> select distinct 列1,列2 from 表1;
mysql> select distinct 列1 from 表1;
mysql> select distinct 列1,列2 from 表1;
注釋 --
/*與*/
#
--
/*與*/
限制返回記錄條數(shù) SQL> select * from 表名 where rownum<5; mysql> select * from 表名 limit 5;
新建用戶(庫) SQL> create user 用戶名 identified by 密碼; mysql> create database 庫名;
刪用戶(庫) SQL> drop user 用戶名; mysql> drop database 庫名;
外連接 使用(+) 使用left join
查詢索引 SQL> select index_name,table_name from user_indexes; mysql> show index from 表名 [FROM 庫名];
通配符 “%” “%”和“_”
SQL語法 SELECT selection_list 選擇哪些列
FROM table_list 從何處選擇行
WHERE primary_constraint 行必須滿足什么條件
GROUP BY grouping_columns 怎樣對(duì)結(jié)果分組
HAVING secondary_constraint 行必須滿足的第二條件
ORDER BY sorting_columns 怎樣對(duì)結(jié)果排序
SELECT selection_list 選擇哪些列
FROM table_list 從何處選擇行
WHERE primary_constraint 行必須滿足什么條件
GROUP BY grouping_columns 怎樣對(duì)結(jié)果分組
HAVING secondary_constraint 行必須滿足的第二條件
ORDER BY sorting_columns 怎樣對(duì)結(jié)果排序



蜂鳥 2011-05-15 19:05 發(fā)表評(píng)論
]]>
Hadoop介紹http://www.aygfsteel.com/alancxx/articles/350080.html蜂鳥蜂鳥Thu, 12 May 2011 03:14:00 GMThttp://www.aygfsteel.com/alancxx/articles/350080.htmlhttp://www.aygfsteel.com/alancxx/comments/350080.htmlhttp://www.aygfsteel.com/alancxx/articles/350080.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/350080.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/350080.html這里先大致介紹一下Hadoop.
    本文大部分內(nèi)容都是從官網(wǎng)
Hadoop上來的。其中有一篇介紹HDFS的pdf文檔,里面對(duì)Hadoop介紹的比較全面了。我的這一個(gè)系列的Hadoop學(xué)習(xí)筆記也是從這里一步一步進(jìn)行下來的,同時(shí)又參考了網(wǎng)上的很多文章,對(duì)學(xué)習(xí)Hadoop中遇到的問題進(jìn)行了歸納總結(jié)。
    言歸正傳,先說一下Hadoop的來龍去脈。談到Hadoop就不得不提到
LuceneNutch。首先,Lucene并不是一個(gè)應(yīng)用程序,而是提供了一個(gè)純Java的高性能全文索引引擎工具包,它可以方便的嵌入到各種實(shí)際應(yīng)用中實(shí)現(xiàn)全文搜索/索引功能。Nutch是一個(gè)應(yīng)用程序,是一個(gè)以Lucene為基礎(chǔ)實(shí)現(xiàn)的搜索引擎應(yīng)用,Lucene 為Nutch提供了文本搜索和索引的API,Nutch不光有搜索的功能,還有數(shù)據(jù)抓取的功能。在nutch0.8.0版本之前,Hadoop還屬于 Nutch的一部分,而從nutch0.8.0開始,將其中實(shí)現(xiàn)的NDFS和MapReduce剝離出來成立一個(gè)新的開源項(xiàng)目,這就是Hadoop,而 nutch0.8.0版本較之以前的Nutch在架構(gòu)上有了根本性的變化,那就是完全構(gòu)建在Hadoop的基礎(chǔ)之上了。在Hadoop中實(shí)現(xiàn)了 Google的GFS和MapReduce算法,使Hadoop成為了一個(gè)分布式的計(jì)算平臺(tái)。
   其實(shí),Hadoop并不僅僅是一個(gè)用于存儲(chǔ)的分布式文件系統(tǒng),而是設(shè)計(jì)用來在由通用計(jì)算設(shè)備組成的大型集群上執(zhí)行分布式應(yīng)用的框架。

   Hadoop包含兩個(gè)部分:

   1、HDFS

      即Hadoop Distributed File System (Hadoop分布式文件系統(tǒng))
      HDFS 具有高容錯(cuò)性,并且可以被部署在低價(jià)的硬件設(shè)備之上。HDFS很適合那些有大數(shù)據(jù)集的應(yīng)用,并且提供了對(duì)數(shù)據(jù)讀寫的高吞吐率。HDFS是一個(gè) master/slave的結(jié)構(gòu),就通常的部署來說,在master上只運(yùn)行一個(gè)Namenode,而在每一個(gè)slave上運(yùn)行一個(gè)Datanode。
      HDFS 支持傳統(tǒng)的層次文件組織結(jié)構(gòu),同現(xiàn)有的一些文件系統(tǒng)在操作上很類似,比如你可以創(chuàng)建和刪除一個(gè)文件,把一個(gè)文件從一個(gè)目錄移到另一個(gè)目錄,重命名等等操 作。Namenode管理著整個(gè)分布式文件系統(tǒng),對(duì)文件系統(tǒng)的操作(如建立、刪除文件和文件夾)都是通過Namenode來控制。 
     下面是HDFS的結(jié)構(gòu):


      從上面的圖中可以看 出,Namenode,Datanode,Client之間的通信都是建立在TCP/IP的基礎(chǔ)之上的。當(dāng)Client要執(zhí)行一個(gè)寫入的操作的時(shí)候,命令 不是馬上就發(fā)送到Namenode,Client首先在本機(jī)上臨時(shí)文件夾中緩存這些數(shù)據(jù),當(dāng)臨時(shí)文件夾中的數(shù)據(jù)塊達(dá)到了設(shè)定的Block的值(默認(rèn)是 64M)時(shí),Client便會(huì)通知Namenode,Namenode便響應(yīng)Client的RPC請(qǐng)求,將文件名插入文件系統(tǒng)層次中并且在 Datanode中找到一塊存放該數(shù)據(jù)的block,同時(shí)將該Datanode及對(duì)應(yīng)的數(shù)據(jù)塊信息告訴Client,Client便這些本地臨時(shí)文件夾中 的數(shù)據(jù)塊寫入指定的數(shù)據(jù)節(jié)點(diǎn)。
      HDFS采取了副本策略,其目的是為了提高系統(tǒng)的可靠性,可用性。HDFS的副本放置策略是三個(gè)副本, 一個(gè)放在本節(jié)點(diǎn)上,一個(gè)放在同一機(jī)架中的另一個(gè)節(jié)點(diǎn)上,還有一個(gè)副本放在另一個(gè)不同的機(jī)架中的一個(gè)節(jié)點(diǎn)上。當(dāng)前版本的hadoop0.12.0中還沒有實(shí) 現(xiàn),但是正在進(jìn)行中,相信不久就可以出來了。

   2、MapReduce的實(shí)現(xiàn)

      
MapReduce是Google 的一項(xiàng)重要技術(shù),它是一個(gè)編程模型,用以進(jìn)行大數(shù)據(jù)量的計(jì)算。對(duì)于大數(shù)據(jù)量的計(jì)算,通常采用的處理手法就是并行計(jì)算。至少現(xiàn)階段而言,對(duì)許多開發(fā)人員來 說,并行計(jì)算還是一個(gè)比較遙遠(yuǎn)的東西。MapReduce就是一種簡(jiǎn)化并行計(jì)算的編程模型,它讓那些沒有多少并行計(jì)算經(jīng)驗(yàn)的開發(fā)人員也可以開發(fā)并行應(yīng)用。
      MapReduce的名字源于這個(gè)模型中的兩項(xiàng)核心操作:Map和 Reduce。也許熟悉Functional Programming(
函數(shù)式編程) 的人見到這兩個(gè)詞會(huì)倍感親切。簡(jiǎn)單的說來,Map是把一組數(shù)據(jù)一對(duì)一的映射為另外的一組數(shù)據(jù),其映射的規(guī)則由一個(gè)函數(shù)來指定,比如對(duì)[1, 2, 3, 4]進(jìn)行乘2的映射就變成了[2, 4, 6, 8]。Reduce是對(duì)一組數(shù)據(jù)進(jìn)行歸約,這個(gè)歸約的規(guī)則由一個(gè)函數(shù)指定,比如對(duì)[1, 2, 3, 4]進(jìn)行求和的歸約得到結(jié)果是10,而對(duì)它進(jìn)行求積的歸約結(jié)果是24。
      關(guān)于MapReduce的內(nèi)容,建議看看孟巖的這篇
MapReduce:The Free Lunch Is Not Over!

   好了,作為這個(gè)系列的第一篇就寫這么多了,我也是剛開始接觸Hadoop,下一篇就是講Hadoop的部署,談?wù)勎以诓渴餒adoop時(shí)遇到的問題,也給大家一個(gè)參考,少走點(diǎn)彎路。


蜂鳥 2011-05-12 11:14 發(fā)表評(píng)論
]]>
Spring中的ServletContext使用http://www.aygfsteel.com/alancxx/articles/349896.html蜂鳥蜂鳥Tue, 10 May 2011 02:02:00 GMThttp://www.aygfsteel.com/alancxx/articles/349896.htmlhttp://www.aygfsteel.com/alancxx/comments/349896.htmlhttp://www.aygfsteel.com/alancxx/articles/349896.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/349896.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/349896.html

Spring 不但提供了一個(gè)功能全面的應(yīng)用開發(fā)框架,本身還擁有眾多可以在程序編寫時(shí)直接使用的工具類,您不但可以在 Spring 應(yīng)用中使用這些工具類,也可以在其它的應(yīng)用中使用,這些工具類中的大部分是可以在脫離 Spring 框架時(shí)使用的。了解 Spring 中有哪些好用的工具類并在程序編寫時(shí)適當(dāng)使用,將有助于提高開發(fā)效率、增強(qiáng)代碼質(zhì)量。

在這個(gè)分為兩部分的文章中,我們將從眾多的 Spring 工具類中遴選出那些好用的工具類介紹給大家。第 1 部分將介紹與文件資源操作和 Web 相關(guān)的工具類。在 第 2 部分 中將介紹特殊字符轉(zhuǎn)義和方法入?yún)z測(cè)工具類。

文件資源操作

文件資源的操作是應(yīng)用程序中常見的功能,如當(dāng)上傳一個(gè)文件后將其保存在特定目錄下,從指定地址加載一個(gè)配置文件等等。我們一般使用 JDK 的 I/O 處理類完成這些操作,但對(duì)于一般的應(yīng)用程序來說,JDK 的這些操作類所提供的方法過于底層,直接使用它們進(jìn)行文件操作不但程序編寫復(fù)雜而且容易產(chǎn)生錯(cuò)誤。相比于 JDK 的 File,Spring 的 Resource 接口(資源概念的描述接口)抽象層面更高且涵蓋面更廣,Spring 提供了許多方便易用的資源操作工具類,它們大大降低資源操作的復(fù)雜度,同時(shí)具有更強(qiáng)的普適性。這些工具類不依賴于 Spring 容器,這意味著您可以在程序中象一般普通類一樣使用它們。

加載文件資源

Spring 定義了一個(gè) org.springframework.core.io.Resource 接口,Resource 接口是為了統(tǒng)一各種類型不同的資源而定義的,Spring 提供了若干 Resource 接口的實(shí)現(xiàn)類,這些實(shí)現(xiàn)類可以輕松地加載不同類型的底層資源,并提供了獲取文件名、URL 地址以及資源內(nèi)容的操作方法。

訪問文件資源

假設(shè)有一個(gè)文件地位于 Web 應(yīng)用的類路徑下,您可以通過以下方式對(duì)這個(gè)文件資源進(jìn)行訪問:

通過 FileSystemResource 以文件系統(tǒng)絕對(duì)路徑的方式進(jìn)行訪問; 
通過 ClassPathResource 以類路徑的方式進(jìn)行訪問; 
通過 ServletContextResource 以相對(duì)于Web應(yīng)用根目錄的方式進(jìn)行訪問。 
相比于通過 JDK 的 File 類訪問文件資源的方式,Spring 的 Resource 實(shí)現(xiàn)類無疑提供了更加靈活的操作方式,您可以根據(jù)情況選擇適合的 Resource 實(shí)現(xiàn)類訪問資源。下面,我們分別通過 FileSystemResource 和 ClassPathResource 訪問同一個(gè)文件資源:


清單 1. FileSourceExample
package com.baobaotao.io;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class FileSourceExample {
    public static void main(String[] args) {
        try {
            String filePath = 
            "D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt";
            // ① 使用系統(tǒng)文件路徑方式加載文件
            Resource res1 = new FileSystemResource(filePath); 
            // ② 使用類路徑方式加載文件
            Resource res2 = new ClassPathResource("conf/file1.txt");
            InputStream ins1 = res1.getInputStream();
            InputStream ins2 = res2.getInputStream();
            System.out.println("res1:"+res1.getFilename());
            System.out.println("res2:"+res2.getFilename());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


在獲取資源后,您就可以通過 Resource 接口定義的多個(gè)方法訪問文件的數(shù)據(jù)和其它的信息:如您可以通過 getFileName() 獲取文件名,通過 getFile() 獲取資源對(duì)應(yīng)的 File 對(duì)象,通過 getInputStream() 直接獲取文件的輸入流。此外,您還可以通過 createRelative(String relativePath) 在資源相對(duì)地址上創(chuàng)建新的資源。

在 Web 應(yīng)用中,您還可以通過 ServletContextResource 以相對(duì)于 Web 應(yīng)用根目錄的方式訪問文件資源,如下所示:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<jsp:directive.page import="
    org.springframework.web.context.support.ServletContextResource"/>
<jsp:directive.page import="org.springframework.core.io.Resource"/>
<%
    // ① 注意文件資源地址以相對(duì)于 Web 應(yīng)用根路徑的方式表示
    Resource res3 = new ServletContextResource(application, 
        "/WEB-INF/classes/conf/file1.txt");
    out.print(res3.getFilename());
%>


對(duì)于位于遠(yuǎn)程服務(wù)器(Web 服務(wù)器或 FTP 服務(wù)器)的文件資源,您則可以方便地通過 UrlResource 進(jìn)行訪問。

為了方便訪問不同類型的資源,您必須使用相應(yīng)的 Resource 實(shí)現(xiàn)類,是否可以在不顯式使用 Resource 實(shí)現(xiàn)類的情況下,僅根據(jù)帶特殊前綴的資源地址直接加載文件資源呢?Spring 提供了一個(gè) ResourceUtils 工具類,它支持“classpath:”和“file:”的地址前綴,它能夠從指定的地址加載文件資源,請(qǐng)看下面的例子:


清單 2. ResourceUtilsExample
package com.baobaotao.io;
import java.io.File;
import org.springframework.util.ResourceUtils;
public class ResourceUtilsExample {
    public static void main(String[] args) throws Throwable{
        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");
        System.out.println(clsFile.isFile());

        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt";
        File httpFile = ResourceUtils.getFile(httpFilePath);
        System.out.println(httpFile.isFile());        
    }
}


ResourceUtils 的 getFile(String resourceLocation) 方法支持帶特殊前綴的資源地址,這樣,我們就可以在不和 Resource 實(shí)現(xiàn)類打交道的情況下使用 Spring 文件資源加載的功能了。

本地化文件資源

本地化文件資源是一組通過本地化標(biāo)識(shí)名進(jìn)行特殊命名的文件,Spring 提供的 LocalizedResourceHelper 允許通過文件資源基名和本地化實(shí)體獲取匹配的本地化文件資源并以 Resource 對(duì)象返回。假設(shè)在類路徑的 i18n 目錄下,擁有一組基名為 message 的本地化文件資源,我們通過以下實(shí)例演示獲取對(duì)應(yīng)中國(guó)大陸和美國(guó)的本地化文件資源:


清單 3. LocaleResourceTest
package com.baobaotao.io;
import java.util.Locale;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.LocalizedResourceHelper;
public class LocaleResourceTest {
    public static void main(String[] args) {
        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper();
        // ① 獲取對(duì)應(yīng)美國(guó)的本地化文件資源
        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.US);
        // ② 獲取對(duì)應(yīng)中國(guó)大陸的本地化文件資源
        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.CHINA);
        System.out.println("fileName(us):"+msg_us.getFilename()); 
        System.out.println("fileName(cn):"+msg_cn.getFilename());
    }
}


雖然 JDK 的 java.util.ResourceBundle 類也可以通過相似的方式獲取本地化文件資源,但是其返回的是 ResourceBundle 類型的對(duì)象。如果您決定統(tǒng)一使用 Spring 的 Resource 接表征文件資源,那么 LocalizedResourceHelper 就是獲取文件資源的非常適合的幫助類了。

文件操作

在使用各種 Resource 接口的實(shí)現(xiàn)類加載文件資源后,經(jīng)常需要對(duì)文件資源進(jìn)行讀取、拷貝、轉(zhuǎn)存等不同類型的操作。您可以通過 Resource 接口所提供了方法完成這些功能,不過在大多數(shù)情況下,通過 Spring 為 Resource 所配備的工具類完成文件資源的操作將更加方便。

文件內(nèi)容拷貝

第一個(gè)我們要認(rèn)識(shí)的是 FileCopyUtils,它提供了許多一步式的靜態(tài)操作方法,能夠?qū)⑽募?nèi)容拷貝到一個(gè)目標(biāo) byte[]、String 甚至一個(gè)輸出流或輸出文件中。下面的實(shí)例展示了 FileCopyUtils 具體使用方法:


清單 4. FileCopyUtilsExample
package com.baobaotao.io;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.OutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
public class FileCopyUtilsExample {
    public static void main(String[] args) throws Throwable {
        Resource res = new ClassPathResource("conf/file1.txt");
        // ① 將文件內(nèi)容拷貝到一個(gè) byte[] 中
        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile());
        // ② 將文件內(nèi)容拷貝到一個(gè) String 中
        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile()));
        // ③ 將文件內(nèi)容拷貝到另一個(gè)目標(biāo)文件
        FileCopyUtils.copy(res.getFile(), 
        new File(res.getFile().getParent()+ "/file2.txt"));

        // ④ 將文件內(nèi)容拷貝到一個(gè)輸出流中
        OutputStream os = new ByteArrayOutputStream();
        FileCopyUtils.copy(res.getInputStream(), os);
    }
}


往往我們都通過直接操作 InputStream 讀取文件的內(nèi)容,但是流操作的代碼是比較底層的,代碼的面向?qū)ο笮圆⒉粡?qiáng)。通過 FileCopyUtils 讀取和拷貝文件內(nèi)容易于操作且相當(dāng)直觀。如在 ① 處,我們通過 FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接將文件內(nèi)容讀到一個(gè) byte[] 中;另一個(gè)可用的方法是 copyToByteArray(InputStream in),它將輸入流讀取到一個(gè) byte[] 中。

如果是文本文件,您可能希望將文件內(nèi)容讀取到 String 中,此時(shí)您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 對(duì) File 進(jìn)行封裝,或使用 InputStreamReader 對(duì) InputStream 進(jìn)行封裝就可以了。

FileCopyUtils 還提供了多個(gè)將文件內(nèi)容拷貝到各種目標(biāo)對(duì)象中的方法,這些方法包括:

方法 說明 
static void copy(byte[] in, File out) 將 byte[] 拷貝到一個(gè)文件中 
static void copy(byte[] in, OutputStream out) 將 byte[] 拷貝到一個(gè)輸出流中 
static int copy(File in, File out) 將文件拷貝到另一個(gè)文件中 
static int copy(InputStream in, OutputStream out) 將輸入流拷貝到輸出流中 
static int copy(Reader in, Writer out) 將 Reader 讀取的內(nèi)容拷貝到 Writer 指向目標(biāo)輸出中 
static void copy(String in, Writer out) 將字符串拷貝到一個(gè) Writer 指向的目標(biāo)中

在實(shí)例中,我們雖然使用 Resource 加載文件資源,但 FileCopyUtils 本身和 Resource 沒有任何關(guān)系,您完全可以在基于 JDK I/O API 的程序中使用這個(gè)工具類。

屬性文件操作

我們知道可以通過 java.util.Properties的load(InputStream inStream) 方法從一個(gè)輸入流中加載屬性資源。Spring 提供的 PropertiesLoaderUtils 允許您直接通過基于類路徑的文件地址加載屬性資源,請(qǐng)看下面的例子:

package com.baobaotao.io;
import java.util.Properties;
import org.springframework.core.io.support.PropertiesLoaderUtils;
public class PropertiesLoaderUtilsExample {
    public static void main(String[] args) throws Throwable {    
        // ① jdbc.properties 是位于類路徑下的文件
        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");
        System.out.println(props.getProperty("jdbc.driverClassName"));
    }
}


一般情況下,應(yīng)用程序的屬性文件都放置在類路徑下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法顯然具有更強(qiáng)的實(shí)用性。此外,PropertiesLoaderUtils 還可以直接從 Resource 對(duì)象中加載屬性資源:

方法 說明 
static Properties loadProperties(Resource resource) 從 Resource 中加載屬性 
static void fillProperties(Properties props, Resource resource) 將 Resource 中的屬性數(shù)據(jù)添加到一個(gè)已經(jīng)存在的 Properties 對(duì)象中

特殊編碼的資源

當(dāng)您使用 Resource 實(shí)現(xiàn)類加載文件資源時(shí),它默認(rèn)采用操作系統(tǒng)的編碼格式。如果文件資源采用了特殊的編碼格式(如 UTF-8),則在讀取資源內(nèi)容時(shí)必須事先通過 EncodedResource 指定編碼格式,否則將會(huì)產(chǎn)生中文亂碼的問題。


清單 5. EncodedResourceExample
package com.baobaotao.io;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.FileCopyUtils;
public class EncodedResourceExample {
        public static void main(String[] args) throws Throwable {
            Resource res = new ClassPathResource("conf/file1.txt");
            // ① 指定文件資源對(duì)應(yīng)的編碼格式(UTF-8)
            EncodedResource encRes = new EncodedResource(res,"UTF-8");
            // ② 這樣才能正確讀取文件的內(nèi)容,而不會(huì)出現(xiàn)亂碼
            String content = FileCopyUtils.copyToString(encRes.getReader());
            System.out.println(content); 
    }
}


EncodedResource 擁有一個(gè) getResource() 方法獲取 Resource,但該方法返回的是通過構(gòu)造函數(shù)傳入的原 Resource 對(duì)象,所以必須通過 EncodedResource#getReader() 獲取應(yīng)用編碼后的 Reader 對(duì)象,然后再通過該 Reader 讀取文件的內(nèi)容。


回頁首 

Web 相關(guān)工具類

您幾乎總是使用 Spring 框架開發(fā) Web 的應(yīng)用,Spring 為 Web 應(yīng)用提供了很多有用的工具類,這些工具類可以給您的程序開發(fā)帶來很多便利。在這節(jié)里,我們將逐一介紹這些工具類的使用方法。

操作 Servlet API 的工具類

當(dāng)您在控制器、JSP 頁面中想直接訪問 Spring 容器時(shí),您必須事先獲取 WebApplicationContext 對(duì)象。Spring 容器在啟動(dòng)時(shí)將 WebApplicationContext 保存在 ServletContext的屬性列表中,通過 WebApplicationContextUtils 工具類可以方便地獲取 WebApplicationContext 對(duì)象。

WebApplicationContextUtils

當(dāng) Web 應(yīng)用集成 Spring 容器后,代表 Spring 容器的 WebApplicationContext 對(duì)象將以 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 為鍵存放在 ServletContext 屬性列表中。您當(dāng)然可以直接通過以下語句獲取 WebApplicationContext:

WebApplicationContext wac = (WebApplicationContext)servletContext.
getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);


但通過位于 org.springframework.web.context.support 包中的 WebApplicationContextUtils 工具類獲取 WebApplicationContext 更方便:

WebApplicationContext wac =WebApplicationContextUtils.
getWebApplicationContext(servletContext);


當(dāng) ServletContext 屬性列表中不存在 WebApplicationContext 時(shí),getWebApplicationContext() 方法不會(huì)拋出異常,它簡(jiǎn)單地返回 null。如果后續(xù)代碼直接訪問返回的結(jié)果將引發(fā)一個(gè) NullPointerException 異常,而 WebApplicationContextUtils 另一個(gè) getRequiredWebApplicationContext(ServletContext sc) 方法要求 ServletContext 屬性列表中一定要包含一個(gè)有效的 WebApplicationContext 對(duì)象,否則馬上拋出一個(gè) IllegalStateException 異常。我們推薦使用后者,因?yàn)樗芴崆鞍l(fā)現(xiàn)錯(cuò)誤的時(shí)間,強(qiáng)制開發(fā)者搭建好必備的基礎(chǔ)設(shè)施。

WebUtils

位于 org.springframework.web.util 包中的 WebUtils 是一個(gè)非常好用的工具類,它對(duì)很多 Servlet API 提供了易用的代理方法,降低了訪問 Servlet API 的復(fù)雜度,可以將其看成是常用 Servlet API 方法的門面類。

下面這些方法為訪問 HttpServletRequest 和 HttpSession 中的對(duì)象和屬性帶來了方便:

方法 說明 
Cookie getCookie(HttpServletRequest request, String name) 獲取 HttpServletRequest 中特定名字的 Cookie 對(duì)象。如果您需要?jiǎng)?chuàng)建 Cookie, Spring 也提供了一個(gè)方便的 CookieGenerator 工具類; 
Object getSessionAttribute(HttpServletRequest request, String name) 獲取 HttpSession 特定屬性名的對(duì)象,否則您必須通過request.getHttpSession.getAttribute(name) 完成相同的操作; 
Object getRequiredSessionAttribute(HttpServletRequest request, String name) 和上一個(gè)方法類似,只不過強(qiáng)制要求 HttpSession 中擁有指定的屬性,否則拋出異常; 
String getSessionId(HttpServletRequest request) 獲取 Session ID 的值; 
void exposeRequestAttributes(ServletRequest request, Map attributes) 將 Map 元素添加到 ServletRequest 的屬性列表中,當(dāng)請(qǐng)求被導(dǎo)向(forward)到下一個(gè)處理程序時(shí),這些請(qǐng)求屬性就可以被訪問到了;

此外,WebUtils還提供了一些和ServletContext相關(guān)的方便方法:

方法 說明 
String getRealPath(ServletContext servletContext, String path) 獲取相對(duì)路徑對(duì)應(yīng)文件系統(tǒng)的真實(shí)文件路徑; 
File getTempDir(ServletContext servletContext) 獲取 ServletContex 對(duì)應(yīng)的臨時(shí)文件地址,它以 File 對(duì)象的形式返回。

下面的片斷演示了使用 WebUtils 從 HttpSession 中獲取屬性對(duì)象的操作:

protected Object formBackingObject(HttpServletRequest request) throws Exception {
    UserSession userSession = (UserSession) WebUtils.getSessionAttribute(request, 
        "userSession");
    if (userSession != null) {
        return new AccountForm(this.petStore.getAccount(
        userSession.getAccount().getUsername()));
    } else {
        return new AccountForm();
    }
}


Spring 所提供的過濾器和監(jiān)聽器

Spring 為 Web 應(yīng)用提供了幾個(gè)過濾器和監(jiān)聽器,在適合的時(shí)間使用它們,可以解決一些常見的 Web 應(yīng)用問題。

延遲加載過濾器

Hibernate 允許對(duì)關(guān)聯(lián)對(duì)象、屬性進(jìn)行延遲加載,但是必須保證延遲加載的操作限于同一個(gè) Hibernate Session 范圍之內(nèi)進(jìn)行。如果 Service 層返回一個(gè)啟用了延遲加載功能的領(lǐng)域?qū)ο蠼o Web 層,當(dāng) Web 層訪問到那些需要延遲加載的數(shù)據(jù)時(shí),由于加載領(lǐng)域?qū)ο蟮?Hibernate Session 已經(jīng)關(guān)閉,這些導(dǎo)致延遲加載數(shù)據(jù)的訪問異常。

Spring 為此專門提供了一個(gè) OpenSessionInViewFilter 過濾器,它的主要功能是使每個(gè)請(qǐng)求過程綁定一個(gè) Hibernate Session,即使最初的事務(wù)已經(jīng)完成了,也可以在 Web 層進(jìn)行延遲加載的操作。

OpenSessionInViewFilter 過濾器將 Hibernate Session 綁定到請(qǐng)求線程中,它將自動(dòng)被 Spring 的事務(wù)管理器探測(cè)到。所以 OpenSessionInViewFilter 適用于 Service 層使用HibernateTransactionManager 或 JtaTransactionManager 進(jìn)行事務(wù)管理的環(huán)境,也可以用于非事務(wù)只讀的數(shù)據(jù)操作中。

要啟用這個(gè)過濾器,必須在 web.xml 中對(duì)此進(jìn)行配置:


<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>*.html</url-pattern>
</filter-mapping>

上面的配置,我們假設(shè)使用 .html 的后綴作為 Web 框架的 URL 匹配模式,如果您使用 Struts 等 Web 框架,可以將其改為對(duì)應(yīng)的“*.do”模型。 
中文亂碼過濾器

在您通過表單向服務(wù)器提交數(shù)據(jù)時(shí),一個(gè)經(jīng)典的問題就是中文亂碼問題。雖然我們所有的 JSP 文件和頁面編碼格式都采用 UTF-8,但這個(gè)問題還是會(huì)出現(xiàn)。解決的辦法很簡(jiǎn)單,我們只需要在 web.xml 中配置一個(gè) Spring 的編碼轉(zhuǎn)換過濾器就可以了:

<web-app>
<!---listener的配置-->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter ① Spring 編輯過濾器
    </filter-class>
    <init-param> ② 編碼方式
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param> ③ 強(qiáng)制進(jìn)行編碼轉(zhuǎn)換
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
    </filter>
    <filter-mapping> ② 過濾器的匹配 URL
        <filter-name>encodingFilter</filter-name>
        <url-pattern>*.html</url-pattern>
    </filter-mapping>

<!---servlet的配置-->
</web-app>


這樣所有以 .html 為后綴的 URL 請(qǐng)求的數(shù)據(jù)都會(huì)被轉(zhuǎn)碼為 UTF-8 編碼格式,表單中文亂碼的問題就可以解決了。

請(qǐng)求跟蹤日志過濾器

除了以上兩個(gè)常用的過濾器外,還有兩個(gè)在程序調(diào)試時(shí)可能會(huì)用到的請(qǐng)求日志跟蹤過濾器,它們會(huì)將請(qǐng)求的一些重要信息記錄到日志中,方便程序的調(diào)試。這兩個(gè)日志過濾器只有在日志級(jí)別為 DEBUG 時(shí)才會(huì)起作用:

方法 說明 
org.springframework.web.filter.ServletContextRequestLoggingFilter 該過濾器將請(qǐng)求的 URI 記錄到 Common 日志中(如通過 Log4J 指定的日志文件); 
org.springframework.web.filter.ServletContextRequestLoggingFilter 該過濾器將請(qǐng)求的 URI 記錄到 ServletContext 日志中。

以下是日志過濾器記錄的請(qǐng)求跟蹤日志的片斷:

(JspServlet.java:224) -     JspEngine --> /htmlTest.jsp
(JspServlet.java:225) -       ServletPath: /htmlTest.jsp
(JspServlet.java:226) -          PathInfo: null
(JspServlet.java:227) -          RealPath: D:\masterSpring\chapter23\webapp\htmlTest.jsp
(JspServlet.java:228) -        RequestURI: /baobaotao/htmlTest.jsp


通過這個(gè)請(qǐng)求跟蹤日志,程度調(diào)試者可以詳細(xì)地查看到有哪些請(qǐng)求被調(diào)用,請(qǐng)求的參數(shù)是什么,請(qǐng)求是否正確返回等信息。雖然這兩個(gè)請(qǐng)求跟蹤日志過濾器一般在程序調(diào)試時(shí)使用,但是即使程序部署不將其從 web.xml 中移除也不會(huì)有大礙,因?yàn)橹灰獙⑷罩炯?jí)別設(shè)置為 DEBUG 以上級(jí)別,它們就不會(huì)輸出請(qǐng)求跟蹤日志信息了。

轉(zhuǎn)存 Web 應(yīng)用根目錄監(jiān)聽器和 Log4J 監(jiān)聽器

Spring 在 org.springframework.web.util 包中提供了幾個(gè)特殊用途的 Servlet 監(jiān)聽器,正確地使用它們可以完成一些特定需求的功能。比如某些第三方工具支持通過 ${key} 的方式引用系統(tǒng)參數(shù)(即可以通過 System.getProperty() 獲取的屬性),WebAppRootListener 可以將 Web 應(yīng)用根目錄添加到系統(tǒng)參數(shù)中,對(duì)應(yīng)的屬性名可以通過名為“webAppRootKey”的 Servlet 上下文參數(shù)指定,默認(rèn)為“webapp.root”。下面是該監(jiān)聽器的具體的配置:


清單 6. WebAppRootListener 監(jiān)聽器配置

<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>baobaotao.root</param-value> ① Web 應(yīng)用根目錄以該屬性名添加到系統(tǒng)參數(shù)中
</context-param>

② 負(fù)責(zé)將 Web 應(yīng)用根目錄以 webAppRootKey 上下文參數(shù)指定的屬性名添加到系統(tǒng)參數(shù)中
<listener>
    <listener-class> 
    org.springframework.web.util.WebAppRootListener
    </listener-class>
</listener>


這樣,您就可以在程序中通過 System.getProperty("baobaotao.root") 獲取 Web 應(yīng)用的根目錄了。不過更常見的使用場(chǎng)景是在第三方工具的配置文件中通過${baobaotao.root} 引用 Web 應(yīng)用的根目錄。比如以下的 log4j.properties 配置文件就通過 ${baobaotao.root} 設(shè)置了日志文件的地址:

log4j.rootLogger=INFO,R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${baobaotao.root}/WEB-INF/logs/log4j.log ① 指定日志文件的地址
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n


另一個(gè)專門用于 Log4J 的監(jiān)聽器是 Log4jConfigListener。一般情況下,您必須將 Log4J 日志配置文件以 log4j.properties 為文件名并保存在類路徑下。Log4jConfigListener 允許您通過 log4jConfigLocation Servlet 上下文參數(shù)顯式指定 Log4J 配置文件的地址,如下所示:

① 指定 Log4J 配置文件的地址
<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
</context-param>

② 使用該監(jiān)聽器初始化 Log4J 日志引擎
<listener>
    <listener-class>
    org.springframework.web.util.Log4jConfigListener
    </listener-class>
</listener>

提示

一些Web應(yīng)用服務(wù)器(如 Tomcat)不會(huì)為不同的Web應(yīng)用使用獨(dú)立的系統(tǒng)參數(shù),也就是說,應(yīng)用服務(wù)器上所有的 Web 應(yīng)用都共享同一個(gè)系統(tǒng)參數(shù)對(duì)象。這時(shí),您必須通過webAppRootKey 上下文參數(shù)為不同Web應(yīng)用指定不同的屬性名:如第一個(gè) Web 應(yīng)用使用 webapp1.root 而第二個(gè) Web 應(yīng)用使用 webapp2.root 等,這樣才不會(huì)發(fā)生后者覆蓋前者的問題。此外,WebAppRootListener 和 Log4jConfigListener 都只能應(yīng)用在 Web 應(yīng)用部署后 WAR 文件會(huì)解包的 Web 應(yīng)用服務(wù)器上。一些 Web 應(yīng)用服務(wù)器不會(huì)將Web 應(yīng)用的 WAR 文件解包,整個(gè) Web 應(yīng)用以一個(gè) WAR 包的方式存在(如 Weblogic),此時(shí)因?yàn)闊o法指定對(duì)應(yīng)文件系統(tǒng)的 Web 應(yīng)用根目錄,使用這兩個(gè)監(jiān)聽器將會(huì)發(fā)生問題。


Log4jConfigListener 監(jiān)聽器包括了 WebAppRootListener 的功能,也就是說,Log4jConfigListener 會(huì)自動(dòng)完成將 Web 應(yīng)用根目錄以 webAppRootKey 上下文參數(shù)指定的屬性名添加到系統(tǒng)參數(shù)中,所以當(dāng)您使用 Log4jConfigListener 后,就沒有必須再使用 WebAppRootListener了。

Introspector 緩存清除監(jiān)聽器

Spring 還提供了一個(gè)名為 org.springframework.web.util.IntrospectorCleanupListener 的監(jiān)聽器。它主要負(fù)責(zé)處理由 JavaBean Introspector 功能而引起的緩存泄露。IntrospectorCleanupListener 監(jiān)聽器在 Web 應(yīng)用關(guān)閉的時(shí)會(huì)負(fù)責(zé)清除 JavaBean Introspector 的緩存,在 web.xml 中注冊(cè)這個(gè)監(jiān)聽器可以保證在 Web 應(yīng)用關(guān)閉的時(shí)候釋放與其相關(guān)的 ClassLoader 的緩存和類引用。如果您使用了 JavaBean Introspector 分析應(yīng)用中的類,Introspector 緩存會(huì)保留這些類的引用,結(jié)果在應(yīng)用關(guān)閉的時(shí)候,這些類以及Web 應(yīng)用相關(guān)的 ClassLoader 不能被垃圾回收。不幸的是,清除 Introspector 的唯一方式是刷新整個(gè)緩存,這是因?yàn)闆]法準(zhǔn)確判斷哪些是屬于本 Web 應(yīng)用的引用對(duì)象,哪些是屬于其它 Web 應(yīng)用的引用對(duì)象。所以刪除被緩存的 Introspection 會(huì)導(dǎo)致將整個(gè) JVM 所有應(yīng)用的 Introspection 都刪掉。需要注意的是,Spring 托管的 Bean 不需要使用這個(gè)監(jiān)聽器,因?yàn)?Spring 的 Introspection 所使用的緩存在分析完一個(gè)類之后會(huì)馬上從 javaBean Introspector 緩存中清除掉,并將緩存保存在應(yīng)用程序特定的 ClassLoader 中,所以它們一般不會(huì)導(dǎo)致內(nèi)存資源泄露。但是一些類庫和框架往往會(huì)產(chǎn)生這個(gè)問題。例如 Struts 和 Quartz 的 Introspector 的內(nèi)存泄漏會(huì)導(dǎo)致整個(gè)的 Web 應(yīng)用的 ClassLoader 不能進(jìn)行垃圾回收。在 Web 應(yīng)用關(guān)閉之后,您還會(huì)看到此應(yīng)用的所有靜態(tài)類引用,這個(gè)錯(cuò)誤當(dāng)然不是由這個(gè)類自身引起的。解決這個(gè)問題的方法很簡(jiǎn)單,您僅需在 web.xml 中配置 IntrospectorCleanupListener 監(jiān)聽器就可以了:

<listener>
    <listener-class>
    org.springframework.web.util.IntrospectorCleanupListener
    </listener-class>
</listener>


回頁首 

小結(jié)

本文介紹了一些常用的 Spring 工具類,其中大部分 Spring 工具類不但可以在基于 Spring 的應(yīng)用中使用,還可以在其它的應(yīng)用中使用。使用 JDK 的文件操作類在訪問類路徑相關(guān)、Web 上下文相關(guān)的文件資源時(shí),往往顯得拖泥帶水、拐彎抹角,Spring 的 Resource 實(shí)現(xiàn)類使這些工作變得輕松了許多。

在 Web 應(yīng)用中,有時(shí)你希望直接訪問 Spring 容器,獲取容器中的 Bean,這時(shí)使用 WebApplicationContextUtils 工具類從 ServletContext 中獲取 WebApplicationContext 是非常方便的。WebUtils 為訪問 Servlet API 提供了一套便捷的代理方法,您可以通過 WebUtils 更好的訪問 HttpSession 或 ServletContext 的信息。

Spring 提供了幾個(gè) Servlet 過濾器和監(jiān)聽器,其中 ServletContextRequestLoggingFilter 和 ServletContextRequestLoggingFilter 可以記錄請(qǐng)求訪問的跟蹤日志,你可以在程序調(diào)試時(shí)使用它們獲取請(qǐng)求調(diào)用的詳細(xì)信息。WebAppRootListener 可以將 Web 應(yīng)用的根目錄以特定屬性名添加到系統(tǒng)參數(shù)中,以便第三方工具類通過 ${key} 的方式進(jìn)行訪問。Log4jConfigListener 允許你指定 Log4J 日志配置文件的地址,且可以在配置文件中通過 ${key} 的方式引用 Web 應(yīng)用根目錄,如果你需要在 Web 應(yīng)用相關(guān)的目錄創(chuàng)建日志文件,使用 Log4jConfigListener 可以很容易地達(dá)到這一目標(biāo)。

Web 應(yīng)用的內(nèi)存泄漏是最讓開發(fā)者頭疼的問題,雖然不正確的程序編寫可能是這一問題的根源,也有可能是一些第三方框架的 JavaBean Introspector 緩存得不到清除而導(dǎo)致的,Spring 專門為解決這一問題配備了 IntrospectorCleanupListener 監(jiān)聽器,它只要簡(jiǎn)單在 web.xml 中聲明該監(jiān)聽器就可以了。



蜂鳥 2011-05-10 10:02 發(fā)表評(píng)論
]]>
hibernate Restrictions用法 MatchMode.ANYWHEREhttp://www.aygfsteel.com/alancxx/articles/349490.html蜂鳥蜂鳥Wed, 04 May 2011 06:09:00 GMThttp://www.aygfsteel.com/alancxx/articles/349490.htmlhttp://www.aygfsteel.com/alancxx/comments/349490.htmlhttp://www.aygfsteel.com/alancxx/articles/349490.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/349490.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/349490.html

方法

說明

Restrictions.eq

Restrictions.allEq

利用Map來進(jìn)行多個(gè)等于的限制

Restrictions.gt

Restrictions.ge

>=

Restrictions.lt

Restrictions.le

<=

Restrictions.between

BETWEEN

Restrictions.like

LIKE

Restrictions.in

in

Restrictions.and

and

Restrictions.or

or

Restrictions.sqlRestriction

用SQL限定查詢


QBC常用限定方法

Restrictions.eq --> equal,等于.

Restrictions.allEq --> 參數(shù)為Map對(duì)象,使用key/value進(jìn)行多個(gè)等于的比對(duì),相當(dāng)于多個(gè)Restrictions.eq 的效果

Restrictions.gt --> great-than > 大于

Restrictions.ge --> great-equal >= 大于等于

Restrictions.lt --> less-than, < 小于

Restrictions.le --> less-equal <= 小于等于

Restrictions.between --> 對(duì)應(yīng)SQL的between子句

Restrictions.like --> 對(duì)應(yīng)SQL的LIKE子句

Restrictions.in --> 對(duì)應(yīng)SQL的in子句

Restrictions.and --> and 關(guān)系

Restrictions.or --> or 關(guān)系

Restrictions.isNull --> 判斷屬性是否為空,為空則返回true

Restrictions.isNotNull --> 與isNull相反

Restrictions.sqlRestriction --> SQL限定的查詢

Order.asc --> 根據(jù)傳入的字段進(jìn)行升序排序

Order.desc --> 根據(jù)傳入的字段進(jìn)行降序排序

MatchMode.EXACT --> 字符串精確匹配.相當(dāng)于"like 'value'"

MatchMode.ANYWHERE --> 字符串在中間匹配.相當(dāng)于"like '%value%'"

MatchMode.START --> 字符串在最前面的位置.相當(dāng)于"like 'value%'"

MatchMode.END --> 字符串在最后面的位置.相當(dāng)于"like '%value'"

例子
查詢年齡在20-30歲之間的所有學(xué)生對(duì)象
List list = session.createCriteria(Student.class)
       .add(Restrictions.between("age",new Integer(20),new Integer(30)).list();
查詢學(xué)生姓名在AAA,BBB,CCC之間的學(xué)生對(duì)象
String[] names = {"AAA","BBB","CCC"};
List list = session.createCriteria(Student.class)
       .add(Restrictions.in("name",names)).list();
查詢年齡為空的學(xué)生對(duì)象
List list = session.createCriteria(Student.class)
       .add(Restrictions.isNull("age")).list();
查詢年齡等于20或者年齡為空的學(xué)生對(duì)象
List list = session.createCriteria(Student.class)
       .add(Restrictions.or(Restrictions.eq("age",new Integer(20)),
                 Restrictions.isNull("age")).list();

--------------------------------------------------------------------
使用QBC實(shí)現(xiàn)動(dòng)態(tài)查詢 
public List findStudents(String name,int age){

Criteria criteria = session.createCriteria(Student.class);
if(name != null){
   criteria.add(Restrictions.liek("name",name,MatchMode.ANYWHERE));
}
if(age != 0){
   criteria.add(Restrictions.eq("age",new Integer(age)));
}
criteria.addOrder(Order.asc("name"));//根據(jù)名字升序排列
return criteria.list();
}

-----------------------------------------------------------------------------------

今天用了寫hibernate高級(jí)查詢時(shí)用了Restrictions(當(dāng)然Expression也是可以以的)這個(gè)類.感覺不錯(cuò).
下面的代碼寫的不易讀.其實(shí)核心就是一句
Restrictions.or(Restrictions.like(),Restrictions.or(Restrictions.like,........))
里面的or可以無限加的.還是比較好用

Session session = getHibernateTemplate().getSessionFactory()
                .openSession();
        Criteria criteria = session.createCriteria(Film.class);
        List<Film> list = criteria.add(
            Restrictions.or(Restrictions.like("description", key,MatchMode.ANYWHERE),
            Restrictions.or(Restrictions.like("name", key,MatchMode.ANYWHERE),
                Restrictions.or(    Restrictions.like("direct", key,MatchMode.ANYWHERE),
                Restrictions.or(Restrictions.like("mainplay",key,MatchMode.ANYWHERE),
                        Restrictions.like("filearea", key,MatchMode.ANYWHERE)))))).list();

        session.close();
        return list;



蜂鳥 2011-05-04 14:09 發(fā)表評(píng)論
]]>
Fedora Core 4下的GPG加密解密及文件完整性驗(yàn)證http://www.aygfsteel.com/alancxx/articles/348896.html蜂鳥蜂鳥Sat, 23 Apr 2011 15:02:00 GMThttp://www.aygfsteel.com/alancxx/articles/348896.htmlhttp://www.aygfsteel.com/alancxx/comments/348896.htmlhttp://www.aygfsteel.com/alancxx/articles/348896.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/348896.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/348896.html
準(zhǔn)備知識(shí):
對(duì)稱加密:
發(fā)送方: 010111 XOR 101100 = 111011   (101100為加密密鑰)
接收方: 111011 XOR 101100 = 010111
公鑰加密:
發(fā)送方產(chǎn)生兩把密鑰:公鑰(Public Key)&私鑰(Private Key),也就是密鑰對(duì)(Key Pair)
明文->公鑰加密->密文->私鑰解密->明文
數(shù)字簽名:
....


-----------------------------發(fā)送方的操作-------------------------------------
sh# mkdir ~/.gnupg   //默認(rèn)是把密鑰對(duì)存在此目錄
sh# gpg --gen-key //生成公鑰pubring.gpg,私鑰secring.gpg,郵箱是很重要的
sh# gpg --list-keys //查看所有密鑰,如果生成了多個(gè)密鑰對(duì)的話就有多個(gè)了
sh# gpg --list-public-key //查看所有公鑰,注意pub后面的*號(hào)字符串,pub xxxxx/******** 2007-07-10,它就是以下可能用到的KEYID
sh# gpg --list-secret-key //查看所有密鑰
sh# gpg --list-sig //查看所有簽名
sh# gpg --export-secret-keys -a -o secring.asc //導(dǎo)出私鑰,作為備份
sh# gpg -a --export zjstandup@126.com >test.gpg //導(dǎo)出公鑰,郵箱名是第一步填的,對(duì)應(yīng)于zjstandup@126.com的公匙信息就保存到了test.gpg文件中,此文件可以由郵箱發(fā)送或上傳至公鑰服務(wù)器供別人下載(如subkeys.pgp.net),有點(diǎn)像BT種子,哈哈

/**此處將演示怎么把公鑰上傳至公鑰服務(wù)器上,可以直接去網(wǎng)站上傳,也可以像以下這樣用命令上傳
sh# gpg --send-keys KEYID //KEYID用以上那個(gè)代替,默認(rèn)好像是傳到了subkeys.pgp.net,文件名就不是test.gpg了,這些公鑰服務(wù)器好像是全球同步更新!厲害阿!

**/


sh# gedit test.txt //生成一個(gè)文本,里面輸入點(diǎn)東西,用于以下測(cè)試

將演示兩種驗(yàn)證方式和一個(gè)數(shù)字簽名
一種是公鑰驗(yàn)證,大概是用于驗(yàn)證文件完整性,相當(dāng)于:sh#md5sum ***;
另一種是私鑰驗(yàn)證,控制只讓那些知道密碼的人能打開看

sh# gpg --clearsign test.txt //使用私匙對(duì)數(shù)據(jù)進(jìn)行簽名,生成test.txt.asc,打開此文件還是可以看到內(nèi)容的,只是多了一些東西,把這個(gè)發(fā)給其他人,這個(gè)演示公鑰驗(yàn)證
sh# gpg --output test.txt.gpg -r zjstandup@126.com -as --encrypt test.txt //導(dǎo)入私鑰,數(shù)據(jù)被加密成了test.txt.gpg,打開此文件看不到原信息的,把這個(gè)發(fā)給對(duì)方,這個(gè)演示私鑰驗(yàn)證
sh# gpg --output test.sig --sign test.txt //這個(gè)演示數(shù)字簽名



---------------------------接收方的操作------------------------------------------
/**下載公鑰,由郵件接收或者從服務(wù)器上下載,此處演示從服務(wù)器下載
sh# gpg --search-keys zjstandup@126.com //搜索公鑰,啟動(dòng)了全球搜索?!然后填入1就下載!

**/
sh# gpg --import test.gpg //導(dǎo)入公鑰至本機(jī),test.gpg由發(fā)送方郵件傳輸過來或從公鑰服務(wù)器下載過來的

/**以下一段不太清楚,好像是防止公鑰被篡改,驗(yàn)證公鑰的完整性
sh# gpg --fingerprint zjstandup@126.com //指紋取樣,防偽造的公鑰,執(zhí)行后可以看到密鑰指紋,可以通過其他通訊方式咨詢對(duì)方,是否是這個(gè)公鑰(應(yīng)該是上方讓大家注意的pub后面的字符串)
sh# gpg --sign-key zjstandup@126.com
sh# gpg --check-sigs zjstandup@126.com
sh# gpg --edit-key zjstandup@126.com
sh# trust
sh# quit
**/

1:公鑰驗(yàn)證
sh# gpg --verify test.txt.asc //將有信息表明是完整的簽字,假如改變了這個(gè)文件里面的信息再執(zhí)行此命令,將出現(xiàn)不同的結(jié)果哦!

2:私鑰驗(yàn)證
sh# gpg --decrypt test.txt.gpg > zjstandup.txt //執(zhí)行,要輸入正確的密碼(在發(fā)送端生成密鑰對(duì)時(shí)的那個(gè))才能生成txt

3;數(shù)字簽名
sh# gpg --output sig.txt --decrypt test.sig //將顯示完整的簽字并還原內(nèi)容生成sig.txt


sh# gpg --help >> manule.txt
sh# gedit manule.txt

//將看到以下說明
gpg (GnuPG) 1.4.1
Copyright (C) 2005 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

Home: ~/.gnupg
支持的算法:
公鑰:RSA, RSA-E, RSA-S, ELG-E, DSA
對(duì)稱加密:3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH
散列:MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512
壓縮:不壓縮, ZIP, ZLIB, BZIP2

語法:gpg [選項(xiàng)] [文件名]
簽字、檢查、加密或解密
默認(rèn)的操作依輸入數(shù)據(jù)而定

指令:

-s, --sign [文件名]           生成一份簽字
     --clearsign [文件名]      生成一份明文簽字
-b, --detach-sign             生成一份分離的簽字
-e, --encrypt                 加密數(shù)據(jù)
-c, --symmetric               僅使用對(duì)稱加密
-d, --decrypt                 解密數(shù)據(jù)(默認(rèn))
     --verify                  驗(yàn)證簽字
     --list-keys               列出密鑰
     --list-sigs               列出密鑰和簽字
     --check-sigs              列出并檢查密鑰簽字
     --fingerprint             列出密鑰和指紋
-K, --list-secret-keys        列出私鑰
     --gen-key                 生成一副新的密鑰對(duì)
     --delete-keys             從公鑰鑰匙環(huán)里刪除密鑰
     --delete-secret-keys      從私鑰鑰匙環(huán)里刪除密鑰
     --sign-key                為某把密鑰添加簽字
     --lsign-key               為某把密鑰添加本地簽字
     --edit-key                編輯某把密鑰或?yàn)槠涮砑雍炞?br />      --gen-revoke              生成一份吊銷證書
     --export                  導(dǎo)出密鑰
     --send-keys               把密鑰導(dǎo)出到某個(gè)公鑰服務(wù)器上
     --recv-keys               從公鑰服務(wù)器上導(dǎo)入密鑰
     --search-keys             在公鑰服務(wù)器上搜尋密鑰
     --refresh-keys            從公鑰服務(wù)器更新所有的本地密鑰
     --import                  導(dǎo)入/合并密鑰
     --card-status             打印卡狀態(tài)
     --card-edit               更改卡上的數(shù)據(jù)
     --change-pin              更改卡的 PIN
     --update-trustdb          更新信任度數(shù)據(jù)庫
     --print-md 算法 [文件]    使用指定的散列算法打印報(bào)文散列值

選項(xiàng):

-a, --armor                   輸出經(jīng) ASCII 封裝
-r, --recipient 某甲          為收件者“某甲”加密
-u, --local-user              使用這個(gè)用戶標(biāo)識(shí)來簽字或解密
-z N                          設(shè)定壓縮等級(jí)為 N (0 表示不壓縮)
     --textmode                使用標(biāo)準(zhǔn)的文本模式
-o, --output                  指定輸出文件
-v, --verbose                 詳細(xì)模式
-n, --dry-run                 不做任何改變
-i, --interactive             覆蓋前先詢問
     --openpgp                 行為嚴(yán)格遵循 OpenPGP 定義
     --pgp2                    生成與 PGP 2.x 兼容的報(bào)文

(請(qǐng)參考在線說明以獲得所有命令和選項(xiàng)的完整清單)

范例:

-se -r Bob [文件名]          為 Bob 這個(gè)收件人簽字及加密
--clearsign [文件名]         做出明文簽字
--detach-sign [文件名]       做出分離式簽字
--list-keys [某甲]           顯示密鑰
--fingerprint [某甲]         顯示指紋

請(qǐng)向 <gnupg-bugs@gnu.org> 報(bào)告程序缺陷。
請(qǐng)向 <zuxyhere@eastday.com> 反映簡(jiǎn)體中文翻譯的問題。


蜂鳥 2011-04-23 23:02 發(fā)表評(píng)論
]]>
GPG(pgp)加解密詳述http://www.aygfsteel.com/alancxx/articles/348895.html蜂鳥蜂鳥Sat, 23 Apr 2011 14:55:00 GMThttp://www.aygfsteel.com/alancxx/articles/348895.htmlhttp://www.aygfsteel.com/alancxx/comments/348895.htmlhttp://www.aygfsteel.com/alancxx/articles/348895.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/348895.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/348895.html一、介紹

我們都知道,互聯(lián)網(wǎng)是不安全的,但其上所使用的大部分應(yīng)用,如Web、Email等一般都只提供明文傳輸方式(用https、smtps等例外)。所以,當(dāng)我們需要傳輸重要文件時(shí),應(yīng)該對(duì)當(dāng)中的信息加密。非對(duì)稱密碼系統(tǒng)是其中一種常見的加密手段。而在基于PGP方式加密的中文介紹少之又少,所以萌生了寫一個(gè)完整教程的想法,當(dāng)然本文部分資料是我搜遍網(wǎng)絡(luò)整理出來的,并不能保證百分之百的原創(chuàng)

GnuPG 是一個(gè)用來進(jìn)行非對(duì)稱加密(PGP)的免費(fèi)軟件,簡(jiǎn)稱GPG(是不是有的童鞋已經(jīng)被PGP和GPG給搞昏了)。先說說什么是非對(duì)稱加密。傳統(tǒng)的加密手段往往是使用同一個(gè)密碼進(jìn)行加密和解密。例如你加密時(shí)用的密碼是“abc”, 則解密時(shí)也要使用“abc”才行。這樣就存在一個(gè)問題,你不能夠把一段加密信息發(fā)送給你的朋友。試想,如果采用這種加密方式把信息發(fā)送給你的朋友時(shí),你的 朋友必須要知道你的密碼才能把你的信息解密出來。但你如何保證你的朋友是絕對(duì)可靠的呢?也就是說,如果你的朋友把你的密碼告訴了別人,你的密碼就不再安全 了。
非對(duì)稱加密采用的是另一種思想。它會(huì)給你產(chǎn)生兩個(gè)密鑰,一個(gè)稱為“公鑰”,另一個(gè)稱為“私鑰”。公鑰是可以公開的,你盡管把它傳給別 人;私鑰你一定要保管好不讓其他任何人知道。當(dāng)某人得到你的公鑰后,他就可以給你發(fā)送加密信息了。具體來說,他把他要發(fā)給你的信息用你的公鑰加密后發(fā)給 你,加密的信息只能用你的私鑰去解密。這樣,因?yàn)槭澜缟铣四阋酝鉀]有別人知道你的私鑰,所以即使別人看到發(fā)送給你的加密信息他也無法解密,甚至連發(fā)送者 本人也不行。因?yàn)樗恢滥愕乃借€。簡(jiǎn)單說來,就是用公鑰去加密;用對(duì)應(yīng)的私鑰去解密。想給誰發(fā)送加密信息,首先要得到他的公鑰。
支持非 對(duì)稱加密的軟件有多種,最著名的可能是美國(guó)的PGP了,不過它是個(gè)商業(yè)軟件,價(jià)格不便宜。對(duì)于加密軟件,我反對(duì)使用破解軟件,因?yàn)槿绻畔⑿枰用艿脑挘?肯定是非常重要的信息,破解軟件無法保證加密的安全可靠。因此我建議使用免費(fèi)開源的GnuPG軟件進(jìn)行信息的加密和解密。

二、使用:

1.生成密鑰對(duì)
要使用GnuPG加密,首先需要?jiǎng)?chuàng)建密鑰對(duì),執(zhí)行:

# gpg –gen-key
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

 

請(qǐng)選擇您要使用的密鑰種類:
(1) DSA 和 ElGamal (默認(rèn))
(2) DSA (僅用于簽名)
(5) RSA (僅用于簽名)
您的選擇? 1  ←只有1可以用于加密,其他種類只能用于簽名
DSA 密鑰對(duì)會(huì)有 1024 位。
ELG-E 密鑰長(zhǎng)度應(yīng)在 1024 位與 4096 位之間。
您想要用多大的密鑰尺寸?(2048)  ←選擇密碼的位數(shù),位數(shù)越大,越安全,但速度越慢
您所要求的密鑰尺寸是 2048 位
請(qǐng)?jiān)O(shè)定這把密鑰的有效期限。
0 = 密鑰永不過期
<n>  = 密鑰在 n 天后過期
<n>w = 密鑰在 n 周后過期
<n>m = 密鑰在 n 月后過期
<n>y = 密鑰在 n 年后過期
密鑰的有效期限是?(0) 0  ←根據(jù)實(shí)際情況選擇密鑰期限
密鑰永遠(yuǎn)不會(huì)過期
以上正確嗎?(y/n)y  ←確認(rèn)

您需要一個(gè)用戶標(biāo)識(shí)來辨識(shí)您的密鑰;本軟件會(huì)用真實(shí)姓名、注釋和電子郵件地址組合
成用戶標(biāo)識(shí),如下所示:
“Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>”

真實(shí)姓名:Hyphen Wang  ←請(qǐng)?zhí)钊胝鎸?shí)姓名,后面會(huì)用到
電子郵件地址:gpgencrypt@linuxfly.org  ←郵件作為標(biāo)記之一,不能重復(fù)
注釋:Use for GPG Encrypt  ←僅是注釋而已
您選定了這個(gè)用戶標(biāo)識(shí):
“Hyphen Wang (Use for GPG Encrypt) <gpgencrypt@linuxfly.org>”

更改姓名(N)、注釋(C)、電子郵件地址(E)或確定(O)/退出(Q)?O  ←輸入“O”確認(rèn)
您需要一個(gè)密碼來保護(hù)您的私鑰。  ←輸入兩次用于訪問私鑰的密碼,緊記,不能公開或丟失

我們需要生成大量的隨機(jī)字節(jié)。這個(gè)時(shí)候您可以多做些瑣事(像是敲打鍵盤、移動(dòng)
鼠標(biāo)、讀寫硬盤之類的),這會(huì)讓隨機(jī)數(shù)字發(fā)生器有更好的機(jī)會(huì)獲得足夠的熵?cái)?shù)。
++++++++++…++++++++++..++++++++

隨機(jī)字節(jié)不夠多。請(qǐng)?jiān)僮鲆恍┢渌默嵤拢允共僮飨到y(tǒng)能搜集到更多的熵?cái)?shù)!
(還需要274字節(jié))  ←運(yùn)行一些的程序,以便在內(nèi)存中獲得更多隨機(jī)數(shù)
我們需要生成大量的隨機(jī)字節(jié)。這個(gè)時(shí)候您可以多做些瑣事(像是敲打鍵盤、移動(dòng)
鼠標(biāo)、讀寫硬盤之類的),這會(huì)讓隨機(jī)數(shù)字發(fā)生器有更好的機(jī)會(huì)獲得足夠的熵?cái)?shù)。
+++++++++++++++++++++++++.+++++.+++++.++++++++++.+++<+++++..+++++^^^
gpg: 密鑰 A3942296 被標(biāo)記為絕對(duì)信任  ←密鑰ID
公鑰和私鑰已經(jīng)生成并經(jīng)簽名。

gpg: 正在檢查信任度數(shù)據(jù)庫
gpg: 需要 3 份勉強(qiáng)信任和 1 份完全信任,PGP 信任模型
gpg: 深度:0 有效性:  2 已簽名:  0 信任度:0-,0q,0n,0m,0f,2u
pub   1024D/A3942296 2008-12-19
密鑰指紋 = E95E 1F77 6C4E 33BD 740C  19AB EEF9 A67E A394 2296
uid                  Hyphen Wang (Use for GPG Encrypt) <gpgencrypt@linuxfly.org>
sub   2048g/911E677B 2008-12-19

2.密鑰的回收
當(dāng)您的密鑰對(duì)生成之后,您應(yīng)該立即做一個(gè)公鑰回收證書,如果您忘記了您的私鑰的口令或者您的私鑰丟失或者被盜竊,您可以發(fā)布這個(gè)證書來聲明以前的公鑰不再有效。生成回收證書的選項(xiàng)是”–gen-revoke”。

gpg –output revoke.asc –gen-revoke mykeyID

其中mykey 參數(shù)是可以表示的密鑰標(biāo)識(shí),產(chǎn)生的回收證書放在revoke.asc文件里,一旦回收證書被發(fā)放,以前的證書就不能再被其他用戶訪問,因此以前的公鑰也就失效了。

PS:如果一旦決定撤銷已經(jīng)上傳的公鑰,就需要將該密鑰的回收證書上傳至密鑰服務(wù)器完成回收工作。

gpg –keyserver Server Address –send-keys mykeyID

3.密鑰的上傳

當(dāng)上述工作完成以后,為了讓盡可能多的人獲取您的公鑰,您可以將公鑰郵寄出去,或者貼在自己的個(gè)人主頁上,當(dāng)然還有一種更好的方法就是上傳到全球性的密鑰服務(wù)器,其他用戶可以通過您提供的公鑰ID來搜索并獲得您的公鑰。

通過如下命令可以將你的key發(fā)布到服務(wù)器上:

gpg –keyserver Server Address –send-keys mykeyID
PS:當(dāng)然您也可以定義默認(rèn)的服務(wù)器key server,一般安裝好后的默認(rèn)key server都是subkeys.pgp.net。你也可以通過修改.gnupg/gpg.conf中的keyserver信息來改變你的key server。
4.密鑰的導(dǎo)出/導(dǎo)入

我們通常需要導(dǎo)出公鑰和私鑰保存起來,當(dāng)然公鑰是可以滿世界的潑灑,但是私鑰請(qǐng)務(wù)必保存好,否則你的密鑰對(duì)將會(huì)永久性的失去威力。
  • 公鑰的導(dǎo)出:

gpg -o keyfilename –export mykeyID

如果沒有mykeyID則是備份所有的公鑰,-o表示輸出到文件keyfilename中,如果加上-a的參數(shù)則輸出文本格式( ASCII )的信息,否則輸出的是二進(jìn)制格式信息。

  • 私鑰的導(dǎo)出:

gpg -o keyfilename –export-secret-keys mykeyID

如果沒有mykeyID則是備份所有的私鑰,-o表示輸出到文件keyfilename中,如果加上-a的參數(shù)則輸出文本格式的信息,否則輸出的是二進(jìn)制格式信息。

  • 密鑰的導(dǎo)入:

gpg –import filename

PS:用戶可以使用gpg –list-keys命令查看是否成功導(dǎo)入了密鑰。

5.加密解密和數(shù)字簽名

通過上述的密鑰生成以及公鑰分發(fā)后,加密和解密數(shù)據(jù)變得非常容易,用戶可以通過使用該功能來達(dá)到安全地在網(wǎng)絡(luò)上傳輸自己的隱密數(shù)據(jù)的目的。

如果用戶patterson要給用戶liyang發(fā)送一個(gè)加密文件,則他可以使用liyang的公鑰加密這個(gè)文件,并且這個(gè)文件也只有l(wèi)iyang使用自己的密鑰才可以解密查看。下面給出加解密的步驟:

  • 用戶patterson使用liyang的公鑰加密文件test,使用下面的指令:

# gpg -e test

You did not specify a user ID. (you may use “-r”)

Enter the user ID. End with an empty line: liyang

Added 1024g/C50E455A 2006-01-02 “liyang (hello) < liyang@sina.com>”

這樣,就可以將gpg.conf文件加密成test.gpg,一般用戶是無法閱讀的

PS:當(dāng)然你也可以直接指定使用哪個(gè)用戶的公鑰進(jìn)行加密:

gpg -e -r liyang test  (-r 表示指定用戶)

還可以加上參數(shù) -a 來輸出ASCII編碼的文件test.asc(test.gpg是二進(jìn)制編碼的,不可用文本讀)

gpg -ea -r liyang test

  • 用戶liyang 使用自己的私鑰來解密該文件,如下所示:

# gpg -d test.gpg

You need a passphrase to unlock the secret key for

user: “liyang (hello) < liyang@sina.com>”

1024-bit ELG-E key, ID C50E455A, created 2006-01-02 (main key ID 378D11AF)

GnuPG提示用戶,需要輸入生成私鑰使用的密碼:

Enter passphrase:

gpg: encrypted with 1024-bit ELG-E key, ID C50E455A, created 2006-01-02

“liyang (hello) < liyang@sina.com>”

PS:無論加密解密,都可以加上-o參數(shù)來指定加密和解密后的輸出文件,例如

#gpg -o doc.gpg -er name doc
其中name是選擇誰的公鑰加密,即誰是文件的接收者。
doc為要加密的文件,即原文件
doc.gpg為命令執(zhí)行后生成的加密的文件,這里要先指定好文件名

  • 對(duì)文件進(jìn)行簽名

1、數(shù)字簽名
命令格式:
#gpg -o doc.sig -s doc
其中doc是原文件,doc.sig包含了原文件和簽名,是二進(jìn)制的。這個(gè)命令會(huì)要求你輸入你的私鑰的密碼句。
#gpg -o doc.sig -ser name doc
既簽名又加密

2、文本簽名
#gpg -o doc.sig –clearsign doc
這樣產(chǎn)生的doc.sig同樣包含原文件和簽名,其中簽名是文本的,而原文件不變。

3、分離式簽名
#gpg -o doc.sig -ab doc
doc.sig僅包括簽名,分離式簽名的意思是原文件和簽名是分開的。
b 表示分離式簽名detach-sign

4、驗(yàn)證簽名
#gpg –verify doc.sig [doc]
驗(yàn)證之前必須導(dǎo)入文件作者的公鑰,對(duì)于分離式簽名,最后還要加上原文件,即后面的doc。

  • 密匙簽名和用戶信任(進(jìn)階功能)

盡管在理論上講,具備了公匙和私匙就可以實(shí)現(xiàn)安全的信息通訊,但是在實(shí)際應(yīng)用中,還必須對(duì)公匙進(jìn)行有效確認(rèn)。因?yàn)椋_實(shí)存在偽造公匙信息的可能。

由此,在GPG中引入了一個(gè)復(fù)雜的信任系統(tǒng),以幫助我們區(qū)分哪些密匙是真的,哪些密匙是假的。這個(gè)信任系統(tǒng)是基于密匙的,主要包括密匙簽名。

當(dāng)收到熟人的公匙并且GPG告知不存在任何實(shí)體可信信息附加于這個(gè)公匙后,首要的事情就是對(duì)這個(gè)密匙進(jìn)行“指紋采樣”(fingerprint)。例如,我們對(duì)來自mike的公匙進(jìn)行了導(dǎo)入操作,并且GPG告知我們不存在這個(gè)密匙的附加可信信息,這時(shí)候,我們首先要做的工作就是對(duì)這個(gè)新密匙進(jìn)行“指紋采樣 ”,相關(guān)命令及執(zhí)行情況如下:

$ gpg –fingerprint mike@hairnet.orgpub 1024D/4F03BD39 2001-01-15 Mike Socks (I’m WIRED) Key fingerprint = B121 5431 8DE4 E3A8 4AA7 737D 20BE 0DB8 4F03 BD39sub 1024g/FDBB477D 2001-01-15$

這樣,就從密匙數(shù)據(jù)中生成了其指紋信息,并且應(yīng)該是唯一的。然后,我們打電話給mike,確認(rèn)兩件事情。首先,他是否發(fā)送給我們了密匙;其次,他的公匙的指紋信息是什么。如果Mike確認(rèn)了這兩件事情,我們就可以確信這個(gè)密匙是合法的。接下來,我們對(duì)密匙進(jìn)行簽名操作,以表示這個(gè)密匙來自Mike而且我們對(duì)密匙的信任,相關(guān)命令及執(zhí)行情況如下:

$ gpg –sign-key mike@hairnet.orgpub 1024D/4F03BD39 created: 2001-01-15 expires: neversub 1024g/FDBB477D created: 2001-01-15 expires: never(1) Mike Socks (I’m WIRED) pub 1024D/4F03BD39 created: 2001-01-15 expires: neverFingerprint = B121 5431 8DE4 E3A8 4AA7 737D 20BE 0DB8 4F03 BD39Mike Socks (I’m WIRED) Are you really sure that you want to sign this keywith your key: Ima User (I’m just ME) Really sign? yYou need a passphrase to unlock the secret key foruser: Ima User (I’m just ME) 1024-bit DSA key, ID D9BAC463, created 2001-01-03Enter passphrase:$

執(zhí)行到此,使用我們的私匙完成了對(duì)Mike的公匙的簽名操作,任何持有我們的公匙的人都可以查證簽名確實(shí)屬于我們自己。這個(gè)附加到Mike的公匙上的簽名信息將隨它環(huán)游Internet世界,我們使用個(gè)人信譽(yù),也就是我們自己的私匙,保證了那個(gè)密匙確實(shí)屬于Mike。這是一個(gè)多么感人的充滿誠(chéng)信的故事啊 :-) 現(xiàn)實(shí)世界的人們是否應(yīng)該從這嚴(yán)格的技術(shù)標(biāo)準(zhǔn)中反思些什么呢?

還是回到這里。獲取附加于一個(gè)公匙上的簽名信息列表的命令是:

gpg –check-sigs mike@hairnet.org

簽名列表越長(zhǎng),密匙的可信度越大。其實(shí),正是簽名系統(tǒng)本身提供了密匙查證功能。假設(shè)我們接收到一個(gè)簽名為Mike的密匙,通過Mike的公匙,我們驗(yàn)證出簽名確實(shí)屬于Mike,那么我們就信任了這個(gè)密匙。推而廣之,我們就可以信任Mike簽名的任何密匙。

為了更加穩(wěn)妥,GPG還引入了另一個(gè)附加功能:可信級(jí)別(trust level)。使用它,我們可以為我們擁有的任何密匙的所有者指定可信級(jí)別。例如,即使我們知道Mike的公匙是可信的,但是事實(shí)上我們不能信任Mike在對(duì)其他密匙簽名時(shí)的判斷;我們會(huì)想,Mike也許只對(duì)少數(shù)密匙進(jìn)行了簽名,但卻沒有好好地檢查一遍。

設(shè)置可信級(jí)別的命令及執(zhí)行情況如下:

$ gpg –edit-key mike@hairnet.orgpub 1024D/4F03BD39 created: 2001-01-15 expires: never trust: -/fsub 1024g/FDBB477D created: 2001-01-15 expires: never(1) Mike Socks (I’m WIRED) Command> trust 1 = Don’t know 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully s = please show me more information m = back to the main menuYour decision? 2Command> quit$

在命令編輯環(huán)境中執(zhí)行trust,然后選擇級(jí)別2(I do NOT trust),這樣我們割斷了任何信任鏈,使每個(gè)密匙都必須經(jīng)過Mike的簽名。

6.刪除密鑰

從私鑰鑰匙環(huán)里刪除密鑰:

# gpg –delete-secret-keys hyphenwang@redflag-linux.com
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

 

sec  1024D/A3942296 2008-12-19 Hyphen Wang (Use for GPG Encrypt) <gpgencrypt@linuxfly.org>

要從鑰匙環(huán)里刪除這把密鑰嗎?(y/N)y
這是一把私鑰!――真的要?jiǎng)h除嗎?(y/N)y

必須先刪除私鑰,然后才能刪除公鑰。
從公鑰鑰匙環(huán)里刪除密鑰:

# gpg –delete-keys hyphenwang@redflag-linux.com
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

 

sec  1024D/A3942296 2008-12-19 Hyphen Wang (Use for GPG Encrypt) <gpgencrypt@linuxfly.org>

要從鑰匙環(huán)里刪除這把密鑰嗎?(y/N)y

三.對(duì)稱加密:

當(dāng)然GPG同樣具備普通的對(duì)稱加密功能,這時(shí)候就不需要密鑰,直接用密碼加密即可(注意,這里的密碼不一定是你私鑰的密碼,您大可以隨意設(shè)定)

gpg -o doc.gpg -c doc

---------------------------------------------

四.GPG常用參數(shù):

語法:gpg [選項(xiàng)] [文件名]
簽字、檢查、加密或解密
默認(rèn)的操作依輸入數(shù)據(jù)而定

指令:

-s, –sign [文件名]           生成一份簽字
–clearsign [文件名]      生成一份明文簽字
-b, –detach-sign             生成一份分離的簽字
-e, –encrypt                 加密數(shù)據(jù)
-c, –symmetric               僅使用對(duì)稱加密
-d, –decrypt                 解密數(shù)據(jù)(默認(rèn))
–verify                  驗(yàn)證簽字
–list-keys               列出密鑰
–list-sigs               列出密鑰和簽字
–check-sigs              列出并檢查密鑰簽字
–fingerprint             列出密鑰和指紋
-K, –list-secret-keys        列出私鑰
–gen-key                 生成一副新的密鑰對(duì)
–delete-keys             從公鑰鑰匙環(huán)里刪除密鑰
–delete-secret-keys      從私鑰鑰匙環(huán)里刪除密鑰
–sign-key                為某把密鑰添加簽字
–lsign-key               為某把密鑰添加本地簽字
–edit-key                編輯某把密鑰或?yàn)槠涮砑雍炞?br /> –gen-revoke              生成一份吊銷證書
–export                  導(dǎo)出密鑰
–send-keys               把密鑰導(dǎo)出到某個(gè)公鑰服務(wù)器上
–recv-keys               從公鑰服務(wù)器上導(dǎo)入密鑰
–search-keys             在公鑰服務(wù)器上搜尋密鑰
–refresh-keys            從公鑰服務(wù)器更新所有的本地密鑰
–import                  導(dǎo)入/合并密鑰
–card-status             打印卡狀態(tài)
–card-edit               更改卡上的數(shù)據(jù)
–change-pin              更改卡的 PIN
–update-trustdb          更新信任度數(shù)據(jù)庫
–print-md 算法 [文件]    使用指定的散列算法打印報(bào)文散列值

選項(xiàng):

-a, –armor                   輸出經(jīng) ASCII 封裝
-r, –recipient 某甲          為收件者“某甲”加密
-u, –local-user              使用這個(gè)用戶標(biāo)識(shí)來簽字或解密
-z N                          設(shè)定壓縮等級(jí)為 N (0 表示不壓縮)
–textmode                使用標(biāo)準(zhǔn)的文本模式
-o, –output                  指定輸出文件
-v, –verbose                 詳細(xì)模式
-n, –dry-run                 不做任何改變
-i, –interactive             覆蓋前先詢問
–openpgp                 行為嚴(yán)格遵循 OpenPGP 定義
–pgp2                    生成與 PGP 2.x 兼容的報(bào)文

(請(qǐng)參考在線說明以獲得所有命令和選項(xiàng)的完整清單)

范例:

-se -r Bob [文件名]          為 Bob 這個(gè)收件人簽字及加密
–clearsign [文件名]         做出明文簽字
–detach-sign [文件名]       做出分離式簽字
–list-keys [某甲]           顯示密鑰
–fingerprint [某甲]         顯示指紋

———————————————————————————–



蜂鳥 2011-04-23 22:55 發(fā)表評(píng)論
]]>
GPG 簡(jiǎn)單使用http://www.aygfsteel.com/alancxx/articles/GPG.html蜂鳥蜂鳥Sat, 23 Apr 2011 14:39:00 GMThttp://www.aygfsteel.com/alancxx/articles/GPG.htmlhttp://www.aygfsteel.com/alancxx/comments/348893.htmlhttp://www.aygfsteel.com/alancxx/articles/GPG.html#Feedback0http://www.aygfsteel.com/alancxx/comments/commentRss/348893.htmlhttp://www.aygfsteel.com/alancxx/services/trackbacks/348893.html

The GNU Privacy Guard

Private和public的鑰匙是gpg加密和解密過程的主要部分,所以第一步就是創(chuàng)建為自己創(chuàng)建一對(duì)密匙.

  1. 生成私鑰

    $gpg --gen-key

    你需要回答一些這個(gè)命令提出的問題

    1. 私鑰的種類和size,這里缺省的答案已經(jīng)足夠好了

    2. 私鑰的有效期,我通常選擇不會(huì)過期,呵呵

    3. 你的真實(shí)的姓名和e-mail地址,這些是用來從一大堆鑰匙中找到你的鑰匙的

    4. 關(guān)于你的鑰匙的comment,可以為空,我一般填一個(gè)昵稱

    5. 鑰匙的密碼. 千萬別忘了,否則所有你加密過的文件都沒用了

  2. 為你的私鑰生成一個(gè)公鑰(文本文件),這是我的:aubrey.asc.zip

    $ gpg --armor --output public.key --export <your email>

    你可以分發(fā)這個(gè)文件了,給你的朋友,或者貼到你的個(gè)人網(wǎng)站上, or whatever.

  3. 為自己加密一個(gè)文件. 這里--recipient可以是你的全名,也可以是你的郵件地址
    #gpg --encrypt --recipient 'Your Name' foo.txt
  4. 密這個(gè)文件. 這里不加--output選項(xiàng)的話,解密的內(nèi)容將被送到屏幕上
    #gpg --output foo.txt --decrypt foo.txt.gpg
  5. 別人加密一個(gè)文件. 這里首先要import別人的公鑰,然后加密。注意這里變化的只是--recipient選項(xiàng)
    #gpg --import key.asc
    #gpg --list-keys
    #gpg --encrypt --recipient 'myfriend@his.isp.net' foo.txt

  6. 解密一個(gè)從別人那里發(fā)來的文件. 這個(gè)和本機(jī)加密的文件解密沒什么區(qū)別.
    #gpg --output foo.txt --decrypt foo.txt.gpg          



蜂鳥 2011-04-23 22:39 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 琼结县| 五莲县| 河北区| 汕头市| 阳西县| 溧水县| 视频| 滨海县| 新竹县| 舞钢市| 都江堰市| 准格尔旗| 淮滨县| 泉州市| 贵州省| 象州县| 兴义市| 班戈县| 扶沟县| 临沭县| 娱乐| 蓬安县| 大同县| 嘉峪关市| 岳阳县| 章丘市| 涞源县| 汉源县| 白沙| 锦屏县| 永嘉县| 水富县| 济南市| 仙桃市| 类乌齐县| 滁州市| 水城县| 建水县| 金阳县| 英山县| 兴安县|