﻿<?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-闵毓</title><link>http://www.blogjava.net/shmily432685/</link><description>http://www.eshoo.com.cn &lt;a title="欢迎来到异客中国" href="http://www.eshoo.com.cn"&gt;欢迎来到异客中国&lt;/a&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 30 Apr 2026 06:24:06 GMT</lastBuildDate><pubDate>Thu, 30 Apr 2026 06:24:06 GMT</pubDate><ttl>60</ttl><item><title>SVN服务器配置</title><link>http://www.blogjava.net/shmily432685/archive/2011/07/12/354203.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Tue, 12 Jul 2011 14:19:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2011/07/12/354203.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/354203.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2011/07/12/354203.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/354203.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/354203.html</trackback:ping><description><![CDATA[<div>
<div>
<div>
<h3 pre=""  fs1"="">原文出处：http://blog.163.com/air-blue55/blog/static/9708657020105612454398/<br />
</h3>
<font  size="3"><strong><br />
</strong></font></div>
</div>
</div>
<div></div>
<div fc05="" fc11="" nbw-blog="" ztag=""  js-fs2"="">
<p>有两种方案：<br />
<br />
<strong>* VisualSVN Server，安装更简单、更直观：</strong><font color="#0060bf">http://www.visualsvn.com/server/download/</font><strong><br />
<br />
*&nbsp;</strong><strong>传统的Subversion&nbsp;服务器程序：<br />
</strong>一、准备工作<br />
<br />
1、获取<strong>&nbsp;Subversion&nbsp;</strong>服务器程序<br />
<br />
到官方网站（http://subversion.tigris.org/）下载最新的服务器安装程序。目前最新的是1.5版本，具体下载地址在：<font color="#0060bf">http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100&amp;expandFolder=8100&amp;folderID=91</font><br />
<br />
<br />
2、获取&nbsp;<strong>TortoiseSVN&nbsp;</strong>客户端程序<br />
<br />
从官方网站&nbsp;<font color="#0060bf">http://tortoisesvn.net/downloads</font>&nbsp;获取最新的&nbsp;TortoiseSVN&nbsp;。TortoiseSVN&nbsp;是一个客户端程序，用来与&nbsp;subvers&nbsp;服务器端通讯。Subversion&nbsp;自带一个客户端程序&nbsp;svn.exe ,但&nbsp;TortoiseSVN&nbsp;更好操作，提高效率。<br />
<br />
<br />
二、安装服务器端和客户端<br />
<br />
安装&nbsp;Subversion（以下简称SVN）的服务器端和客户端。下载下来的服务器端是个&nbsp;zip&nbsp;压缩包，直接解压缩即可，比如我解压到E:\subversion&nbsp;。客户端安装文件是个&nbsp;exe&nbsp;可执行文件，直接运行按提示安装即可，客户端安装完成后提示重启。<br />
<br />
<br />
三、建立版本库（Repository）<br />
<br />
运行Subversion服务器需要首先要建立一个版本库（Repository）。版本库可以看作是服务器上集中存放和管理数据的地方。<br />
<br />
开始建立版本库。首先建立&nbsp;e:\svn&nbsp;空文件夹作为所有版本库的根目录。然后，<strong>进入命令行并切换到</strong><strong>subversion的bin目录。输入如下命令：</strong><br />
<br />
<strong>svnadmin create E:\svn\repos1</strong><br />
<br />
此命令在&nbsp;E:\svn&nbsp;下建立一个版本库&nbsp;repos1&nbsp;。repos1&nbsp;下面会自动生成一些文件夹和文件。<br />
<br />
我们也可以使用&nbsp;TortoiseSVN&nbsp;图形化的完成这一步：<br />
<br />
先建立空目录&nbsp;E:\svn\repos1&nbsp;，注意一定是要空的。然后在&nbsp;repos1&nbsp;文件夹上&#8220;<strong>右键-&gt;TortoiseSVN-&gt;Create Repository here</strong>...&#8221;，然后可以选择版本库模式，这里使用默认的FSFS即可，然后就创建了一系列文件夹和文件，同命令行建立的一样。<br />
<br />
<br />
<br />
四、运行独立服务器<br />
<br />
此时&nbsp;subversion&nbsp;服务还没有开始，只是通过它的命令建立了版本库。继续在刚才的命令窗口输入：<br />
<br />
svnserve.exe --daemon<br />
<br />
svnserve&nbsp;将会在端口&nbsp;3690&nbsp;等待请求，--daemon（两个短横线）选项告诉&nbsp;svnserve&nbsp;以守护进程方式运行，这样在手动终止之前不会退出。注意不要关闭命令行窗口，关闭窗口会把&nbsp;svnserve&nbsp;停止。<br />
<br />
为了验证svnserve正常工作，使用TortoiseSVN -&gt; Repo-browser&nbsp;来查看版本库。在弹出的&nbsp;URL&nbsp;对话框中输入：<br />
<br />
svn://localhost/svn/repos1<br />
<br />
点&nbsp;OK&nbsp;按钮后就可以看见&nbsp;repos1&nbsp;版本库的目录树结构了，只不过这时&nbsp;repos1&nbsp;是个空库。<br />
<br />
你也可以使用--root选项设置根位置来限制服务器的访问目录，从而增加安全性和节约输入svnserve URL的时间：<br />
<br />
<strong>svnserve.exe --daemon --root drive:\path\to\repository</strong><br />
<br />
以前面的测试作为例，svnserve&nbsp;将会运行为：<br />
eg:<br />
<strong>svnserve.exe --daemon --root e:\svn</strong><br />
<br />
然后TortoiseSVN中的版本库浏览器URL缩减为：<br />
<br />
<u>svn://localhost/repos1</u></p>
<p><u></u>&nbsp;</p>
<p><u></u>&nbsp;</p>
<p><font color="#000000">==svn开机自启动=====================<o p=""></o></font></p>
<p><font color="#000000">创建autoRunSVN.bat文件，内容是：<o p=""></o></font></p>
<p><o p=""><font color="#000000">&nbsp;</font></o></p>
<p><font color="#000000">Cpp代码<o p=""></o></font></p>
<p><font color="#000000">sc create MySVNServer binpath= "\"C:\Program Files\Subversion\svnserve\svnserve\" --service -r H:\homerepos" displayname= "SVNService" depend= Tcpip start= auto&nbsp;&nbsp;<o p=""></o></font></p>
<p><font color="#000000">pause&nbsp;<o p=""></o></font></p>
<p><strong>sc create MySVNServer binpath= "\"J:\java\Subversion\bin\svnserve.exe" --service -r \"G:\svn repository\"" displayname= "SVNService" depend= Tcpip start= auto<o p=""></o></strong></p>
<p><font color="#000000">pause<strong><o p=""></o></strong></font></p>
<p><font color="#000000">&nbsp;注意之处：<o p=""></o></font></p>
<p><font color="#000000">（1）sc是windows自带的服务配置程序，MySVNServer&nbsp;是服务的名称，似乎没什么用。<o p=""></o></font></p>
<p><o p=""><font color="#000000">&nbsp;</font></o></p>
<p><font color="#000000">（2）参数binPath表示svnserve可执行文件的安装路径，由于路径中的"Program Files"带有空格，因此整个路径需要用双引号引起来。而双引号本身是个特殊字符，需要进行转义，因此在路径前后的两个双引号都需要写成\"&nbsp;。<o p=""></o></font></p>
<p><font color="#000000">（3）--service参数表示以windows服务的形式运行，--r指明svn repository的位置，service参数与r参数都作为binPath的一部分，因此与svnserve.exe的路径一起被包含在一对双引号当中，而这对双引号不需要进行转义。<o p=""></o></font></p>
<p><o p=""><font color="#000000">&nbsp;</font></o></p>
<p><font color="#000000">（4）displayname表示在windows服务列表中显示的名字，&nbsp;depend =Tcpip&nbsp;表示svnserve服务的运行需要tcpip服务，start=auto表示开机后自动运行。安装服务后，svnserve要等下次开机时才会自动运行。&nbsp;（5）binPath的等号前面无空格，等号后面有空格&nbsp;displayname depend start也都一样<o p=""></o></font></p>
<p><font color="#000000">service前面是--，不是-&nbsp;，而r前面是-<o p=""></o></font></p>
<p><font color="#000000">（6）若要卸载svn服务，则执行&nbsp;sc delete svnserve&nbsp;即可。&nbsp;<o p=""></o></font></p>
<p><o p=""><font color="#000000">&nbsp;</font></o></p>
<p><font color="#000000">（7）从&#8220;sc&#8221;到&#8220;auto&#8221;是在同一个命令sc，必须写在同一行。<o p=""></o></font></p>
<p><o p=""><font color="#000000">&nbsp;</font></o></p>
<p><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;创建成功后，可以在运行中键入service.msc察看系统服务，找到SVNService项，查看这项服务的属性，可以使用Windows提供的界面操作SVNService服务了。</font><o p=""></o></p>
<p>&nbsp;</p>
<p><strong>P.S. 经本人实验，以上的SVN开机自启动方法一直无法实现，由于不会写批处理语句，也不知道是哪里错，但网上很多地方都是用这种方法去实现&nbsp; 开机自启动。最后，只能重新找了一种新方法，虽然无法开机自启动，但可以较方便实现多个服务进程和管理多个文件夹，请各位自行选择。</strong></p>
<p><font color="#000000">创建SVNService.bat文件，内容如下（尊重作者版权，请勿删除作者信息）：</font></p>
<font color="#000000"></font>
<p>&nbsp;</p>
<p>@ECHO OFF<br />
::======================================================================<br />
::作者&nbsp;&nbsp;&nbsp;&nbsp; : Zealic<br />
::版本&nbsp;&nbsp;&nbsp;&nbsp; : 1.05<br />
::功能&nbsp;&nbsp;&nbsp;&nbsp; : 通过简便快捷的方式安装 Subversion.<br />
::最后更新 : 2007-12-28<br />
::======================================================================<br />
::初始化环境<br />
::======================================================================</p>
<p>&nbsp;</p>
<p>ECHO *** 安装 Subversion 服务 ***</p>
<p>::======================================================================<br />
::======================================================================<br />
::创建服务<br />
::======================================================================<br />
ECHO +++ 创建资源库服务 +++<br />
ECHO 创建系统服务，这需要输入一些信息...</p>
<p>:INPUT_SVC_NAME<br />
SET /P svc_name=请输入服务名&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;<br />
::服务名不能为空值<br />
if "%svc_name%" == "" (<br />
&nbsp; ECHO 服务名不能为空，请重新输入。<br />
&nbsp; GOTO INPUT_SVC_NAME<br />
)<br />
::查询服务是否存在，通过查找输出是否存在错误，"1060:"是发生错误是时输出的错误代码。<br />
SC QUERY "%svc_name%" | find "1060:" &gt;&gt; NUL<br />
IF %errorlevel% == 1 (<br />
&nbsp; ECHO 服务 "%svc_name%" 已经存在！请重新输入服务名。<br />
&nbsp; GOTO INPUT_SVC_NAME<br />
)<br />
ECHO.</p>
<p>::输入资源库信息<br />
:INPUT_REPOS<br />
SET /P&nbsp;&nbsp;&nbsp; repos=请输入资源库路径 :&nbsp;<br />
ECHO.</p>
<p>::创建服务<br />
ECHO 您使用以下信息创建 Subversion 服务 :&nbsp;<br />
ECHO 服务名称&nbsp;&nbsp; : "%svc_name%"<br />
ECHO 资源库路径 : "%repos%"<br />
ECHO 正在创建服务...<br />
SC create %svc_name% binPath= "\"E:\Subversion\bin\svnserve.exe\" --service -r \"%repos%\"" depend= Tcpip start= auto| find "1060:" &gt;&gt; NUL<br />
ECHO.<br />
IF %errorlevel% == 0 GOTO SC_ERROR<br />
ECHO --- 创建服务成功! ---<br />
ECHO.<br />
ECHO.</p>
<p>::======================================================================<br />
::生成操作批处理文件<br />
::======================================================================<br />
ECHO +++ 生成服务操作批处理 +++<br />
ECHO 服务操作批处理文件可以帮助您快速操作服务。<br />
SET bat_delete=DELETE_%svc_name%.BAT<br />
SET bat_start=START_%svc_name%.BAT<br />
SET bat_stop=STOP_%svc_name%.BAT<br />
ECHO 生成删除服务批处理 "%bat_delete%" ...<br />
::bat_delete<br />
ECHO @ECHO OFF&gt; %bat_delete%<br />
ECHO NET STOP %svc_name%&gt;&gt; %bat_delete%<br />
ECHO SC delete %svc_name%&gt;&gt; %bat_delete%<br />
ECHO DEL %bat_start%&gt;&gt; %bat_delete%<br />
ECHO DEL %bat_stop%&gt;&gt; %bat_delete%<br />
ECHO DEL %bat_delete%&gt;&gt; %bat_delete%<br />
ECHO PAUSE&gt;&gt; %bat_delete%<br />
::bat_start<br />
ECHO 生成运行服务批处理 "%bat_start%" ...<br />
ECHO @ECHO OFF&gt; %bat_start%<br />
ECHO NET START %svc_name%&gt;&gt; %bat_start%<br />
ECHO PAUSE&gt;&gt; %bat_start%<br />
::bat_stop<br />
ECHO 生成停止服务批处理 "%bat_stop%" ...<br />
ECHO @ECHO OFF&gt; %bat_stop%<br />
ECHO NET STOP %svc_name%&gt;&gt; %bat_stop%<br />
ECHO PAUSE&gt;&gt; %bat_stop%<br />
ECHO.<br />
ECHO --- 生成服务操作批处理成功! ---<br />
ECHO.<br />
ECHO.</p>
<p>::======================================================================<br />
::Finish<br />
::======================================================================<br />
ECHO ### 所有操作成功! ###<br />
GOTO END</p>
<p>::======================================================================<br />
::错误段<br />
::======================================================================<br />
:ENV_ERROR<br />
ECHO --- 设置环境变量失败! ---<br />
GOTO END</p>
<p>:SC_ERROR<br />
ECHO --- 创建服务失败! ---<br />
GOTO END</p>
<p>:SC_INV_PORT<br />
ECHO 无效的端口号，请重新输入。<br />
GOTO INPUT_SVC_PORT</p>
<p>:END<br />
PAUSE</p>
<p><font color="#000000">其中<font color="#ff0000">SC create %svc_name% binPath= "\"E:\Subversion\bin\svnserve.exe\" --service -r \"%repos%\"" depend= Tcpip start= auto| find "1060:" &gt;&gt; NUL</font><font color="#000000">需要将binpath改为svnserve.exe所在路径，之后就可以运行服务了。</font></font></p>
<p><font color="#000000"></font>&nbsp;</p>
<font color="#000000">
<p>五、配置用户和权限<br />
<br />
用文本编辑器打开E:\svn\repos1\conf目录，修改<strong>svnserve.conf</strong>：<br />
<br />
将：<br />
<br />
# password-db = passwd<br />
<br />
改为：<br />
<br />
password-db = passwd<br />
<br />
<strong>即去掉前面的</strong><strong>&nbsp;#&nbsp;</strong><strong>注释符，注意前面不能有空格。</strong><br />
<br />
然后修改同目录的<strong>passwd</strong>文件，增加一个帐号：<br />
<br />
将：<br />
<br />
[users]<br />
# harry = harryssecret<br />
# sally = sallyssecret<br />
<br />
<strong>增加帐号：</strong><strong><br />
</strong><br />
[users]<br />
#harry = harryssecret<br />
#sally = sallyssecret<br />
test = test<br />
<br />
<br />
六、初始化导入<br />
<br />
下面就是将我们的数据（项目）导入到这个版本库，以后就由版本库管理我们的数据。我们的任何改动都回被版本库记录下来，甚至我们自己丢失、改错数据时版本库也能帮我们找回数据。<br />
<br />
比如，我在&nbsp;d:\wwwroot&nbsp;下有个&nbsp;guestbook&nbsp;文件夹，里面存放的是我编写的留言簿程序。在此文件夹上&#8220;右键&nbsp;-&gt; TortoiseSVN -&gt; Import...&#8221;&nbsp;，在弹出对话框的&#8220;URL of repository&#8221;输入&#8220;svn://localhost/repos1/guestbook&#8221;。在&#8220;Import message&#8221;输入&#8220;导入整个留言簿&#8221;作为注释。<br />
点&nbsp;OK&nbsp;后要求输入帐号。我们在用户名和密码处都输入&nbsp;test&nbsp;。完成后&nbsp;guestbook&nbsp;中的内容全部导入到了&nbsp;svn://localhost/svn/repos1/guestbook&nbsp;。<br />
<br />
我们看到在&nbsp;e:\svn\repos1&nbsp;没有任何变化，连个&nbsp;guestbook&nbsp;文件夹都没有建立，唯一的变化就是e:\svn\repos1容量变大了。实际上我们源guestbook中的内容已经导入&nbsp;repos1&nbsp;版本库了，源&nbsp;guestbook&nbsp;文件夹可以删除了。<br />
<br />
需要注意的是，这一步操作可以完全在另一台安装了&nbsp;TortoiseSVN&nbsp;的客户机上进行。例如运行svnserve的主机的IP是133.96.121.22，则URL部分输入的内容就是&#8220;svn://133.96.<st1 tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="121.22" unitname="&#8221;" wst="on" chmetcnv="">121.22&#8221;&nbsp;</st1>。<br />
<br />
<br />
七、基本操作流程<br />
<br />
1、取出（check out）<br />
<br />
取出版本库到一个工作拷贝：<br />
<br />
来到任意空目录下，比如在f分区建立一个空文件夹&nbsp;f:\work&nbsp;。&#8220;右键&nbsp;-&gt; SVN Checkout&#8221;。在&#8220;URL of repository&#8221;中输入&#8220;svn://localhost/svn/repos1/guestbook&#8221;，这样我们就得到了一份&nbsp;guestbook&nbsp;中内容的工作拷贝。<br />
<br />
2、存入（check in）/提交（commit）<br />
<br />
在工作拷贝中作出修改并提交：<br />
<br />
在&nbsp;guestbook&nbsp;工作拷贝中随便打开一个文件，作出修改，然后&#8220;右键&nbsp;-&gt; SVN Commit... &#8221;。这样我们就把修改提交到了版本库，版本库根据情况存储我们提交的数据。<br />
<br />
在修改过的文件上&#8220;右键&nbsp;-&gt; TortoiseSVN -&gt; Show Log&#8221;&nbsp;，可以看到对这个文件所有的提交。在不同的&nbsp;revision&nbsp;条目上&#8220;右键&nbsp;-&gt; Compare with working copy&#8221;，我们可以比较工作拷贝的文件和所选&nbsp;revision&nbsp;版本的区别。</p>
</font></div>
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);<img src ="http://www.blogjava.net/shmily432685/aggbug/354203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2011-07-12 22:19 <a href="http://www.blogjava.net/shmily432685/archive/2011/07/12/354203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>产品介绍，煤矿专用虹膜考勤机</title><link>http://www.blogjava.net/shmily432685/archive/2010/10/21/335800.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Thu, 21 Oct 2010 08:42:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2010/10/21/335800.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/335800.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2010/10/21/335800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/335800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/335800.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p><span style="font-family: simsun"><span style="font-size: 14pt"><span style="color: #ff6600"><strong>一、矿用考勤普遍存在的问题</strong></span></span></span></p>
<ul>
    <li><span style="font-size: 12pt">您是否还在为井下人员数量不准确而发愁吗？</span>
    <li><span style="font-size: 12pt">您是否还在为考勤代打卡而发愁吗？</span>
    <li><span style="font-size: 12pt">您是否还在为考勤受外界环境的影响而发愁吗？</span></li>
</ul>
<p><span style="font-size: 14pt"><span style="color: #ff6600"><strong><span style="font-family: simsun">二、艾特永益矿用虹膜考勤机简介</span></strong></span></span></p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; 艾特永益矿用虹膜考勤机为您解决一切烦恼，目前市场上广泛采用的磁卡，IC卡，射频卡等问题无法解决替代性问题，而指纹、人脸识别等生物识别技术，也因为识别精度不够，指纹容易损伤、先天指纹不清、下井人员面部因素、设备维护困难等问题不能满足需要。<br />
&nbsp;&nbsp;&nbsp; 而虹膜识别考勤系统可以从根本上杜绝公司考勤时有人替打卡现象，手指和人脸因矿井的外在因素影响，而且识别率很高。<br />
&nbsp;&nbsp;&nbsp; 并且虹膜考勤系统有着以下几方面的优点：<br />
&nbsp;&nbsp;&nbsp; 1、 虹膜识别技术免接触，不可以篡改，安全性高，<br />
&nbsp;&nbsp;&nbsp; 2、 正常状态下的虹膜识别速度在1秒左右。<br />
&nbsp;&nbsp;&nbsp; 3、 统计虹膜识别考勤数据快捷，不需人工统计。<br />
&nbsp;&nbsp;&nbsp; 4、 产品先进，虹膜身份识别技术是目前所有生物识别技术里安全性，唯一性最高的人体生物识别技术。使用上已经非常方便可靠，所以投资一步到位，操作简单，使用寿命长。</span></p>
<p><span style="font-size: 12pt">&nbsp;我们为您提供最优质的服务，根据您的具体要求，与各种其他系统结合（比如智能卡），完全实现订制。</span></p>
<p><span style="font-family: simsun"><span style="font-size: 14pt"><span style="color: #ff6600"><strong>三、配套考勤软件</strong></span></span></span></p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; 考勤系统的目的是为实现员工考勤数据采集、数据统计和信息查询过程的自动化，完善人事管理现代化，方便员工上班报到，方便管理人员统计、考核员工出勤情况，方便管理部门查询、考核各部门出勤率；准确地掌握员工出勤情况，有效地管理、掌握人员流动情况，适用于机关﹑金融和各企事业单位。<br />
&nbsp;&nbsp;&nbsp; 考勤基本功能<br />
&nbsp;&nbsp;&nbsp; 1. 员工上下班的数据，经考勤软件从门禁数据库采集，为原始考勤数据的来源。<br />
&nbsp;&nbsp;&nbsp; 2. 统计：统计系统将个人的信息进行过滤处理，只保留每天考勤记录，然后按员工姓名、日期或其他分类方式进行统计，生成各类报表。<br />
&nbsp;&nbsp;&nbsp; 3. 查询：可根据需要随时在查询系统查询各员工的上下班、出勤缺勤等情况，并可随时打印出来。<br />
&nbsp;&nbsp;&nbsp; 4. 考勤管理：系统允许系统管理员进行系统设置。设置包括每次采集的有效时间段设置，迟到、早退、旷工的时间设置等。如提前多少时间上班有效，早退多少时间是旷工等。用户可以根据自己的实际情况，进行设置。可根据公司的制度设定迟到、早退、旷工的条件。<br />
&nbsp;&nbsp;&nbsp; 5. 员工管理：每位员工都有较详细的信息，包括员工编号、部门、职位等。<br />
&nbsp;&nbsp;&nbsp; 6. 无人值守考勤：记录任何非法出入信息及图像，及时记录于机器硬盘上，断电仍可保证记录安全储存。</span></p>
<p><span style="font-size: 12pt"><br class="img-brk" />
<br class="img-brk" />
<img style="width: 724px; height: 981px; visibility: visible" alt="" src="http://i00.c.aliimg.com/img/ibank/2010/798/240/191042897_802525787.jpg" /><br class="img-brk" />
<br class="img-brk" />
<span style="font-size: 12pt"><img style="width: 724px; height: 981px; visibility: visible" alt="" src="http://i00.c.aliimg.com/img/ibank/2010/667/240/191042766_802525787.jpg" /></span></span></p><img src ="http://www.blogjava.net/shmily432685/aggbug/335800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2010-10-21 16:42 <a href="http://www.blogjava.net/shmily432685/archive/2010/10/21/335800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java: JNI完全手册</title><link>http://www.blogjava.net/shmily432685/archive/2008/11/09/239528.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Sun, 09 Nov 2008 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2008/11/09/239528.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/239528.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2008/11/09/239528.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/239528.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/239528.html</trackback:ping><description><![CDATA[<a href="http://www.pconline.com.cn/pcedu/empolder/gj/java/0506/642328.html">出处 http://www.pconline.com.cn/pcedu/empolder/gj/java/0506/642328.html</a><br />
JAVA以其跨平台的特性深受人们喜爱，而又正由于它的跨平台的目的，使得它和本地机器的各种内部联系变得很少，约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。<br />
　　JAVA通过JNI调用本地方法，而本地方法是以库文件的形式存放的（在WINDOWS平台上是DLL文件形式，在UNIX机器上是SO文件形式）。通过调用本地的库文件的内部方法，使JAVA可以实现和本地机器的紧密联系，调用系统级的各接口方法。<br />
<br />
　　简单介绍及应用如下： <br />
　　一、JAVA中所需要做的工作 <br />
　　在JAVA程序中，首先需要在类中声明所调用的库(.dll)名称，如下： <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"><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;{&nbsp;<br />
System.loadLibrary(&#8220;goodluck&#8221;);&nbsp;<br />
}</span></div>
在这里，库的扩展名字可以不用写出来，究竟是DLL还是SO，由系统自己判断。 <br />
<br />
　　还需对将要调用的方法做本地声明，关键字为native。且只需要声明，而不需要具体实现。如下： <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"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</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;set(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i);&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;get();</span></div>
然后编译该JAVA程序文件，生成CLASS，再用JAVAH命令，JNI就会生成C/C++的头文件。 <br />
<br />
　　例如程序testdll.java，内容为：<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"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;testdll&nbsp;<br />
{&nbsp;<br />
</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;<br />
{&nbsp;<br />
System.loadLibrary(</span><span style="color: #000000">"</span><span style="color: #000000">goodluck</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
}&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;get();&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</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;set(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i);&nbsp;<br />
</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;<br />
{&nbsp;<br />
testdll&nbsp;test&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;testdll();&nbsp;<br />
test.set(</span><span style="color: #000000">10</span><span style="color: #000000">);&nbsp;<br />
System.out.println(test.get());&nbsp;<br />
}&nbsp;<br />
}</span></div>
用javac testdll.java编译它，会生成testdll.class。 <br />
　　再用javah testdll，则会在当前目录下生成testdll.h文件，这个文件需要被C/C++程序调用来生成所需的库文件。 <br />
<br />
　　二、C/C++中所需要做的工作 <br />
　　对于已生成的.h头文件，C/C++所需要做的，就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面，就可以用JAVA调用C/C++所实现的功能了。 <br />
　　接上例子。我们先看一下testdll.h文件的内容：<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"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#include&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Header&nbsp;for&nbsp;class&nbsp;testdll&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#ifndef&nbsp;_Included_testdll&nbsp;<br />
#define&nbsp;_Included_testdll&nbsp;<br />
#ifdef&nbsp;__cplusplus&nbsp;<br />
extern&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">C</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;{&nbsp;<br />
#endif&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;<br />
*&nbsp;Class:&nbsp;testdll&nbsp;<br />
*&nbsp;Method:&nbsp;get&nbsp;<br />
*&nbsp;Signature:&nbsp;()I&nbsp;<br />
</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_testdll_get&nbsp;(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass);&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;<br />
*&nbsp;Class:&nbsp;testdll&nbsp;<br />
*&nbsp;Method:&nbsp;set&nbsp;<br />
*&nbsp;Signature:&nbsp;(I)V&nbsp;<br />
</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
JNIEXPORT&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;JNICALL&nbsp;Java_testdll_set&nbsp;(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass,&nbsp;jint);&nbsp;<br />
#ifdef&nbsp;__cplusplus&nbsp;<br />
}&nbsp;<br />
#endif&nbsp;<br />
#endif</span></div>
　　在具体实现的时候，我们只关心两个函数原型 <br />
　　JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和 <br />
　　JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);<br />
<br />
　　这里JNIEXPORT和JNICALL都是JNI的关键字，表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型，我们可以视而不见，就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中，我们也只需要关心在JAVA程序中存在的参数，至于JNIEnv*和jclass我们一般没有必要去碰它。 <br />
<br />
　　好，下面我们用testdll.cpp文件具体实现这两个函数：<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"><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">testdll.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
</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;<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_testdll_get&nbsp;(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass)&nbsp;<br />
{&nbsp;<br />
</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;i;&nbsp;<br />
}&nbsp;<br />
JNIEXPORT&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;JNICALL&nbsp;Java_testdll_set&nbsp;(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass,&nbsp;jint&nbsp;j)&nbsp;<br />
{&nbsp;<br />
i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;j;&nbsp;<br />
}</span></div>
编译连接成库文件，本例是在WINDOWS下做的，生成的是DLL文件。并且名称要与JAVA中需要调用的一致，这里就是goodluck.dll 。把goodluck.dll拷贝到testdll.class的目录下，java testdll运行它，就可以观察到结果了。 <br />
我的项目比较复杂，需要调用动态链接库，这样在JNI传送参数到C程序时，需要对参数进行处理转换。才可以被C程序识别。<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"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SendSMS&nbsp;{&nbsp;<br />
</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;<br />
{&nbsp;<br />
System.out.println(System.getProperty(</span><span style="color: #000000">"</span><span style="color: #000000">java.library.path</span><span style="color: #000000">"</span><span style="color: #000000">));&nbsp;<br />
System.loadLibrary(</span><span style="color: #000000">"</span><span style="color: #000000">sms</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
}&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsInit();&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">native</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsSend(</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;mobileNo,&nbsp;</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;smContent);&nbsp;<br />
}</span></div>
<br />
在这里要注意的是，path里一定要包含类库的路径，否则在程序运行时会抛出异常：<br />
　　java.lang.UnsatisfiedLinkError: no sms in java.library.path<br />
　　at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)<br />
　　at java.lang.Runtime.loadLibrary0(Runtime.java:788)<br />
　　at java.lang.System.loadLibrary(System.java:834)<br />
　　at com.mobilesoft.sms.mobilesoftinfo.SendSMS.<clinit>(SendSMS.java:14)<br />
　　at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)<br />
　　Exception in thread "main"<br />
<br />
　　指引的路径应该到.dll文件的上一级，如果指到.dll，则会报：<br />
　　java.lang.UnsatisfiedLinkError: C:\sms.dll: Can't find dependent libraries<br />
　　at java.lang.ClassLoader$NativeLibrary.load(Native Method)<br />
　　at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1560)<br />
　　at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1485)<br />
　　at java.lang.Runtime.loadLibrary0(Runtime.java:788)<br />
　　at java.lang.System.loadLibrary(System.java:834)<br />
　　at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)<br />
　　Exception in thread "main"<br />
<br />
　　通过编译，生成com_mobilesoft_sms_mobilesoftinfo_SendSMS.h头文件。（建议使用Jbuilder进行编译，操作比较简单！）这个头文件就是Java和C之间的纽带。要特别注意的是方法中传递的参数jbyteArray，这在接下来的过程中会重点介绍。<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"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#include&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;Header&nbsp;for&nbsp;class&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#ifndef&nbsp;_Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;<br />
#define&nbsp;_Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;<br />
#ifdef&nbsp;__cplusplus&nbsp;<br />
extern&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">C</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;{&nbsp;<br />
#endif&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;<br />
*&nbsp;Class:&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;<br />
*&nbsp;Method:&nbsp;SmsInit&nbsp;<br />
*&nbsp;Signature:&nbsp;()I&nbsp;<br />
</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit&nbsp;<br />
(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass);&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;<br />
*&nbsp;Class:&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;<br />
*&nbsp;Method:&nbsp;SmsSend&nbsp;<br />
*&nbsp;Signature:&nbsp;([B[B)I&nbsp;<br />
</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend&nbsp;<br />
(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;jclass,&nbsp;jbyteArray,&nbsp;jbyteArray);&nbsp;<br />
#ifdef&nbsp;__cplusplus&nbsp;<br />
}&nbsp;<br />
#endif&nbsp;<br />
#endif</span></div>
<br />
对于我要调用的C程序的动态链接库，C程序也要提供一个头文件，sms.h。这个文件将要调用的方法罗列了出来。<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"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;<br />
*&nbsp;SMS&nbsp;API&nbsp;<br />
*&nbsp;Author:&nbsp;yippit&nbsp;<br />
*&nbsp;Date:&nbsp;2004.6.8&nbsp;<br />
</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#ifndef&nbsp;MCS_SMS_H&nbsp;<br />
#define&nbsp;MCS_SMS_H&nbsp;<br />
#define&nbsp;DLLEXPORT&nbsp;__declspec(dllexport)&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">sms&nbsp;storage</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_SIM&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_MT&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">sms&nbsp;states</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_UNREAD&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_READ&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #008000">/*</span><span style="color: #008000">sms&nbsp;type</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_NOPARSE&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_NORMAL&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_FLASH&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;<br />
#define&nbsp;SMS_MMSNOTI&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">&nbsp;<br />
typedef&nbsp;struct&nbsp;tagSmsEntry&nbsp;{&nbsp;<br />
</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index;&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">index,&nbsp;start&nbsp;from&nbsp;1</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;status;&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">read,&nbsp;unread</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;type;&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">-1-can't&nbsp;parser&nbsp;0-normal,&nbsp;1-flash,&nbsp;2-mms</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;storage;&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">SMS_SIM,&nbsp;SMS_MT</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;date[</span><span style="color: #000000">24</span><span style="color: #000000">];&nbsp;<br />
</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;number[</span><span style="color: #000000">32</span><span style="color: #000000">];&nbsp;<br />
</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;text[</span><span style="color: #000000">144</span><span style="color: #000000">];&nbsp;<br />
}&nbsp;SmsEntry;&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsInit(</span><span style="color: #0000ff">void</span><span style="color: #000000">);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsSend(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">phonenum,&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">content);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsSetSCA(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">sca);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsGetSCA(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">sca);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsSetInd(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ind);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsGetInd(</span><span style="color: #0000ff">void</span><span style="color: #000000">);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsGetInfo(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;storage,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">max,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">used);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsSaveFlash(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;flag);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsRead(SmsEntry&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">entry,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;storage,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsDelete(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;storage,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index);&nbsp;<br />
DLLEXPORT&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SmsModifyStatus(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;storage,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index);&nbsp;</span><span style="color: #008000">/*</span><span style="color: #008000">unread&nbsp;-&gt;&nbsp;read</span><span style="color: #008000">*/</span><span style="color: #000000">&nbsp;<br />
#endif</span></div>
在有了这两个头文件之后，就可以进行C程序的编写了。也就是实现对JNI调用的两个方法。在网上的资料中，由于调用的方法实现的都比较简单，（大多是打印字符串等）所以避开了JNI中最麻烦的部分，也是最关键的部分，参数的传递。由于Java和C的编码是不同的，所以传递的参数是要进行再处理，否则C程序是会对参数在编译过程中提出警告，例如；warning C4024: 'SmsSend' : different types for formal and actual parameter 2等。<br />
　　Sms.c的程序如下：<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"><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">sms.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">com_mobilesoft_sms_mobilesoftinfo_SendSMS.h</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;env,&nbsp;jclass&nbsp;jobject)&nbsp;<br />
{&nbsp;<br />
</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;SmsInit();&nbsp;<br />
}&nbsp;<br />
<br />
JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend(JNIEnv&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;env,&nbsp;jclass&nbsp;jobject,&nbsp;jbyteArray&nbsp;mobileno,&nbsp;jbyteArray&nbsp;smscontent)&nbsp;<br />
{&nbsp;<br />
</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pSmscontent&nbsp;;&nbsp;<br />
</span><span style="color: #008000">//</span><span style="color: #008000">jsize&nbsp;theArrayLengthJ&nbsp;=&nbsp;(*env)-&gt;GetArrayLength(env,mobileno);&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #000000">jbyte&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;arrayBody&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">env)</span><span style="color: #000000">-&gt;</span><span style="color: #000000">GetByteArrayElements(env,mobileno,</span><span style="color: #000000">0</span><span style="color: #000000">);&nbsp;<br />
</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pMobileNo&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)arrayBody;&nbsp;<br />
printf(</span><span style="color: #000000">"</span><span style="color: #000000">[%s]\n&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;pMobileNo);&nbsp;<br />
</span><span style="color: #008000">//</span><span style="color: #008000">jsize&nbsp;size&nbsp;=&nbsp;(*env)-&gt;GetArrayLength(env,smscontent);&nbsp;</span><span style="color: #008000"><br />
</span><span style="color: #000000">arrayBody&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">*</span><span style="color: #000000">env)</span><span style="color: #000000">-&gt;</span><span style="color: #000000">GetByteArrayElements(env,smscontent,</span><span style="color: #000000">0</span><span style="color: #000000">);&nbsp;<br />
pSmscontent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">)arrayBody;&nbsp;<br />
printf(</span><span style="color: #000000">"</span><span style="color: #000000">&lt;%s&gt;\n</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;pSmscontent);&nbsp;<br />
</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;SmsSend(pMobileNo,pSmscontent);&nbsp;<br />
}</span></div>
<br />
　对于C或C++，在程序上是会有稍微的不同，这可以由读者对其进行适当的修改。这里要注意的是GetArrayLength，GetByteArrayElements等这些JNI中已经包含的方法，这些方法是专门对转换参数类型而提供的。具体的方法有很多，在下一篇中会做专门的介绍。<br />
　　在完成了上述的文件后，可以对sms.c进行编译，生成.dll文件（建议在release中编译，这样动态链接库的容积会比较小！）<br />
　　完成.dll文件的编译后，就可以在Java中调用C程序中的方法了。例如文件test.java
<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"><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;test&nbsp;{&nbsp;<br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;test()&nbsp;{&nbsp;<br />
}&nbsp;<br />
</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;{&nbsp;<br />
</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;mobileno&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;{&nbsp;<br />
</span><span style="color: #000000">0x31</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x33</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x36</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x36</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x31</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x36</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x33</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x30</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x36</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x36</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x37</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">0x00</span><span style="color: #000000">};&nbsp;<br />
String&nbsp;smscontentemp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">早上好</span><span style="color: #000000">"</span><span style="color: #000000">;&nbsp;<br />
</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;temp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;{</span><span style="color: #000000">0</span><span style="color: #000000">};&nbsp;<br />
</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{&nbsp;<br />
</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;smscontentdb&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;smscontentemp.getBytes(</span><span style="color: #000000">"</span><span style="color: #000000">gbk</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
</span><span style="color: #0000ff">byte</span><span style="color: #000000">[]&nbsp;smscontent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">byte</span><span style="color: #000000">[smscontentdb.length&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;temp.length];&nbsp;<br />
System.arraycopy(smscontentdb,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;smscontent,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;smscontentdb.length);&nbsp;<br />
System.arraycopy(temp,&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;smscontent,&nbsp;smscontentdb.length,&nbsp;temp.length);&nbsp;<br />
SendSMS&nbsp;sendSMS&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SendSMS();&nbsp;<br />
sendSMS.SmsInit();&nbsp;<br />
</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(sendSMS.SmsSend(mobileno,&nbsp;smscontent)&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;{&nbsp;<br />
System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">chenggong&nbsp;!</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
}&nbsp;<br />
</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;{&nbsp;<br />
System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">shibai&nbsp;!</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;<br />
}&nbsp;<br />
}</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;ex)&nbsp;{}&nbsp;<br />
}&nbsp;<br />
}</span></div>
在这个文件中要注意的有一点，就是在传递字节数组到C程序中时，最后的结尾一定要以0结束。这是一个偷懒的做法，不过是个有效的做法。因为大多数情况下，接口是由第三方提供的。所以我们一般是不知道在C的方法里，具体是怎么处理参数的。而C又是要求数组是有长度。所以，在Java中，如果你不想写程序传数组的长度，那么在数组中以0结尾就是最方便的方法了。当然，如果有更好的方法也希望大家提出。<br />
<br />
　　到这里，一个完整的Java通过JNI调用动态链接库的程序就完成了。实际上也不是很复杂。只要多注意一下细节，是很容易得出来的。 <br clear="all" /><img src ="http://www.blogjava.net/shmily432685/aggbug/239528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2008-11-09 16:48 <a href="http://www.blogjava.net/shmily432685/archive/2008/11/09/239528.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载：Java远程通讯可选技术及原理 </title><link>http://www.blogjava.net/shmily432685/archive/2008/03/06/184249.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Thu, 06 Mar 2008 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2008/03/06/184249.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/184249.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2008/03/06/184249.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/184249.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/184249.html</trackback:ping><description><![CDATA[<div class="postText">在分布式服务框架中，一个最基础的问题就是远程服务是怎么通讯的，在Java领域中有很多可实现远程通讯的技术，例如：RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等，这些名词之间到底是些什么关系呢，它们背后到底是基于什么原理实现的呢，了解这些是实现分布式服务框架的基础知识，而如果在性能上有高的要求的话，那深入了解这些技术背后的机制就是必须的了，在这篇blog中我们将来一探究竟，抛砖引玉，欢迎大家提供更多的实现远程通讯的技术和原理的介绍。<br />
<strong style="font-size: 14pt; color: #ff6600"><br />
<span style="font-size: 18pt; color: #008000">基本原理</span></strong><br />
要实现网络机器间的通讯，首先得来看看计算机系统网络通信的基本原理，在底层层面去看，网络通信需要做的就是将流从一台计算机传输到另外一台计算机，基于传输协议和网络IO来实现，其中传输协议比较出名的有http、tcp、udp等等，http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议，网络IO，主要有bio、nio、aio三种方式，所有的分布式应用通讯都基于这个原理而实现，只是为了应用的易用，各种语言通常都会提供一些更为贴近应用易用的应用层协议。<br />
<span style="font-size: 18pt; color: #008000"><strong><br />
应用级协议</strong></span><br />
远程服务通讯，需要达到的目标是在一台计算机发起请求，另外一台机器在接收到请求后进行相应的处理并将结果返回给请求端，这其中又会有诸如one way request、同步请求、异步请求等等请求方式，按照网络通信原理，需要实现这个需要做的就是将请求转换成流，通过传输协议传输至远端，远端计算机在接收到请求的流后进行处理，处理完毕后将结果转化为流，并通过传输协议返回给调用端。<br />
原理是这样的，但为了应用的方便，业界推出了很多基于此原理之上的应用级的协议，使得大家可以不用去直接操作这么底层的东西，通常应用级的远程通信协议会提供：<br />
1、为了避免直接做流操作这么麻烦，提供一种更加易用或贴合语言的标准传输格式；<br />
2、网络通信机制的实现，就是替你完成了将传输格式转化为流，通过某种传输协议传输至远端计算机，远端计算机在接收到流后转化为传输格式，并进行存储或以某种方式通知远端计算机。<br />
所以在学习应用级的远程通信协议时，我们可以带着这几个问题进行学习：<br />
1、传输的标准格式是什么？<br />
2、怎么样将请求转化为传输的流？<br />
3、怎么接收和处理流？<br />
4、传输协议是？<br />
不过应用级的远程通信协议并不会在传输协议上做什么多大的改进，主要是在流操作方面，让应用层生成流和处理流的这个过程更加的贴合所使用的语言或标准，至于传输协议则通常都是可选的，在java领域中知名的有：RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS，来具体的看看这些远程通信的应用级协议：<br />
<strong><strong>--------------------------------------------------------------------------------------------------------------------------------------------------</strong><br />
RMI</strong><br />
RMI是个典型的为java定制的远程通信协议，我们都知道，在single vm中，我们可以通过直接调用java object instance来实现通信，那么在远程通信时，如果也能按照这种方式当然是最好了，这种远程通信的机制成为RPC（Remote Procedure Call），RMI正是朝着这个目标而诞生的。<br />
来看下基于RMI的一次完整的远程通信过程的原理：<br />
1、客户端发起请求，请求转交至RMI客户端的stub类；<br />
2、stub类将请求的接口、方法、参数等信息进行序列化；<br />
3、基于socket将序列化后的流传输至服务器端；<br />
4、服务器端接收到流后转发至相应的skelton类；<br />
5、skelton类将请求的信息反序列化后调用实际的处理类；<br />
6、处理类处理完毕后将结果返回给skelton类；<br />
7、Skelton类将结果序列化，通过socket将流传送给客户端的stub；<br />
8、stub在接收到流后反序列化，将反序列化后的Java Object返回给调用者。<br />
来看jboss-remoting对于此过程的一个更好的图示：<br />
<img height="225" alt="" src="http://www.blogjava.net/images/blogjava_net/bluedavy/jboss-remoting-arch.jpg" width="710" border="0" /><br />
根据原理来回答下之前学习应用级协议带着的几个问题：<br />
1、传输的标准格式是什么？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 是Java ObjectStream。<br />
2、怎么样将请求转化为传输的流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;基于Java串行化机制将请求的java object信息转化为流。<br />
3、怎么接收和处理流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据采用的协议启动相应的监听端口，当有流进入后基于Java串行化机制将流进行反序列化，并根据RMI协议获取到相应的处理对象信息，进行调用并处理，处理完毕后的结果同样基于java串行化机制进行返回。<br />
4、传输协议是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Socket。<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
XML-RPC<br />
</strong>XML-RPC也是一种和RMI类似的远程调用的协议，它和RMI的不同之处在于它以标准的xml格式来定义请求的信息(请求的对象、方法、参数等)，这样的好处是什么呢，就是在跨语言通讯的时候也可以使用。<br />
来看下XML-RPC协议的一次远程通信过程：<br />
1、客户端发起请求，按照XML-RPC协议将请求信息进行填充；<br />
2、填充完毕后将xml转化为流，通过传输协议进行传输；<br />
3、接收到在接收到流后转换为xml，按照XML-RPC协议获取请求的信息并进行处理；<br />
4、处理完毕后将结果按照XML-RPC协议写入xml中并返回。<br />
图示以上过程：<br />
<img height="270" alt="" src="http://www.blogjava.net/images/blogjava_net/bluedavy/xmlrpc.jpg" width="527" border="0" /><br />
同样来回答问题：<br />
1、传输的标准格式是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标准格式的XML。<br />
2、怎么样将请求转化为传输的流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将XML转化为流。<br />
3、怎么接收和处理流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过监听的端口获取到请求的流，转化为XML，并根据协议获取请求的信息，进行处理并将结果写入XML中返回。<br />
4、传输协议是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Http。<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
Binary-RPC<br />
</strong>Binary-RPC看名字就知道和XML-RPC是差不多的了，不同之处仅在于传输的标准格式由XML转为了二进制的格式。<br />
同样来回答问题：<br />
1、传输的标准格式是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标准格式的二进制文件。<br />
2、怎么样将请求转化为传输的流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将二进制格式文件转化为流。<br />
3、怎么接收和处理流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过监听的端口获取到请求的流，转化为二进制文件，根据协议获取请求的信息，进行处理并将结果写入XML中返回。<br />
4、传输协议是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Http。<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
SOAP<br />
</strong>SOAP原意为Simple Object Access Protocol，是一个用于分布式环境的、轻量级的、基于XML进行信息交换的通信协议，可以认为SOAP是XML RPC的高级版，两者的原理完全相同，都是http+XML，不同的仅在于两者定义的XML规范不同，SOAP也是Webservice采用的服务调用协议标准，因此在此就不多加阐述了。<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
CORBA<br />
</strong><font face="arial,sans-serif" color="#000000">Common&nbsp;Object&nbsp;Request&nbsp;Broker&nbsp;Architecture（公用对象请求代理[调度]程序体系结构），是一组用来定义&#8220;分布式对象系统&#8221;的标准，由OMG(Object&nbsp;Menagement&nbsp;Group)作为发起和标准制定单位。CORBA的目的是定义一套协议，符合这个协议的对象可以互相交互，不论它们是用什么样的语言写的，不论它们运行于什么样的机器和操作系统。<br />
</font>CORBA在我看来是个类似于SOA的体系架构，涵盖可选的远程通信协议，但其本身不能列入通信协议这里来讲，而且CORBA基本淘汰，再加上对CORBA也不怎么懂，在此就不进行阐述了。<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
JMS<br />
</strong>JMS呢，是实现java领域远程通信的一种手段和方法，基于JMS实现远程通信时和RPC是不同的，虽然可以做到RPC的效果，但因为不是从协议级别定义的，因此我们不认为JMS是个RPC协议，但它确实是个远程通信协议，在其他的语言体系中也存在着类似JMS的东西，可以统一的将这类机制称为消息机制，而消息机制呢，通常是高并发、分布式领域推荐的一种通信机制，这里的主要一个问题是容错（详细见ErLang论文）。<br />
来看JMS中的一次远程通信的过程：<br />
1、客户端将请求转化为符合JMS规定的Message；<br />
2、通过JMS API将Message放入JMS Queue或Topic中；<br />
3、如为JMS Queue，则发送中相应的目标Queue中，如为Topic，则发送给订阅了此Topic的JMS Queue。<br />
4、处理端则通过轮训JMS Queue，来获取消息，接收到消息后根据JMS协议来解析Message并处理。<br />
回答问题：<br />
1、传输的标准格式是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JMS规定的Message。<br />
2、怎么样将请求转化为传输的流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将参数信息放入Message中即可。<br />
3、怎么接收和处理流？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;轮训JMS Queue来接收Message，接收到后进行处理，处理完毕后仍然是以Message的方式放入Queue中发送或Multicast。<br />
4、传输协议是？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不限。<br />
基于JMS也是常用的实现远程异步调用的方法之一。<br />
<br />
<span style="font-size: 18pt; color: #008000"><strong>可选实现技术</strong></span><br />
当然，在上面的原理中并没有介绍到所有的java领域可选的远程通信协议了，例如还有EJB采用的ORMI、Spring自己定义的一个简单的Http Invoker等等。<br />
看完原理后我们再来看看目前java领域可用于实现远程通讯的框架或library，知名的有：JBoss-Remoting、Spring-Remoting、Hessian、Burlap、XFire(Axis)、ActiveMQ、Mina、Mule、EJB3等等，来对每种做个简单的介绍和评价，其实呢，要做分布式服务框架，这些东西都是要有非常深刻的了解的，因为分布式服务框架其实是包含了解决分布式领域以及应用层面领域两方面问题的。<br />
当然，你也可以自己根据远程网络通信原理(transport protocol+Net IO)去实现自己的通讯框架或library。<br />
那么在了解这些远程通讯的框架或library时，会带着什么问题去学习呢？<br />
1、是基于什么协议实现的？<br />
2、怎么发起请求？<br />
3、怎么将请求转化为符合协议的格式的？<br />
4、使用什么传输协议传输？<br />
5、响应端基于什么机制来接收请求？<br />
6、怎么将流还原为传输格式的？<br />
7、处理完毕后怎么回应？<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
JBoss-Remoting<br />
</strong>Jboss-remoting是由jboss编写的一个java领域的远程通讯框架，基于此框架，可以很简单的实现基于多种传输协议的java对象的RPC。<br />
直接来回答问题：<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JBoss-Remoting是个通讯框架，因此它支持多种协议方式的通信，例如纯粹的socket+io方式、rmi方式、http+io方式等。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在JBoss-Remoting中，只需将需要发起的请求参数对象传入jboss-remoting的InvocationRequest对象即可，也可根据协议基于InvocationRequest封装符合需求的InvocationRequest对象。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JBoss-Remoting基于Java串行化机制或JBoss自己的串行化实现来将请求转化为对象字节流。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持多种传输协议，例如socket、http等。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 响应端只需将自己的处理对象注册到JBoss-Remoting提供的server端的Connector对象中即可。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JBoss-Remoting基于java串行化机制或jboss自己的串行化实现来将请求信息还原为java对象。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处理完毕后将结果对象直接返回即可，jboss-remoting会将此对象按照协议进行序列化，返回至调用端。<br />
另外，jboss-remoting支持多种通信方式，例如同步/异步/单向通信等。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
<a title="心得与体会" href="http://www.blogjava.net/shmily432685/admin/EditPosts.aspx?catid=4001" >spring in action</a>-Remoting<br />
</strong><a title="心得与体会" href="http://www.blogjava.net/shmily432685/admin/EditPosts.aspx?catid=4001" >spring in action</a>-remoting是Spring提供java领域的远程通讯框架，基于此框架，同样也可以很简单的将普通的spring bean以某种远程协议的方式来发布，同样也可以配置spring bean为远程调用的bean。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和JBoss-Remoting一样，作为一个远程通讯的框架，Spring通过集成多种远程通讯的library，从而实现了对多种协议的支持，例如rmi、http+io、xml-rpc、binary-rpc等。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在Spring中，由于其对于远程调用的bean采用的是proxy实现，发起请求完全是通过服务接口调用的方式。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Spring按照协议方式将请求的对象信息转化为流，例如Spring Http Invoker是基于Spring自己定义的一个协议来实现的，传输协议上采用的为http，请求信息是基于java串行化机制转化为流进行传输。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持多种传输协议，例如rmi、http等等。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 响应端遵循协议方式来接收请求，对于使用者而言，则只需通过spring的配置方式将普通的spring bean配置为响应端或者说提供服务端。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;按照协议方式来进行还原。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处理完毕后直接返回即可，spring-remoting将根据协议方式来做相应的序列化。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
Hessian<br />
</strong>Hessian是由caucho提供的一个基于binary-RPC实现的远程通讯library。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于Binary-RPC协议实现。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;需通过Hessian本身提供的API来发起请求。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hessian通过其自定义的串行化机制将请求信息进行序列化，产生二进制流。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hessian基于Http协议进行传输。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 响应端根据Hessian提供的API来接收请求。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hessian根据其私有的串行化机制来将请求信息进行反序列化，传递给使用者时已是相应的请求信息对象了。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 处理完毕后直接返回，hessian将结果对象进行序列化，传输至调用端。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
Burlap<br />
</strong>Burlap也是有caucho提供，它和hessian的不同在于，它是基于XML-RPC协议的。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于XML-RPC协议实现。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据Burlap提供的API。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将请求信息转化为符合协议的XML格式，转化为流进行传输。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Http协议。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 监听Http请求。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据XML-RPC协议进行还原。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回结果写入XML中，由Burlap返回至调用端。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
XFire、Axis<br />
</strong>XFire、Axis是Webservice的实现框架，WebService可算是一个完整的SOA架构实现标准了，因此采用XFire、Axis这些也就意味着是采用webservice方式了。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于SOAP协议。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;获取到远端service的proxy后直接调用。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将请求信息转化为遵循SOAP协议的XML格式，由框架转化为流进行传输。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Http协议。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 监听Http请求。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据SOAP协议进行还原。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回结果写入XML中，由框架返回至调用端。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
ActiveMQ<br />
</strong>ActiveMQ是JMS的实现，基于JMS这类消息机制实现远程通讯是一种不错的选择，毕竟消息机制本身的功能使得基于它可以很容易的去实现同步/异步/单向调用等，而且消息机制从容错角度上来说也是个不错的选择，这是Erlang能够做到容错的重要基础。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于JMS协议。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;遵循JMS API发起请求。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不太清楚，猜想应该是二进制流。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持多种传输协议，例如socket、http等等。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 监听符合协议的端口。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 同问题3。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 遵循JMS API生成消息，并写入JMS Queue中。<br />
基于JMS此类机制实现远程通讯的例子有Spring-Intergration、Mule、Lingo等等。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
Mina<br />
</strong>Mina是Apache提供的通讯框架，在之前一直没有提到网络IO这块，之前提及的框架或library基本都是基于BIO的，而Mina是采用NIO的，NIO在并发量增长时对比BIO而言会有明显的性能提升，而java性能的提升，与其NIO这块与OS的紧密结合是有不小的关系的。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于纯粹的Socket+NIO。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过Mina提供的Client API。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mina遵循java串行化机制对请求对象进行序列化。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持多种传输协议，例如socket、http等等。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以NIO的方式监听协议端口。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 遵循java串行化机制对请求对象进行反序列化。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 遵循Mina API进行返回。<br />
MINA是NIO方式的，因此支持异步调用是毫无悬念的。<br />
<br />
<strong>--------------------------------------------------------------------------------------------------------------------------------------------------<br />
EJB<br />
</strong>EJB最突出的在于其分布式，EJB采用的是ORMI协议，和RMI协议是差不多的，但EJB在分布式通讯的安全控制、transport pool、smart proxy等方面的突出使得其在分布式领域是不可忽视的力量。<br />
1、是基于什么协议实现的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于ORMI协议。<br />
2、怎么发起请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EJB调用。<br />
3、怎么将请求转化为符合协议的格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 遵循java串行化机制对请求对象进行序列化。<br />
4、使用什么传输协议传输？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Socket。<br />
5、响应端基于什么机制来接收请求？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 监听协议端口。<br />
6、怎么将流还原为传输格式的？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 遵循java串行化机制对请求对象进行反序列化。<br />
7、处理完毕后怎么回应？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 直接返回处理对象即可。<br />
<br />
在之前的分布式服务框架系列的文章中对于jndi有误导的嫌疑，在这篇blog中也顺带的提下jndi的机制，由于JNDI取决于具体的实现，在这里只能是讲解下jboss的jndi的实现了。<br />
在将对象实例绑定到jboss jnp server后，当远程端采用context.lookup()方式获取远程对象实例并开始调用时，jboss jndi的实现方法是从jnp server上获取对象实例，将其序列化回本地，然后在本地进行反序列化，之后在本地进行类调用。<br />
通过这个机制，就可以知道了，本地其实是必须有绑定到jboss上的对象实例的class的，否则反序列化的时候肯定就失败了，而远程通讯需要做到的是在远程执行某动作，并获取到相应的结果，可见纯粹基于JNDI是无法实现远程通讯的。<br />
但JNDI也是实现分布式服务框架一个很关键的技术点，因为可以通过它来实现透明化的远端和本地调用，就像ejb，另外它也是个很好的隐藏实际部署机制(就像datasource)等的方案。<br />
<br />
<span style="font-size: 18pt; color: #008000"><strong>总结</strong></span><br />
由上一系列的分析可知，在远程通讯领域中，涉及的知识点还是相当的多的，例如有：通信协议(Socket/tcp/http/udp/rmi/xml-rpc etc.)、消息机制、网络IO（BIO/NIO/AIO）、MultiThread、本地调用与远程调用的透明化方案（涉及java classloader、Dynamic Proxy、Unit Test etc.）、异步与同步调用、网络通信处理机制（自动重连、广播、异常、池处理等等）、Java Serialization (各种协议的私有序列化机制等)、各种框架的实现原理（传输格式、如何将传输格式转化为流的、如何将请求信息转化为传输格式的、如何接收流的、如何将流还原为传输格式的等等），要精通其中的哪些东西，得根据实际需求来决定了，只有在了解了原理的情况下才能很容易的做出选择，甚至可以根据需求做私有的远程通讯协议，对于从事分布式服务平台或开发较大型的分布式应用的人而言，我觉得至少上面提及的知识点是需要比较了解的。<br />
<br />
<strong style="font-size: 18pt; color: #008000">参考文档（感谢这些文章）</strong><br />
RMI原理及实现：<a href="http://www.yesky.com/274/1625274.shtml">http://www.yesky.com/274/1625274.shtml</a><br />
Java NIO原理和使用：<a href="http://www.jdon.com/concurrent/nio%D4%AD%C0%ED%D3%A6%D3%C3.htm">http://www.jdon.com/concurrent/nio%D4%AD%C0%ED%D3%A6%D3%C3.htm</a><br />
XML RPC协议：<a href="http://hedong.3322.org/archives/000470.html" target="_blank">http://hedong.3322.org/archives/000470.html</a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.mengyan.org/blog/archives/2005/07/12/30.html">http://www.mengyan.org/blog/archives/2005/07/12/30.html</a><br />
Spring技术应用中的远程服务详解：<a href="http://www.builder.com.cn/2007/1027/583384.shtml">http://www.builder.com.cn/2007/1027/583384.shtml</a><br />
JAVA RPC通信<span style="color: #000000">机制之SOAP：</span><a href="http://www.java114.com/content16/content3826.html">http://www.java114.com/content16/content3826.html</a> <br />
Java Remoting：Protocol BenchMarks：<a href="http://q.sohu.com/forum/5/topic/1148909" target="_blank">http://q.sohu.com/forum/5/topic/1148909</a><br />
Evalution of RMI Alternative：<a href="https://www.jfire.org/modules/phpwiki/index.php/Evaluation%20of%20RMI%20Alternative" target="_blank">https://www.jfire.org/modules/phpwiki/index.php/Evaluation%20of%20RMI%20Alternative</a><br />
Metaprotocol Taxonomy：<a href="http://hessian.caucho.com/doc/metaprotocol-taxonomy.xtp" target="_blank">http://hessian.caucho.com/doc/metaprotocol-taxonomy.xtp</a> <br />
什么是Webservice：<a href="http://www.vchome.net/dotnet/webservice/webservice15.htm">http://www.vchome.net/dotnet/webservice/webservice15.htm</a> </div><img src ="http://www.blogjava.net/shmily432685/aggbug/184249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2008-03-06 13:55 <a href="http://www.blogjava.net/shmily432685/archive/2008/03/06/184249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql快速批量导入文本数据</title><link>http://www.blogjava.net/shmily432685/archive/2007/10/16/153329.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Tue, 16 Oct 2007 09:10:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2007/10/16/153329.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/153329.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2007/10/16/153329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/153329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/153329.html</trackback:ping><description><![CDATA[<p>近日有一文本文件，数据格式是以tab分割。数据量有数千万条数据，需要导入mysql数据库中，通过传统的方式进行拷贝到数据库中，需要花费很多天时间，中间也会出现很多错误，未必能导入成功。<br />
使用：load data local infile "本地路径" into table 表名命令方式进行导入，10w条数据也只需要花费几秒钟时间，可中文无法导入。<br />
仔细分析了一下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;建库时采用utf8编码，表也是utf8编码。对中文应该是支持的。排除数据库的问题。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;只能从要导入的文本文件考虑，将其编码用ultraEdit转换编码为utf8后，进行导入，成功导入。数据也没有出现错误。&nbsp;</p>
也可采用select * from&nbsp;表名 into outfile "c:\\文件路径";进行查询；进行导出表中的数据为文本文件格式。 <br />
也可以采用select * from&nbsp;表名 into outfile "c:\\stu_t.txt" lines terminated by '\r\n';进行查询，导出。<img src ="http://www.blogjava.net/shmily432685/aggbug/153329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2007-10-16 17:10 <a href="http://www.blogjava.net/shmily432685/archive/2007/10/16/153329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>经典网摘</title><link>http://www.blogjava.net/shmily432685/archive/2007/04/23/112931.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Mon, 23 Apr 2007 05:29:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2007/04/23/112931.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/112931.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2007/04/23/112931.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/112931.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/112931.html</trackback:ping><description><![CDATA[<p>人=吃饭+睡觉+上班+玩,<br>猪=吃饭+ 睡觉,<br>代入:人=猪+上班+玩,<br>即:人-玩=猪+上班.<br>结论:不懂玩的人=会上班的猪&nbsp;&nbsp; </p>
<p>男人=吃饭+ 睡觉+挣钱<br>猪=吃饭+ 睡觉<br>男人=猪+挣钱<br>猪=男人-挣钱<br>所以男人不挣钱等于猪。</p>
<p>女人=吃饭+ 睡觉+花钱。<br>猪&nbsp; =吃饭+ 睡觉。代入上式得：<br>女人=猪+花钱。移项得：<br>女人-花钱=猪。<br>结论：女人不花钱的都是猪。</p>
<p>综上：<br>男人为了让女人不变成猪而挣钱！<br>女人为了让男人不变成猪而花钱 </p>
<p>&nbsp;</p>
<p>写字楼里写字间，写字间中程序员<br>程序人员写程序，又将程序换酒钱<br>酒醒只在屏前坐，酒醉还来屏下眠<br>酒醉酒醒日复日，屏前屏下年复年<br>但愿老死电脑间，不愿鞠躬老板前<br>奔驰宝马贵者趣，公交自行程序员<br>别人笑我太疯癫，我笑自己命太贱<br>但见满街漂亮妹，哪个归得程序员</p><img src ="http://www.blogjava.net/shmily432685/aggbug/112931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2007-04-23 13:29 <a href="http://www.blogjava.net/shmily432685/archive/2007/04/23/112931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat+mysql+jbpm配置工作流（1）</title><link>http://www.blogjava.net/shmily432685/archive/2007/03/30/107517.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Fri, 30 Mar 2007 09:42:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2007/03/30/107517.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/107517.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2007/03/30/107517.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/107517.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/107517.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 初次研究工作流Jbpm配置与开发：<br>JDK142<br>tomcat 5.0<br>mysql 5.0.16<br>apache-ant-1.6.5<br>jbpm-starters-kit-3.1.4<br>&nbsp;&nbsp;<a href='http://www.blogjava.net/shmily432685/archive/2007/03/30/107517.html'>阅读全文</a><img src ="http://www.blogjava.net/shmily432685/aggbug/107517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2007-03-30 17:42 <a href="http://www.blogjava.net/shmily432685/archive/2007/03/30/107517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用js控制功能收集(待续)</title><link>http://www.blogjava.net/shmily432685/archive/2007/03/09/102760.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Fri, 09 Mar 2007 02:55:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2007/03/09/102760.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/102760.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2007/03/09/102760.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/102760.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/102760.html</trackback:ping><description><![CDATA[【弹出的窗口之定时关闭控制】     <br />  下面我们再对弹出窗口进行一些控制，效果就更好了。如果我们再将一小段代码加入弹出的页面（注意是加入到page.html的HTML中，可不是主页面中，否则…），让它在10秒钟后<b style="COLOR: black; BACKGROUND-COLOR: #ff66ff">自动关闭</b>是不是更酷了？     <br />  首先，将如下代码加入page.html文件的&lt;head&gt;区：     <br />  &lt;script   language="javascript"&gt;     <br />  function   closeit()   {     <br />  setTimeout("self.close()",10000)   //毫秒     <br />  }     <br />  &lt;/script&gt;     <br />  然后，再用&lt;body   onload="closeit()"&gt;这一句话代替page.html中原有的&lt;BODY&gt;这一句就可以了。（这一句话千万不要忘记写啊！这一句的作用是调用关闭窗口的代码，10秒钟后就自行关闭该窗口。）     <br /><img src ="http://www.blogjava.net/shmily432685/aggbug/102760.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2007-03-09 10:55 <a href="http://www.blogjava.net/shmily432685/archive/2007/03/09/102760.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails</title><link>http://www.blogjava.net/shmily432685/archive/2007/01/15/93939.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Mon, 15 Jan 2007 05:23:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2007/01/15/93939.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/93939.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2007/01/15/93939.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/93939.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/93939.html</trackback:ping><description><![CDATA[<div>摘自:<a href="http://www.javaeye.com/topic/43290">http://www.javaeye.com/topic/43290</a><br />一、安装Ruby、rails、mongrel和Apache2.2</div>
		<div> </div>
		<div>从rubyforge网站下载One-Click Ruby Install，运行安装程序，就安装好了ruby和rubygems。</div>
		<div> </div>
		<div>运行命令：</div>
		<div>
				<font 230,="" 230);?="">gem install rails –y</font>
		</div>
		<div>
				<font 230,="" 230);?="">gem install mongrel –y</font>
		</div>
		<div>
				<font 230,="" 230);?="">gem install mongrel_service -y</font>
		</div>
		<div>安装好了rails和mongrel</div>
		<div> </div>
		<div>从Apache网站下载Windows版本的Apache2.2，运行安装程序，就安装好了Apache2.2。</div>
		<div> </div>
		<div>二、把Mongrel作为Services启动</div>
		<div> </div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::install -N depot -c d:\Rubyproject\depot -p 3000 –e production</font>
		</div>
		<div>-N指明服务名称，-d指明rails应用的目录，-p是mongrel监听的tcp端口，-e是启动模式为生产模式</div>
		<div> </div>
		<div>这样打开控制面版|管理工具|服务，就可以发现增加了一项名为“depot”的服务，就可以通过控制面版来管理服务了。如果需要命令行启动和关闭该服务，那么：</div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::start -N depot</font>
		</div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::stop -N depot</font>
		</div>
		<div> </div>
		<div>如果需要从服务中注销该项服务，那么：</div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::remove -N depot</font>
		</div>
		<div> </div>
		<div>如果需要安装多个mongrel实例，那么可以这样：</div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::install -N depot0 -c d:\Rubyproject\depot -p 3000 –e production</font>
		</div>
		<div>
				<font 230,="" 230);?="">mongrel_rails service::install -N depot1 -c d:\Rubyproject\depot -p 3001 –e production</font>
		</div>
		<div>诸如此类。</div>
		<div> </div>
		<div>三、配置Apache2.2</div>
		<div> </div>
		<div>用编辑工具打开Apache2.2目录下面的conf/httpd.conf，需要取消如下模块的注释：</div>
		<div>
				<font 230,="" 230);?="">LoadModule proxy_module modules/mod_proxy.so</font>
		</div>
		<div>
				<font 230,="" 230);?="">LoadModule proxy_balancer_module modules/mod_proxy_balancer.so</font>
		</div>
		<div>
				<font 230,="" 230);?="">LoadModule proxy_http_module modules/mod_proxy_http.so</font>
		</div>
		<div>如果你希望对页面输出使用压缩，也需要取消如下模块的注释：</div>
		<div>
				<font 230,="" 230);?="">LoadModule deflate_module modules/mod_deflate.so</font>
		</div>
		<div> </div>
		<div>然后按如下内容配置基于HTTP代理的负载均衡：</div>
		<div>
				<div>
						<font 230,="" 230);?="">
						</font>
				</div>
				<font 230,="" 230);?="">
						<div class="code_title">xml 代码</div>
						<div class="dp-highlighter">
								<div class="bar"> </div>
								<ol class="dp-xml">
										<li class="alt">
												<span>
														<span>ProxyRequests Off   </span>
												</span>
										</li>
										<li class="">
												<span>
												</span>
												<span class="tag">&lt;</span>
												<span class="tag-name">Proxy</span>
												<span> balancer://myCluster</span>
												<span class="tag">&gt;</span>
												<span>  </span>
										</li>
										<li class="alt">
												<span>  BalancerMember http://localhost:3000   </span>
										</li>
										<li class="">
												<span>  BalancerMember http://localhost:3001   </span>
										</li>
										<li class="alt">
												<span>
												</span>
												<span class="tag">
														<span class="tag-name">
														</span>
														<span class="tag">&gt;</span>
														<span>  </span>
												</span>
										</li>
										<li class="">
												<span>  </span>
										</li>
										<li class="alt">
												<span>
												</span>
												<span class="tag">&lt;</span>
												<span class="tag-name">VirtualHost</span>
												<span> *:80</span>
												<span class="tag">&gt;</span>
												<span>  </span>
										</li>
										<li class="">
												<span>  ServerName www.xxx.com   </span>
										</li>
										<li class="alt">
												<span>  DocumentRoot d:/rubyproject/depot/public   </span>
										</li>
										<li class="">
												<span>  ProxyPass /images !   </span>
										</li>
										<li class="alt">
												<span>  ProxyPass /stylesheets !   </span>
										</li>
										<li class="">
												<span>  ProxyPass /javascripts !   </span>
										</li>
										<li class="alt">
												<span>  ProxyPass / balancer://myCluster/   </span>
										</li>
										<li class="">
												<span>  ProxyPassReverse / balancer://myCluster/   </span>
										</li>
										<li class="alt">
												<span>  ProxyPreserveHost on   </span>
										</li>
										<li class="">
												<span>
												</span>
												<span class="tag">
														<span class="tag-name">
														</span>
														<span class="tag">&gt;</span>
														<span>  </span>
												</span>
										</li>
								</ol>
						</div>
				</font>
		</div>
		<div> </div>
		<div>myCluster定义了群集中的每个mongrel应用服务器节点。ProxyPass /images !指明该URL开始的请求不代理给Mongrel群集，而由Apache自己处理。重起Apache，然后打开浏览器访问<a href="http://www.xxx.com/">www.xxx.com</a>，检查配置是否正确。</div>
		<div> </div>
		<div>至此，在Windows Server上面一个具备良好稳定性和性能的Ruby on rails生产环境就搭建好了。</div>
		<div> </div>
		<div>对于页面输出，还可以使用mod_deflate进行输出内容压缩，以提高页面下载速度，这个就留给大家自己配置了。<br /><br /><br /><p>关闭标记被Rich Editor过滤掉了，重新用bbcode贴一下：</p><p></p><div class="code_title">代码</div><div class="code_div"><div class="dp-highlighter"><div class="bar"></div><ol class="dp-xml"><li class="alt"><span><span>ProxyRequests Off       </span></span></li><li class=""><span></span><span class="tag">&lt;</span><span class="tag-name">Proxy</span><span> balancer://myCluster</span><span class="tag">&gt;</span><span>      </span></li><li class="alt"><span>  BalancerMember http://localhost:3000       </span></li><li class=""><span>  BalancerMember http://localhost:3001       </span></li><li class="alt"><span></span><span class="tag">&lt;/</span><span class="tag-name">Proxy</span><span class="tag">&gt;</span><span>      </span></li><li class=""><span>      </span></li><li class="alt"><span></span><span class="tag">&lt;</span><span class="tag-name">VirtualHost</span><span> *:80</span><span class="tag">&gt;</span><span>      </span></li><li class=""><span>  ServerName www.xxx.com       </span></li><li class="alt"><span>  DocumentRoot d:/rubyproject/depot/public       </span></li><li class=""><span>  ProxyPass /images !       </span></li><li class="alt"><span>  ProxyPass /stylesheets !       </span></li><li class=""><span>  ProxyPass /javascripts !       </span></li><li class="alt"><span>  ProxyPass / balancer://myCluster/       </span></li><li class=""><span>  ProxyPassReverse / balancer://myCluster/       </span></li><li class="alt"><span>  ProxyPreserveHost on       </span></li><li class=""><span></span><span class="tag">&lt;/</span><span class="tag-name">VirtualHost</span><span class="tag">&gt;</span><span>    </span></li></ol></div></div><script><![CDATA[ender_code();]]&gt;</script><p></p><p>cluster的作用不是加速单个请求的，是提高整体的负载能力的。</p></div><img src ="http://www.blogjava.net/shmily432685/aggbug/93939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2007-01-15 13:23 <a href="http://www.blogjava.net/shmily432685/archive/2007/01/15/93939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决java.lang.UnsupportedClassVersionError问题！！</title><link>http://www.blogjava.net/shmily432685/archive/2006/12/29/90651.html</link><dc:creator>闵毓</dc:creator><author>闵毓</author><pubDate>Fri, 29 Dec 2006 01:44:00 GMT</pubDate><guid>http://www.blogjava.net/shmily432685/archive/2006/12/29/90651.html</guid><wfw:comment>http://www.blogjava.net/shmily432685/comments/90651.html</wfw:comment><comments>http://www.blogjava.net/shmily432685/archive/2006/12/29/90651.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/shmily432685/comments/commentRss/90651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/shmily432685/services/trackbacks/90651.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Eclipse解决java.lang.UnsupportedClassVersionError问题，只需要把项目用的JDK与你安装的JDK搞成版本一样就解决了．<br>步骤：右击你的项目－－＞属性－－＞Java Compiler，设置合适的版本！！&nbsp;&nbsp;<a href='http://www.blogjava.net/shmily432685/archive/2006/12/29/90651.html'>阅读全文</a><img src ="http://www.blogjava.net/shmily432685/aggbug/90651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/shmily432685/" target="_blank">闵毓</a> 2006-12-29 09:44 <a href="http://www.blogjava.net/shmily432685/archive/2006/12/29/90651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>