﻿<?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-仓蓝-随笔分类-java</title><link>http://www.blogjava.net/cangshi004/category/50719.html</link><description>日记本</description><language>zh-cn</language><lastBuildDate>Wed, 11 Sep 2013 16:21:08 GMT</lastBuildDate><pubDate>Wed, 11 Sep 2013 16:21:08 GMT</pubDate><ttl>60</ttl><item><title>JAVA编程之安全配置Struts 2应用程序详解</title><link>http://www.blogjava.net/cangshi004/archive/2012/03/22/372435.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Thu, 22 Mar 2012 03:21:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/03/22/372435.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/372435.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/03/22/372435.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/372435.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/372435.html</trackback:ping><description><![CDATA[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当你在配置Struts 2这个应用程序时，安全功能是一个最关键的问题，本文章详细介绍一下这方面的内容，希望对大家有所帮助吧。呵呵，当然，如果有不当之处，也请朋友们指正啊！配置Struts 2应用程序是基于servlet技术的，所以Struts 2的安全策略也可以使用配置文件进行灵活的配置。 
<p>配置安全策略时，有两个概念需要清楚的区分 ，用户和角色，简单的说用户为使用计算机的人，可以是个人或组织。角色是一个抽象的概念，泛指职务或者权限。例如，张三，李四，王五三个人，有职员、主管和经理三个职务（权限），张三是用户，张三可以是主管职务，代表张三这个用户含有主管的权利。</p>
<p>不同的servlet容器所提供的用户和角色管理机制是不相同的。我使用的是Tomcat服务器，它提供的用户和角色管理机制文件是在其安装目录下的conf目录中的tomcat-users.xml文件，可以在这个文件里完成对用户和角色的编辑。例如：</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">tomcat-users</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">rolename</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">rolename</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"role1"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"both"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat,role1"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"role1"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"tomcat"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"role1"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">tomcat-users</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>这个文件定义了2个角色(tomcat和role1)和3名用户(tomcat、both和role1)。你可以在tomcat-users.xml文件里定义任意多个用户和角色。</p>
<p>使用Struts 2保护应用程序的资源</p>
<p>Struts 2应用程序的安全策略是通过部署web.xml文件中的security-constraint元素实现的，该元素的语法定义：</p><pre><ol class="dp-xml"><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;security-constraint&nbsp;(display-name?,&nbsp;web-resource-collection+,&nbsp;auth-constraint?,&nbsp;user-data-constraint?)</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></li><li><span><font color="#000000">&lt;!ELEMENT&nbsp;display-name&nbsp;(#PCDATA)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;web-resource-collection&nbsp;(web-resource-name,&nbsp;description?,&nbsp;url-pattern*,&nbsp;http-method*)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li><span><font color="#000000">&lt;!ELEMENT&nbsp;auth-constraint&nbsp;(description?,&nbsp;role-name*)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;user-data-constraint&nbsp;(description?,&nbsp;transport-guarantee)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>该语法说明了，security-constraint元素可以有一个可选的display-name子元素，至少一个web-resource-collection子元素，一个可选的auth-constraint子元素和一个可选的user-data-constraint子元素。</p>
<p>web-resource-collection子元素是用来列出打算保护的Web资源，具体的做法是为这些资源设置URL限制，它是通过设置web-resource-collection元素包含的子元素实现的：</p>
<p>&#9670;&nbsp; web-resource-name：是与受保护资源相关联的名称。该子元素为必须元素。</p>
<p>&#9670;&nbsp; description：对给定资源的描述。这个子元素为可选元素。</p>
<p>&#9670;&nbsp; url-pattern：用来设置URL表达式，与这个URL表达式相匹配的URL地址指向的资源将受到保护。该子元素为至少有一个，为必须元素。</p>
<p>&#9670;&nbsp; http-method：用来表明哪些HTTP方法将受到限制，例如设置为GET那么所有的GET请求就将受到限制。该元素为可选元素。</p>
<p>auth-constraint元素用于指定可以访问该资源用户角色集合。如果没有指定auth-constraint元素，就将安全约束应用于所有角色。它包含下面几个子元素：</p>
<p>&#9670;&nbsp; description：描述。该元素是可选元素。</p>
<p>&#9670;&nbsp; role-name：可以访问保护资源的用户角色。该元素可以有多个。</p>
<p>&#9670;&nbsp; user-data-constraint元素用来设置怎样保护在客户端和Web容器之间传递的数据。</p>
<p>&#9670;&nbsp; description： 描述。可选元素。</p>
<p>&#9670;&nbsp; transport-guarantee ：该元素有以下几个值</p>
<p>1. NONE，这意味着应用不需要传输保证。</p>
<p>2. INTEGRAL，意味着服务器和客户端之间的数据必须以某种方式发送，而且在传送中数据不能被篡改。</p>
<p>3. CONFIDENTIAL，这意味着传输的数据必须加密。</p>
<p>配置完毕security-constraint元素的基本信息，大致为下面的格式：</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">security-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">web-resource-collection</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">web-resource-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">Admin&nbsp;Arew</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">web-resource-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">*.action</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">web-resource-collection</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">auth-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">myeclipseWeb</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">auth-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">security-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>这个security-constraint元素的效果为：只要与表达式"*.action"匹配的请求不是来自拥有"myeclipseWeb"权限的用户，Web容器就会阻断它。在这里还可以使用http-method元素，阻断特定方法的请求，因为没有使用会阻断所有方法提交的请求。</p>
<p>设置完安全策略后，还需要设置让用户有机会提供证明，证明自己有权限访问这个受限资源的登陆方法。允许使用的登陆方法使用login-config元素设置，下面为login-config元素的语法定义：</p><pre><ol class="dp-xml"><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;login-config&nbsp;(auth-method?,&nbsp;realm-name?,&nbsp;form-login-config?)</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></li><li><span><font color="#000000">&lt;!ELEMENT&nbsp;auth-method&nbsp;(#PCDATA)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;realm-name&nbsp;(#PCDATA)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li><span><font color="#000000">&lt;!ELEMENT&nbsp;form-login-config&nbsp;(form-login-page,&nbsp;form-error-page)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>login-config子元素的描述如下： <br />&#9670;&nbsp; auth-method指定用来验证用户身份的方法。它的值为下面的一个：BASIC、DIGEST、FORM或 CLIENT-CERT <br />&#9670;&nbsp; realm-name指定HTTP Basic验证中在标准登陆框中显示的一条提示。 <br />&#9670;&nbsp; form-login-config元素是在&lt;auth-method&gt;元素值为"FORM"时使用的。它是指定基于表单的登录中应该使用的登录页面和出错页面。如果没有使用基于表单的验证，则忽略这些元素。这个元素的定义如下，其中form-login-page用于指定显示登录页面的资源路径， form-error-page则用于指定用户登录失败时显示出错页面的资源路径。</p><pre><ol class="dp-xml"><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;form-login-config&nbsp;(form-login-page,&nbsp;form-error-page)</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></li><li><span><font color="#000000">&lt;!ELEMENT&nbsp;form-login-page&nbsp;(#PCDATA)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&lt;!ELEMENT&nbsp;form-error-page&nbsp;(#PCDATA)</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>设置完登陆方法后，还应该使用security-role元素，注册允许用来访问受保护资源所有角色。在该元素内部使用一个role-name子元素来注册一个角色。例如：</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">myeclipseWeb</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>注册了一个"myeclipseWeb"的角色。</p>
<p>演示示例：使用BASIC登陆方法验证用户身份</p>
<p>1.我使用的Servlet容器是Tomcat，找到它的目录下conf目录中的tomcat-users.xml文件打开内容如下：</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;?</span><span class="tag-name">xml</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">version</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">'1.0'</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">encoding</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">'utf-8'</font></span><span class="tag"><strong><font color="#006699">?&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">tomcat-users</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">rolename</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"myeclipseWeb"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">rolename</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"myeclipseWebservices"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"webservices"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"webservices-pwd"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"myeclipseWebservices"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"admin"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"admin-pwd"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"myeclipseWeb,myeclipseWebservices"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">user</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">username</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"web"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">password</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"web-pwd"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">roles</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"myeclipseWeb"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">tomcat-users</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>我使用的IDE是myEclipse9.0，它配置好Tomcat下的tomcat-users.xml文件内容如上，我直接使用它了，你也可以添加自己的角色和用户。该文件定义了2个角色和3个用户，每一个用户都由自己的角色(或者说权限，可以有多重权限)。</p>
<p>2.创建Web项目，找到web.xml，配置它，使它支持Struts 2并且启动Struts 2的安全策略</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;?</span><span class="tag-name">xml</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">version</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"1.0"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">encoding</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"UTF-8"</font></span><span class="tag"><strong><font color="#006699">?&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">web-app</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">id</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"WebApp_9"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">version</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"2.4"</font></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="attribute"><font color="#ff0000">xmlns</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"http://java.sun.com/xml/ns/j2ee"</font></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="attribute"><font color="#ff0000">xmlns:xsi</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"http://www.w3.org/2001/XMLSchema-instance"</font></span><span><font color="#000000">&nbsp;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="attribute"><font color="#ff0000">xsi:schemaLocation</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"http://java.sun.com/xml/ns/j2ee&nbsp;http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">display-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">Struts&nbsp;Blank</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">display-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">filter</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">struts2</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">filter-class</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">filter</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">struts2</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">filter-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">/*</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">filter-mapping</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">index.html</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="comments"><font color="#008200">&lt;!--&nbsp;&nbsp;配置应用程序需要保护的资源与什么角色才可以访问它&nbsp;&nbsp;&nbsp;--&gt;</font></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">security-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">web-resource-collection</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">web-resource-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">Admin&nbsp;Arew</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">web-resource-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">*.action</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">web-resource-collection</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">auth-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">myeclipseWeb</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">auth-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">security-constraint</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="comments"><font color="#008200">&lt;!--&nbsp;注册可以访问保护资源的角色&nbsp;&nbsp;--&gt;</font></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">myeclipseWeb</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">myeclipseWebservices</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">role-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">security-role</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="comments"><font color="#008200">&lt;!--&nbsp;&nbsp;设置登录方法&nbsp;&nbsp;--&gt;</font></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">login-config</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">auth-method</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">BASIC</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">auth-method</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">realm-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">User&nbsp;Basic&nbsp;Authentication</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">realm-name</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">login-config</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">web-app</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>3. 创建接收一个字段信息的动作类：</p><pre><ol class="dp-j"><li class="alt"><span class="keyword"><strong><font color="#006699">public</font></strong></span><span><font color="#000000">&nbsp;</font></span><span class="keyword"><strong><font color="#006699">class</font></strong></span><span><font color="#000000">&nbsp;SecureAction&nbsp;</font></span><span class="keyword"><strong><font color="#006699">extends</font></strong></span><span><font color="#000000">&nbsp;ActionSupport&nbsp;{&nbsp;</font></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">private</font></strong></span><span><font color="#000000">&nbsp;</font></span><span class="keyword"><strong><font color="#006699">static</font></strong></span><span><font color="#000000">&nbsp;</font></span><span class="keyword"><strong><font color="#006699">final</font></strong></span><span><font color="#000000">&nbsp;</font></span><span class="keyword"><strong><font color="#006699">long</font></strong></span><span><font color="#000000">&nbsp;serialVersionUID&nbsp;=&nbsp;1961430702313132722L;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">private</font></strong></span><span><font color="#000000">&nbsp;String&nbsp;username;&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">public</font></strong></span><span><font color="#000000">&nbsp;String&nbsp;getUsername()&nbsp;{&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">return</font></strong></span><span><font color="#000000">&nbsp;username;&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</font></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">public</font></strong></span><span><font color="#000000">&nbsp;</font></span><span class="keyword"><strong><font color="#006699">void</font></strong></span><span><font color="#000000">&nbsp;setUsername(String&nbsp;username)&nbsp;{&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">this</font></strong></span><span><font color="#000000">.username&nbsp;=&nbsp;username;&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</font></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="annotation"><font color="#646464">@Override</font></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">public</font></strong></span><span><font color="#000000">&nbsp;String&nbsp;execute()&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;</font></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><span class="keyword"><strong><font color="#006699">return</font></strong></span><span><font color="#000000">&nbsp;SUCCESS;&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</font></span></li><li class="alt"><span><font color="#000000">}&nbsp;</font></span></li></ol></pre>
<p>4. 创建struts.xml配置文件，声明动作</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;?</span><span class="tag-name">xml</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">version</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"1.0"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">encoding</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"UTF-8"</font></span><span><font color="#000000">&nbsp;</font></span><span class="tag"><strong><font color="#006699">?&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&lt;!DOCTYPE&nbsp;struts&nbsp;PUBLIC&nbsp;</font></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;"-//Apache&nbsp;Software&nbsp;Foundation//DTD&nbsp;Struts&nbsp;Configuration&nbsp;2.0//EN"&nbsp;</font></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;"http://struts.apache.org/dtds/struts-2.0.dtd"</font><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">struts</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">package</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">name</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"securePackage"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">extends</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"struts-default"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">action</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">name</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"secure"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">class</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"struts2.action.SecureAction"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">result</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">name</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"success"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">/index.jsp</font></span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">result</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">action</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">package</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">struts</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>5. 创建输入页面input.jsp和结果页面index.jsp</p>
<p>input.jsp:</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">s:form</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">action</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"secure"</font></span><span class="tag"><strong><font color="#006699">&gt;</font></strong></span><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">s:textfield</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">name</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"username"</font></span><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">label</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"Enter&nbsp;your&nbsp;name"</font></span><strong><font color="#006699"><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">s:textfield</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">s:submit</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">value</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"submit"</font></span><strong><font color="#006699"><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">s:submit</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li class="alt"><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">s:form</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">body</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>index.jsp</p><pre><ol class="dp-xml"><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">body</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li><li><span><font color="#000000">&nbsp;&nbsp;&nbsp;&nbsp;</font><strong><font color="#006699"><span class="tag">&lt;</span><span class="tag-name">s:property</span></font></strong><span><font color="#000000">&nbsp;</font></span><span class="attribute"><font color="#ff0000">value</font></span><span><font color="#000000">=</font></span><span class="attribute-value"><font color="#0000ff">"username"</font></span><span class="tag"><strong><font color="#006699">/&gt;</font></strong></span><span><font color="#000000">,Welcome&nbsp;</font></span></span></li><li class="alt"><span><strong><font color="#006699"><span class="tag">&lt;/</span><span class="tag-name">body</span><span class="tag">&gt;</span></font></strong><span><font color="#000000">&nbsp;</font></span></span></li></ol></pre>
<p>6.测试效果，在浏览器输入：http://localhost:8081/SecureTest/input.jsp，得到如下<a style="text-decoration: none" href="http://www.dttjf.com/product/689/"><font color="black">自力式温度调节阀</font></a>界面：输入"Tom"，点击"submit"按钮，查看效果：</p><br />
<p>看到了登陆框了吧，此时我们要访问的资源是一个受限资源所以要求权限验证<a style="text-decoration: none" href="http://www.dtqiufa.com/product/0604/"><font color="black">顶装式球阀</font></a>，还记得我们的用户表吧，查看用户表输入用户信息查看结果：</p>
<p>&nbsp;</p>
<p>输入"webservices"与"webservices-pwd"的用户信息：</p>
<p>&nbsp;</p>
<p>提示了一个"403"错误，这是因为虽然用户信息正确，但是"webservices"用户的没有"myeclipseWeb"权限。</p>
<p>这次输入一个不存在的用户信息：</p>
<p>这次获得了一个"401"错误，这是登陆失败的提示结果，这里会因浏览器的不同而需要不同次数的失败登陆才会得到这个结果。</p>
<p>接下来输入一个正确的用户，并且拥有"webservices"权限的用户信息：</p>
<p>点击"确定"，获得如下结果：</p>
<p>可以看到，我们成功的访问了受保护的资源。若要传中文字，解决方案我已经在前面"配置Struts2"时介绍过了，需要修改Struts 2默认的编码方式还需要修改页面的编码方式，都改为"GBK"。</p>
<p>&nbsp;<div><a href="http://www.ptcm.com/product/product_detail_57.html">自吸磁力泵</a>18 <a href="http://www.ptcm.com/product/product_detail_78.html">旋涡磁力泵</a>17 <a href="http://www.ptcm.com/news/news_detail_1949.html">不锈钢磁力泵</a>33 <a href="http://www.ptcm.com/product/product_detail_249.html">工程塑料磁力泵</a></div></p><img src ="http://www.blogjava.net/cangshi004/aggbug/372435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-03-22 11:21 <a href="http://www.blogjava.net/cangshi004/archive/2012/03/22/372435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java虚拟机技术参数应用详解</title><link>http://www.blogjava.net/cangshi004/archive/2012/03/06/371316.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Tue, 06 Mar 2012 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/03/06/371316.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/371316.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/03/06/371316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/371316.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/371316.html</trackback:ping><description><![CDATA[Java虚拟机技术参数应用详解<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JAVA虚拟机参数主要分为基本和扩展两类，在命令行中输入JAVA_HOME\bin\java 就可得到基本参数列表，在命令行输入JAVA_HOME\bin\java &#8211;X 就可得到扩展参数列表。 
<p>　　基本参数说明：</p>
<p>　　-client，-server</p>
<p>　　这两个参数用于设置虚拟机使用何种运行模式，client模式启动比较快，但运行时性能和内存管理效率不如server模式，通常用于客户端应用程序。相反，server模式启动比client慢，但可获得更高的运行性能。</p>
<p>　　在 windows上，缺省的虚拟机类型为client模式，如果要使用server模式，就需要在启动虚拟机时加-server参数，以获得更高性能，对服务器端应用，推荐采用server模式，尤其是多个CPU的系统。在Linux，Solaris上缺省采用server模式。</p>
<p>　　-hotspot</p>
<p>　　含义与client相同，jdk1.4以前使用的参数，jdk1.4开始不再使用，代之以client.</p>
<p>　　-classpath，-cp</p>
<p>　　虚拟机在运行一个类时，需要将其装入内存，虚拟机搜索类的方式和顺序如下：</p>
<p>　　Bootstrap classes，Extension classes，User classes.</p>
<p>　　Bootstrap 中的路径是虚拟机自带的jar或zip文件，虚拟机首先搜索这些包文件，用System.getProperty（"sun.boot.class.path"）可得到虚拟机搜索的包名。</p>
<p>　　Extension是位于jre\lib\ext目录下的jar文件，虚拟机在搜索完Bootstrap后就搜索该目录下的jar文件。用System. getProperty（"java.ext.dirs&#8220;）可得到虚拟机使用Extension搜索路径。</p>
<p>　　User classes搜索顺序为当前目录、环境变量 CLASSPATH、-classpath.</p>
<p>　　-classpath告知虚拟机搜索目录名、jar文档名、zip文档名，之间用分号；分隔。</p>
<p>　　例如当你自己开发了公共类并包装成一个common.jar包，在使用common.jar中的类时，就需要用-classpath common.jar 告诉虚拟机从common.jar中查找该类，否则虚拟机就会抛出java.lang.NoClassDefFoundError异常，表明未找到类定义。</p>
<p>　　在运行时可用System.getProperty（&#8220;java.class.path&#8221;）得到虚拟机查找类的路径。</p>
<p>　　使用-classpath后虚拟机将不再使用CLASSPATH中的类搜索路径，如果-classpath和CLASSPATH都没有设置，则虚拟机使用当前路径（。）作为类搜索路径。</p>
<p>　　推荐使用-classpath来定义虚拟机要搜索的类路径，而不要使用环境变量 CLASSPATH的搜索路径，以减少多个项目同时使用CLASSPATH时存在的潜在冲突。例如应用1要使用a1.0.jar中的类G，应用2要使用 a2.0.jar中的类G，a2.0.jar是a1.0.jar的升级包，当a1.0.jar，a2.0.jar都在CLASSPATH中，虚拟机搜索到第一个包中的类G时就停止搜索，如果应用1应用2的虚拟机都从CLASSPATH中搜索，就会有一个应用得不到正确版本的类G.</p>
<p>　　-D&lt;propertyName&gt;=value</p>
<p>　　在虚拟机的系统属性中设置属性名/值对，运行在此虚拟机之上的应用程序可用System.getProperty（&#8220;propertyName&#8221;）得到value的值。</p>
<p>　　如果value中有空格，则需要用双引号将该值括起来，如-Dname=&#8220;space string&#8221;。</p>
<p>　　该参数通常用于设置系统级全局变量值，如配置文件路径，应为该属性在程序中任何地方都可访问。</p>
<p>　　-verbose[：class|gc|jni]</p>
<p>　　在输出设备上显示虚拟机运行信息。</p>
<p>　　verbose和verbose：class含义相同，输出虚拟机装入的类的信息，显示的信息格式如下：</p>
<p>　　[Loaded java.io.FilePermission$1 from shared objects file]</p>
<p>　　当虚拟机报告类找不到或类冲突时可用此参数来诊断来查看虚拟机从装入类的情况。</p>
<p>　　-verbose：gc在虚拟机发生内存回收时在输出设备显示信息，格式如下：</p>
<p>　　[Full GC 268K-&gt;168K（1984K）， 0.0187390 secs]</p>
<p>　　该参数用来监视虚拟机内存回收的情况。</p>
<p>　　-verbose：jni在虚拟机调用native方法时输出设备显示信息，格式如下：</p>
<p>　　[Dynamic-linking native method HelloNative.sum &#8230;&#8230; JNI]</p>
<p>　　该参数用来监视虚拟机调用本地方法的情况，在发生jni错误时可为诊断提供便利。</p>
<p>　　-version</p>
<p>　　显示可运行的虚拟机版本信息然后退出。一台机器上装有不同版本的JDK时</p>
<p>　　-showversion</p>
<p>　　显示版本信息以及帮助信息。</p>
<p>　　-ea[：&lt;packagename&gt;&#8230;&#8230;|：&lt;classname&gt;]</p>
<p>　　-enableassertions[：&lt;packagename&gt;&#8230;&#8230;|：&lt;classname&gt;]</p>
<p>　　从JDK1.4开始，java可支持断言机制，用于诊断运行时问题。通常在测试阶段使断言有效，在正式运行时不需要运行断言。断言后的表达式的值是一个逻辑值，为true时断言不运行，为false时断言运行，抛出java.lang.AssertionError错误。</p>
<p>　　上述参数就用来设置虚拟机是否启动断言机制，缺省时虚拟机关闭断言机制，用-ea可打开断言机制，不加&lt;packagename&gt;和 classname时运行所有包和类中的断言，如果希望只运行某些包或类中的断言，可将包名或类名加到-ea之后。例如要启动包com.foo.util 中的断言，可用命令 &#8211;ea：com.foo.util .</p>
<p>　　-da[：&lt;packagename&gt;&#8230;&#8230;|：&lt;classname&gt;]</p>
<p>　　-disableassertions[：&lt;packagename&gt;&#8230;&#8230;|：&lt;classname&gt;]</p>
<p>　　用来设置虚拟机关闭断言处理，packagename和classname的使用方法和-ea相同。</p>
<p>　　-esa | -enablesystemassertions</p>
<p>　　设置虚拟机显示系统类的断言。</p>
<p>　　-dsa | -disablesystemassertions</p>
<p>　　设置虚拟机关闭系统类的断言。</p>
<p>　　-agentlib：&lt;libname&gt;[=&lt;options&gt;]</p>
<p>　　该参数是JDK5新引入的，用于虚拟机装载本地代理库。</p>
<p>　　Libname为本地代理库文件名，虚拟机的搜索路径为环境变量PATH中的路径，options为传给本地库启动时的参数，多个参数之间用逗号分隔。在Windows平台上虚拟机搜索本地库名为libname.dll的文件，在 Unix上虚拟机搜索本地库名为libname.so的文件，搜索路径环境变量在不同系统上有所不同，Linux、SunOS、IRIX上为 LD_LIBRARY_PATH，AIX上为LIBPATH，HP-UX上为SHLIB_PATH.</p>
<p>　　例如可使用-agentlib：hprof来获取虚拟机的运行情况，包括CPU、内存、线程等的运行数据，并可输出到指定文件中，可用-agentlib：hprof=help来得到使用帮助列表。在jre\bin目录下可发现hprof.dll文件。</p>
<p>　　-agentpath：&lt;pathname&gt;[=&lt;options&gt;]</p>
<p>　　设置虚拟机按全路径装载本地库，不再搜索PATH中的路径。其他功能和agentlib相同。</p>
<p>　　-javaagent：&lt;jarpath&gt;[=&lt;options&gt;]</p>
<p>　　虚拟机启动时装入java语言设备代理。Jarpath文件中的mainfest文件必须有Agent-Class属性。代理类要实现public static void premain（String agentArgs， Instrumentation inst）方法。当虚拟机初始化时，将按代理类的说明顺序调用premain方法。</p>
<p>　　参见：java.lang.instrument</p>
<p>　　扩展参数说明</p>
<p>　　-Xmixed</p>
<p>　　设置-client模式虚拟机对使用频率高的方式进行Just-In-Time编译和执行，对其他方法使用解释方式执行。该方式是虚拟机缺省模式。</p>
<p>　　-Xint</p>
<p>　　设置-client模式下运行的虚拟机以解释方式执行类的字节码，不将字节码编译为本机码。</p>
<p>　　-Xbootclasspath：path</p>
<p>　　-Xbootclasspath/a：path</p>
<p>　　-Xbootclasspath/p：path</p>
<p>　　改变虚拟机装载缺省系统运行包rt.jar而从-Xbootclasspath中设定的搜索路径中装载系统运行类。除非你自己能写一个运行时，否则不会用到该参数。</p>
<p>　　/a：将在缺省搜索路径后加上path 中的搜索路径。</p>
<p>　　/p：在缺省搜索路径前先搜索path中的搜索路径。</p>
<p>　　-Xnoclassgc</p>
<p>　　关闭虚拟机对class的垃圾回收功能。</p>
<p>　　-Xincgc</p>
<p>　　启动增量垃圾收集器，缺省是关闭的。增量垃圾收集器能减少偶然发生的长时间的垃圾回收造成的暂停时间。但<a style="text-decoration: none" href="http://www.yglgb.com/"><font color="black">浓浆泵</font></a>增量垃圾收集器和应用程序并发执行，因此会占用部分CPU在应用程序上的功能。</p>
<p>　　-Xloggc：&lt;file&gt;</p>
<p>　　将虚拟机每次垃圾回收的信息写到日志文件中，文件名由file指定，文件格式是平文件，内容和-verbose：gc输出内容相同。</p>
<p>　　-Xbatch</p>
<p>　　虚拟机的缺省运行方式是在后台编译类代码，然后在前台执行代码，使用-Xbatch参数将关闭虚拟机后台编译，在前台编译完成后再执行。</p>
<p>　　-Xms&lt;size&gt;</p>
<p>　　设置虚拟机可用内存堆的初始大小，缺省单位为字节，该大小为1024的整数倍并且要大于1MB，可用k（K）或m（M）为单位来设置较大的内存数。初始堆大小为2MB.</p>
<p>　　例如：-Xms6400K，-Xms256M</p>
<p>　　-Xmx&lt;size&gt;</p>
<p>　　设置虚拟机内存堆的最大可用大小，缺省单位为字节。该值必须为1024整数倍，并且要大于2MB.可用k（K）或m（M）为单位来设置较大的内存数。缺省堆最大值为64MB.</p>
<p>　　例如：-Xmx81920K，-Xmx80M</p>
<p>　　当应用程序申请了大内存运行时虚拟机抛出java.lang.OutOfMemoryError： Java heap space错误，就需要使用-Xmx设置较大的可用内存堆泵。</p>
<p>　　-Xss&lt;size&gt;</p>
<p>　　设置线程栈的大小，缺省单位为字节。与-Xmx类似，也可用K或M来设置较大的值。通常操作系统分配给线程栈的缺省大小为1MB.</p>
<p>　　另外也可在java中创建线程对象时设置栈的大小，构造函数原型为Thread（ThreadGroup group， Runnable target， String name， long stackSize）。</p>
<p>　　-Xprof</p>
<p>　　输出CPU运行时的诊断信息。</p>
<p>　　-Xfuture</p>
<p>　　对类文件进行严格格式检查，以保证类代码符合类代码规范。为保持向后兼容，虚拟机缺省不进行严格的格式检查。</p>
<p>　　-Xrs</p>
<p>　　减少虚拟机中操作系统的信号（singals）的使用。该参数通常用在虚拟机以后台服务方式运行时使用（如Servlet）。</p>
<p>　　-Xcheck：jni</p>
<p>　　调用JNI函数时进行附加的检查，特别地虚拟机将校验传递给JNI函数参数的合法性，在本地代码中遇到非法数据时，虚拟机将报一个致命错误而终止。使用该阀参数后将造成性能下降。</p>
<p>&nbsp;<div><a href="http://www.ptcm.com/product/product_detail_184.html">单螺杆泵</a>183 <a href="http://www.ptcm.com/news/news_detail_2000.html">不锈钢螺杆泵</a>30 <a href="http://www.ptcm.com/news/news_detail_2021.html">容积泵</a>27 <a href="http://www.ptcm.com/product/product_detail_224.html">防爆油泵</a></div></p><img src ="http://www.blogjava.net/cangshi004/aggbug/371316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-03-06 10:50 <a href="http://www.blogjava.net/cangshi004/archive/2012/03/06/371316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA之JDK在64位系统默认开启压缩指针分析</title><link>http://www.blogjava.net/cangshi004/archive/2012/03/02/371120.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Fri, 02 Mar 2012 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/03/02/371120.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/371120.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/03/02/371120.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/371120.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/371120.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; JAVA之JDK在64位系统默认开启压缩指针分析（请多多指正！）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sun的HotSpot VM从JDK5开始会根据运行环境来自动设定VM的一些参数（ergonomics）。其中大家最熟悉的可能是它会自动选择client与server模式、堆的初始和最大大小等。事实上ergonomics会设置非常多的内部参数，包括自动选择GC算法、并行GC的线程数、GC的工作区分块大小、对象晋升阈值等等。 
<p>　　Ergonomics相关的逻辑大都在hotspot/src/share/vm/runtime/arguments.cpp中，值得留意的是使用了FLAG_SET_ERGO（）的地方。</p>
<p>　　于是我们可以留意一下几个版本的HotSpot对UseCompressedOops参数的处理的差异：</p>
<p>　　HotSpot 16：</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><span class="tag"><li class="alt"><span class="preprocessor"><font color="#808080">#ifdef&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Check&nbsp;that&nbsp;UseCompressedOops&nbsp;can&nbsp;be&nbsp;set&nbsp;with&nbsp;<br />the&nbsp;max&nbsp;heap&nbsp;size&nbsp;allocated&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;by&nbsp;ergonomics.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(MaxHeapSize&nbsp;&lt;=&nbsp;max_heap_for_compressed_oops())&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(FLAG_IS_DEFAULT(UseCompressedOops))&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Turn&nbsp;off&nbsp;until&nbsp;bug&nbsp;is&nbsp;fixed.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;the&nbsp;following&nbsp;line&nbsp;to&nbsp;return&nbsp;it&nbsp;to&nbsp;default&nbsp;status.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;FLAG_SET_ERGO(bool,&nbsp;UseCompressedOops,&nbsp;true);&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;...&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#endif&nbsp;//&nbsp;_LP64</font></span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　HotSpot 17:</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><span class="tag"><li class="alt"><span class="preprocessor"><font color="#808080">#ifndef&nbsp;ZERO&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#ifdef&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Check&nbsp;that&nbsp;UseCompressedOops&nbsp;can&nbsp;be&nbsp;set&nbsp;with&nbsp;<br />the&nbsp;max&nbsp;heap&nbsp;size&nbsp;allocated&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;by&nbsp;ergonomics.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(MaxHeapSize&nbsp;&lt;=&nbsp;max_heap_for_compressed_oops())&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#ifndef&nbsp;COMPILER1&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(FLAG_IS_DEFAULT(UseCompressedOops)&nbsp;&amp;&amp;&nbsp;!UseG1GC)&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Disable&nbsp;Compressed&nbsp;Oops&nbsp;by&nbsp;default.&nbsp;Uncomment&nbsp;<br />next&nbsp;line&nbsp;to&nbsp;enable&nbsp;it.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;FLAG_SET_ERGO(bool,&nbsp;UseCompressedOops,&nbsp;true);&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#endif&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;...&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#endif&nbsp;//&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span class="preprocessor"><font color="#808080">#endif&nbsp;//&nbsp;!ZERO&nbsp;&nbsp; </font></span><span>&nbsp;</span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　HotSpot 19 / HotSpot 20:</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><span class="tag"><li class="alt"><span class="preprocessor"><font color="#808080">#ifndef&nbsp;ZERO&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#ifdef&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Check&nbsp;that&nbsp;UseCompressedOops&nbsp;can&nbsp;be&nbsp;set&nbsp;with&nbsp;<br />the&nbsp;max&nbsp;heap&nbsp;size&nbsp;allocated&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;by&nbsp;ergonomics.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(MaxHeapSize&nbsp;&lt;=&nbsp;max_heap_for_compressed_oops())&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#ifndef&nbsp;COMPILER1&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(FLAG_IS_DEFAULT(UseCompressedOops)&nbsp;&amp;&amp;&nbsp;!UseG1GC)&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FLAG_SET_ERGO(</span><span class="datatypes"><strong><font color="#2e8b57">bool</font></strong></span><span>,&nbsp;UseCompressedOops,&nbsp;</span><span class="keyword"><strong>true</strong></span><span>);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#endif&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;...&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span class="preprocessor"><font color="#808080">#endif&nbsp;//&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span class="preprocessor"><font color="#808080">#endif&nbsp;//&nbsp;!ZERO</font></span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　（注：HotSpot VM的版本号与JDK的版本号之间的关系，请参考另一篇笔记：Sun/Oracle JDK、OpenJDK、HotSpot VM版本之间的对应关系）</p>
<p>　　可以看到，UseCompressedOops参数从HotSpot 19开始终于开始受ergonomics控制，会在下述条件满足的时候默认开启<a style="text-decoration: none" href="http://www.ygclb.com/"><font color="black">管道磁力泵</font></a>：</p>
<p>　　1、是64位系统（#ifdef _LP64）并且不是client VM（#ifndef COMPILER1）；</p>
<p>　　2、Java堆的最大大小不大于一个阈值（MaxHeapSize &lt;= max_heap_for_compressed_oops（））；</p>
<p>　　3、没有通过。hotspotrc或命令行参数手动设定过UseCompressedOops参数的值；</p>
<p>　　4、没有使用Garbage-First （G1） GC.</p><br />第1、3、4点都很直观，于是第2点就是个关键点了：阈值是多大？ 
<p>　　还是看回代码，HotSpot 20：</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><span class="tag"><li class="alt"><span class="keyword"><strong>void</strong></span><span>&nbsp;set_object_alignment()&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Object&nbsp;alignment.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;assert(is_power_of_2(ObjectAlignmentInBytes),&nbsp;</span><span class="string"><font color="#0000ff">"ObjectAlignmentInBytes&nbsp;must&nbsp;be&nbsp;power&nbsp;of&nbsp;2"</font></span><span>);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;MinObjAlignmentInBytes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;ObjectAlignmentInBytes;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;assert(MinObjAlignmentInBytes&nbsp;&gt;=&nbsp;HeapWordsPerLong&nbsp;*&nbsp;HeapWordSize,&nbsp;<br /></span><span class="string"><font color="#0000ff">"ObjectAlignmentInBytes&nbsp;value&nbsp;is&nbsp;too&nbsp;small"</font></span><span>);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;MinObjAlignment&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;MinObjAlignmentInBytes&nbsp;/&nbsp;HeapWordSize;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;assert(MinObjAlignmentInBytes&nbsp;==&nbsp;MinObjAlignment&nbsp;*&nbsp;HeapWordSize,&nbsp;<br /></span><span class="string"><font color="#0000ff">"ObjectAlignmentInBytes&nbsp;value&nbsp;is&nbsp;incorrect"</font></span><span>);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;MinObjAlignmentInBytesMask&nbsp;=&nbsp;MinObjAlignmentInBytes&nbsp;-&nbsp;1;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;LogMinObjAlignmentInBytes&nbsp;&nbsp;=&nbsp;exact_log2(ObjectAlignmentInBytes);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;LogMinObjAlignment&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;LogMinObjAlignmentInBytes&nbsp;-&nbsp;LogHeapWordSize;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Oop&nbsp;encoding&nbsp;heap&nbsp;max&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;OopEncodingHeapMax&nbsp;=&nbsp;(uint64_t(max_juint)&nbsp;+&nbsp;1)&nbsp;&lt;&lt;&nbsp;LogMinObjAlignmentInBytes;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span class="keyword"><strong>inline</strong></span><span>&nbsp;uintx&nbsp;max_heap_for_compressed_oops()&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;Avoid&nbsp;sign&nbsp;flip.&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword"><strong>if</strong></span><span>&nbsp;(OopEncodingHeapMax&nbsp;&lt;&nbsp;MaxPermSize&nbsp;+&nbsp;os::vm_page_size())&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword"><strong>return</strong></span><span>&nbsp;0;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;LP64_ONLY(</span><span class="keyword"><strong>return</strong></span><span>&nbsp;OopEncodingHeapMax&nbsp;-&nbsp;MaxPermSize&nbsp;-&nbsp;os::vm_page_size());&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;NOT_LP64(ShouldNotReachHere();&nbsp;</span><span class="keyword"><strong>return</strong></span><span>&nbsp;0);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>}</span></li></span></font></span></code></code></font></code></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　（注：其中 （uint64_t（max_juint） + 1） 的值也被称为NarrowOopHeapMax，也就是2的32次方，0x100000000；</p>
<p>　　ObjectAlignmentInBytes在64位HotSpot上默认为8；</p>
<p>　　HeapWord在globalDefinitions.hpp里定义，大小跟一个char*一样；</p>
<p>　　HeapWordSize在同一个文件里定义，等于sizeof（HeapWord），在64位系统上值为8；</p>
<p>　　LogHeapWordSize也在同一文件里，在64位系统上定义为3）</p>
<p>　　跟踪一下里面几个参数的计算，在64位HotSpot上有，</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><span class="tag">
</span></font></span></code></code></font></code><ol class="dp-cpp"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><font color="#006699"><li class="alt"><span>ObjectAlignmentInBytes&nbsp;=&nbsp;8&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>MinObjAlignmentInBytes&nbsp;=&nbsp;8&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>HeapWordSize&nbsp;=&nbsp;8&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>MinObjAlignment&nbsp;=&nbsp;1&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>MinObjAlignmentInBytesMask&nbsp;=&nbsp;0x0111&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>LogMinObjAlignmentInBytes&nbsp;=&nbsp;3&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>LogHeapWordSize&nbsp;=&nbsp;3&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;_LP64&nbsp;&nbsp;&nbsp; </font></span><span>&nbsp;</span></li><li><span>LogMinObjAlignment&nbsp;=&nbsp;0&nbsp;&nbsp;&nbsp; &nbsp;</span></li></font></code></code></font></code><li class="alt"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><font color="#006699"><span>OopEncodingHeapMax&nbsp;=&nbsp;0x800000000&nbsp;</span><span class="comment"><font color="#008200">//&nbsp;32GB&nbsp;&nbsp;&nbsp;</font></span><span>&nbsp;</span></font></code></code></font></code></li></ol></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　于是，前面提到的第2个条件在64位HotSpot VM上默认是：</p>
<p>　　C++代码</p>
<div align="center">
<div id="dmk" align="center">
<div align="left"><code class="txcode"><code class="txcode"><font face="NSimsun"><code class="txcode"><code class="txcode"><span class="keyword"><font color="#006699"><li class="alt"><span class="tag"><span>MaxHeapSize&nbsp;+&nbsp;MaxPermSize&nbsp;+&nbsp;os::vm_page_size()&nbsp;&lt;=&nbsp;32GB</span></span></li></font></span></code></code></font></code></code></div></div></div><!--<span class="right ft12"><a href="#" target="_blank">转发此文到空间</a></span>-->

<p>　　os：：vm_page_size（）是操作系统的虚拟内存的分页大小，在Linux上等于sysconf（_SC_PAGESIZE）的值；在x86_64上的Linux默认分页大小为4KB.</p>
<p>　　MaxHeapSize的值基本上等于-Xmx参数设置的值（会根据分页大小、对齐等因素做调整）。</p>
<p>　　MaxPermSize就是perm gen设置的最大大小。</p>
<p>　　这下可以确认，在我现在用的环境里，当包括perm gen在内的GC堆大小在32GB - 4KB以下的时候，使用64位的JDK 6 update 23或更高版本就会自动开启UseCompressedOops功能<div><a href="http://www.ptcm.com/product/product_detail_215.html">浓硫酸液下泵</a>17 <a href="http://www.ptcm.com/product/product_detail_104.html">长轴液下泵</a>17 <a href="http://www.ptcm.com/product/product_detail_105.html">氟塑料液下泵</a>。<a href="http://www.ptcm.com/product/product_detail_207.html">潜水电泵</a>54 <a href="http://www.ptcm.com/product/product_detail_208.html">深井潜水泵</a>23 <a href="http://www.ptcm.com/product/product_detail_216.html">耐腐蚀液下泵</a></div></p><p><br /></p><img src ="http://www.blogjava.net/cangshi004/aggbug/371120.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-03-02 11:07 <a href="http://www.blogjava.net/cangshi004/archive/2012/03/02/371120.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入解析Java核心内容：JVM中的栈和局部变量</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/29/370972.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Wed, 29 Feb 2012 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/29/370972.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/370972.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/29/370972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/370972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/370972.html</trackback:ping><description><![CDATA[<p><span style="font-family: 黑体">深入解析Java核心内容：JVM中的栈和局部变量<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 总的来说，深入Java核心其实最主要包含个方面的内容：JVM中的栈和局部变量 Java内存分配原理&nbsp; Java垃圾回收机制&nbsp; Java中多态的实现机制 </span></p>
<p><strong>Java中的栈</strong></p>
<p>每当启用一个线程时，JVM就为他分配一个Java栈，栈是以帧为单位保存当前线程的运行状态。某个线程正在执行的方法称为当前方法，当前方法使用的栈帧称为当前帧，当前方法所属的类称为当前类，当前类的常量池称为当前常量池。当线程执行一个方法时，它会跟踪当前常量池。</p>
<p>每当线程调用一个Java方法时，JVM就会在该线程对应的栈中压入一个帧，这个帧自然就成了当前帧。当执行这个方法时，它使用这个帧来存储参数、局部变量、中间运算结果等等。</p>
<p>Java栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。所以我们不用考虑多线程情况下栈数据访问同步的情况。</p>
<p>像方法区和堆一样，Java栈和帧在内存中也不必是连续的,帧可以分布在连续的栈里，也可以分布在堆里</p>
<p><strong>Java栈的组成元素&#8212;&#8212;栈帧</strong></p>
<p>栈帧由三部分组成：局部变量区、操作数栈、帧数据区。局部变量区和操作数栈的大小要视对应的方法而定，他们是按字长计算的。但调用一个方法时，它从类型信息中得到此方法局部变量区和操作数栈大小，并据此分配栈内存，然后压入Java栈。</p>
<p>局部变量区 局部变量区被组织为以一个字长为单位、从0开始计数的数组，类型为short、byte和char的值在存入数组前要被转换成int值，而long和 double在数组中占据连续的两项，在访问局部变量中的long或double时，只需取出连续两项的第一项的索引值即可,如某个long值在局部变量区中占据的索引时3、4项，取值时，指令只需取索引为3的long值即可。</p>
<p>下面就看个例子，好让大家对局部变量区有更深刻的认识。这个图来自《深入JVM》：</p><pre><ol class="dp-j"><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;runClassMethod(</span><span class="keyword">int</span><span>&nbsp;i,</span><span class="keyword">long</span><span>&nbsp;l,</span><span class="keyword">float</span><span>&nbsp;f,</span><span class="keyword">double</span><span>&nbsp;d,Object&nbsp;o,</span><span class="keyword">byte</span><span>&nbsp;b)&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="number">0</span><span>;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;runInstanceMethod(</span><span class="keyword">char</span><span>&nbsp;c,</span><span class="keyword">double</span><span>&nbsp;d,</span><span class="keyword">short</span><span>&nbsp;s,</span><span class="keyword">boolean</span><span>&nbsp;b)&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="number">0</span><span>;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; &nbsp;</span></li></ol></pre>
<p>上面代码片的方法参数和局部变量在局部变量区中的存储结构如下图：</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201107/20110727145124188.jpg" target="_blank"><img class="fit-image" alt="局部变量区的存储结构" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145124188.jpg" border="0" height="263" width="498" /></a></p>
<p>上面这个图没什么好说的，大家看看就会懂。但是，在这个图里，有一点需要注意：</p>
<p>runInstanceMethod的局部变量区第一项是个reference（引用），它指定的就是对象本身的引用，也就是我们常用的this,但是在runClassMethod方法中，没这个引用，那是因为runClassMethod是个静态方法。 </p><br />
<p>操作数栈和局部变量区一样，操作数栈也被组织成一个以字长为单位的数组。但和前者不同的是，它不是通过索引来访问的，而是通过入栈和出栈来访问的。可把操作数栈理解为存储计算时，临时数据的存储区域。下面我们通过一段简短的程序片段外加一幅图片来了解下操作数栈的作用。</p>
<p>int a = 100;</p>
<p>int b = 98;</p>
<p>int c = a+b;</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127435.jpg" target="_blank"><img class="fit-image" alt="操作数栈的结构" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127435.jpg" border="0" height="207" width="477" /></a></p>
<p>从图中可以得出：操作数栈其实就是个临时数据存储区域，它是通过入栈和出栈来进行操作的。</p>
<p>帧数据区除了局部变量区和操作数栈外，Java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。这些数据都保存在Java栈帧的帧数据区中。<br />当JVM执行到需要常量池数据的指令时，它都会通过帧数据区中指向常量池的指针来访问它。</p>
<p>除了处理常量池解析外，帧里的数据还要处理Java方法的正常结束和异常终止。如果是通过return正常结束，则当前栈帧从Java栈中弹出，恢复<a style="text-decoration: none" href="http://www.ygyxb.com/"><font color="black">玻璃钢液下泵</font></a>发起调用的方法的栈。如果方法又返回值，JVM会把返回值压入到发起调用方法的操作数栈。</p>
<p>为了处理Java方法中的异常情况，帧数据区还必须保存一个对此方法异常引用表的引用。当异常抛出时，JVM给catch块中的代码。如果没发现，方法立即终止，然后JVM用帧区数据的信息恢复发起调用的方法的帧。然后再发起调用方法的上下文重新抛出同样的异常。</p>
<p><strong>栈的整个结构</strong></p>
<p>在前面就描述过：栈是由栈帧组成，每当线程调用一个Java方法时，JVM就会在该线程对应的栈中压入一个帧，而帧是由局部变量区、操作数栈和帧数据区组成。那在一个代码块中，栈到底是什么形式呢？下面是我从《深入JVM》中摘抄的一个例子，大家可以看看：</p>
<p>代码片段：</p>
<p style="text-align: left"><a href="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127354.jpg" target="_blank"><img class="fit-image" alt="栈的整个结构代码示例" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127354.jpg" border="0" height="213" width="451" /></a></p>
<p>&nbsp;</p>
<p>执行过程中的三个快照：</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127315.jpg" target="_blank"><img class="fit-image" alt="" src="http://java.itwaka.com/UploadFiles_4554/201107/20110727145127315.jpg" border="0" height="262" width="498" /></a></p>
<p>&nbsp;</p>
<p>上面所给的图，只想说明两件事情，我们也可用此来理解Java中的栈：</p>
<p>1、只有在调用一个方法时，才为当前栈分配一个帧，然后将该帧压入栈。</p>
<p>2、帧中存储了对应方法的局部数据，方法执行完，对应的帧则从栈中弹出，并把返回结果存储在调用方法的帧的操作数栈中。</p><p><div><a href="http://www.ptcm.com/product/product_detail_53.html">立式多级泵</a>34 <a href="http://www.ptcm.com/product/product_detail_74.html">卧式多级泵</a>24 <a href="http://www.ptcm.com/product/product_detail_76.html">多级离心泵</a>41 <a href="http://www.ptcm.com/product/product_detail_255.html">不锈钢多级泵</a>31 <a href="http://www.ptcm.com/product/product_detail_186.html">水环真空泵</a>32 <a href="http://www.ptcm.com/product/product_detail_189.html">旋片真空泵</a></div><br /></p><img src ="http://www.blogjava.net/cangshi004/aggbug/370972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-29 10:52 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/29/370972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用DES加密Java源码的原因应用分析</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/09/369665.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Thu, 09 Feb 2012 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/09/369665.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/369665.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/09/369665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/369665.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/369665.html</trackback:ping><description><![CDATA[<p>　&nbsp;&nbsp; 加密利用：DES加密Java源码的原因应用分析<br />　　Java源代码经过编译以后在JVM中执行。由于JVM界面是完全透明的，Java类文件能够很容易通过反编译器重新转换成源代码。因此，所有的算法、类文件等都可以以源代码的形式被公开，使得软件不能受到保护，为了保护产权，一般可以有以下几种方法：</p>
<p>　　（1）"模糊"类文件，加大反编译器反编译源代码文件的难度。然而，可以修改反编译器，使之能够处理这些模糊类文件。所以仅仅依赖"模糊类文件"来保证代码的安全是不够的。</p>
<p>　　（2）流行的加密工具对源文件进行加密，比如PGP（Pretty Good Privacy）或GPG（GNU Privacy Guard）。这时，最终用户在运行应用之前必须先进行解密。但解密之后，最终用户就有了一份不加密的类文件，这和事先不进行加密没有什么差别。</p>
<p>　　（3）加密类文件，在运行中JVM用定制的类装载器（Class Loader）解密类文件。Java运行时装入字节码的机制隐含地意味着可以对字节码进行修改。JVM每次装入类文件时都需要一个称为ClassLoader的对象，这个对象负责把新的类装入正在运行的JVM。JVM给ClassLoader一个包含了待装入类（例如java.lang.Object）名字的字符串，然后由ClassLoader负责找到类文件，装入原始数据，并把它转换成一个Class对象。</p>
<p>　　用户下载的是加密过的类文件，在加密类文件装入之时进行解密，因此可以看成是一种即时解密器。由于解密后的字节码文件永远不会保存到文件系统，所以窃密者很难得到解密后的代码。</p>
<p>　　由于把原始字节码转换成Class对象的过程完全由系统负责，所以创建定制ClassLoader对象其实并不困难，只需先获得原始数据，接着就可以进行包含解密在内的任何转换。</p>
<p>　　Java密码体系和Java密码扩展</p>
<p>　　Java密码体系(JCA)和Java密码扩展(JCE)的设计目的是为Java提供与实现无关的加密函数API。它们都用factory方法来创建类的例程，然后把实际的加密函数委托给提供者指定的底层引擎,引擎中为类提供了服务提供者接口在Java中实现数据的加密/解密，是使用其内置的JCE(Java加密扩展)来实现的。Java开发工具集1.1为实现包括数字签名和信息摘要在内的加密功能，推出了一种基于供应商的新型灵活应用编程接口。Java密码体系结构支持供应商的互操作,同时支持硬件和软件实现。</p>
<p>　　Java密码学结构设计遵循两个原则:</p>
<p>　　(1)算法的独立性和可靠性。</p>
<p>　　(2)实现的独立性和相互作用性。</p>
<p>　　算法的独立性是通过定义密码服务类来获得。用户只需了解密码算法的概念,而不用去关心如何实现这些概念。实现的独立性和相互作用性通过密码服务提供器来实现。密码服务提供器是实现一个或多个密码服务的一个或多个程序包。软件开发商根据一定接口,将各种算法实现后,打包成一个提供器,用户可以安装不同的提供器。安装和配置提供器,可将包含提供器的ZIP和JAR文件放在CLASSPATH下,再编辑Java安全属性文件来设置定义一个提供器。Java运行环境Sun版本时, 提供一个缺省的提供器Sun。</p>
<p>　　下面介绍DES算法及如何利用DES算法加密和解密类文件的步骤。</p>
<p>　　DES算法简介</p>
<p>　　DES（Data Encryption Standard）是发明最早的最广泛使用的分组对称加密算法。DES算法的入口参数有三个：Key、Data、Mode。其中Key为8个字节共64位，是DES算法的工作密钥；Data也为8个字节64位，是要被加密或被解密的数据；Mode为DES的工作方式，有两种：加密或解密。</p>
<p>　　DES算法工作流程如下：若Mode为加密模式，则利用Key 对数据Data进行加密， 生成Data的密码形式（64位）作为DES的输出结果；如Mode为解密模式，则利用Key对密码形式的数据Data进行解密，还原为Data的明码形式（64位）作为DES的输出结果。在<a href="http://www.dtzxf.com/"><font color="black">上海针型阀</font></a>通信网络的两端，双方约定一致的Key，在通信的源点用Key对核心数据进行DES加密，然后以密码形式在公共通信网（如电话网）中传输到通信网络的终点，数据到达目的地后，用同样的Key对密码数据进行解密，便再现了明码形式的核心数据。这样，便保证了核心数据在公共通信网中传输的安全性和可靠性。</p>
<p>　　也可以通过定期在通信网络的源端和目的端同时改用新的Key，便能更进一步提高数据的保密性。<br />　　利用DES算法加密的步骤</p>
<p>　　（1）生成一个安全密钥。在加密或解密任何数据之前需要有一个密钥。密钥是随同被加密的应用程序一起发布的一段数据，密钥代码如下所示。</p>
<p>　　【生成一个密钥代码】</p>
<p>view plaincopy to clipboardprint?<br />// 生成一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />// 为我们选择的DES算法生成一个KeyGenerator对象<br />KeyGenerator kg = KeyGenerator.getInstance ("DES" );<br />Kg.init (sr);<br />// 生成密钥<br />Secret Key key = kg.generateKey();<br />// 将密钥数据保存为文件供以后使用，其中key Filename为保存的文件名<br />Util.writeFile (key Filename, key.getEncoded () );<br />// 生成一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />// 为我们选择的DES算法生成一个KeyGenerator对象<br />KeyGenerator kg = KeyGenerator.getInstance ("DES" );<br />Kg.init (sr);<br />// 生成密钥<br />Secret Key key = kg.generateKey();<br />// 将密钥数据保存为文件供以后使用，其中key Filename为保存的文件名<br />Util.writeFile (key Filename, key.getEncoded () );</p>
<p>　　（2）加密数据。得到密钥之后，接下来就可以用它加密数据。如下所示。</p>
<p>　　【用密钥加密原始数据】</p>
<p>&nbsp;</p>
<p>view plaincopy to clipboardprint?<br />// 产生一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />//从密钥文件key Filename中得到密钥数据<br />Byte rawKeyData = Util.readFile (key Filename);<br />// 从原始密钥数据创建DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创建一个密钥工厂，然后用它把DESKeySpec转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );<br />Secret Key key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成加密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />cipher.init( Cipher.ENCRYPT_MODE, key, sr );<br />// 通过读类文件获取需要加密的数据<br />Byte data = Util.readFile (filename);<br />// 执行加密操作<br />Byte encryptedClassData = cipher.doFinal(data );<br />// 保存加密后的文件，覆盖原有的类文件。<br />Util.writeFile( filename, encryptedClassData );<br />// 产生一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />//从密钥文件key Filename中得到密钥数据<br />Byte rawKeyData = Util.readFile (key Filename);<br />// 从原始密钥数据创建DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创建一个密钥工厂，然后用它把DESKeySpec转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance("DES" );<br />Secret Key key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成加密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />cipher.init( Cipher.ENCRYPT_MODE, key, sr );<br />// 通过读类文件获取需要加密的数据<br />Byte data = Util.readFile (filename);<br />// 执行加密操作<br />Byte encryptedClassData = cipher.doFinal(data );<br />// 保存加密后的文件，覆盖原有的类文件。<br />Util.writeFile( filename, encryptedClassData );</p>
<p>&nbsp;</p>
<p>　　（3）解密数据。运行经过加密的程序时，ClassLoader分析并解密类文件。操作步骤如下所示。</p>
<p>　　【用密钥解密数据】</p>
<p>view plaincopy to clipboardprint?<br />// 生成一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />// 从密钥文件中获取原始密钥数据<br />Byte rawKeyData = Util.readFile( keyFilename );<br />// 创建一个DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创建一个密钥工厂，然后用它把DESKeySpec对象转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );<br />SecretKey key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成解密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />Cipher.init( Cipher.DECRYPT_MODE, key, sr );<br />// 获得经过加密的数据<br />Byte encrypted Data = Util.readFile (Filename);<br />//执行解密操作<br />Byte decryptedData = cipher.doFinal( encryptedData );<br />// 然后将解密后的数据转化成原来的类文件。<br />// 生成一个可信任的随机数源<br />SecureRandom sr = new SecureRandom();<br />// 从密钥文件中获取原始密钥数据<br />Byte rawKeyData = Util.readFile( keyFilename );<br />// 创建一个DESKeySpec对象<br />DESKeySpec dks = new DESKeySpec (rawKeyData);<br />// 创建一个密钥工厂，然后用它把DESKeySpec对象转换成Secret Key对象<br />SecretKeyFactory key Factory = SecretKeyFactory.getInstance( "DES" );<br />SecretKey key = keyFactory.generateSecret( dks );<br />// Cipher对象实际完成解密操作<br />Cipher cipher = Cipher.getInstance( "DES" );<br />// 用密钥初始化Cipher对象<br />Cipher.init( Cipher.DECRYPT_MODE, key, sr );<br />// 获得经过加密的数据<br />Byte encrypted Data = Util.readFile (Filename);<br />//执行解密操作<br />Byte decryptedData = cipher.doFinal( encryptedData );<br />// 然后将解密后的数据转化成原来的类文件。</p>
<p>　　将上述代码与自定义的类装载器结合就可以做到边解密边运行，从而起到保护源代码的作用。</p>
<p>　　结束语</p>
<p>　　加密/解密是数据传输中保证数据安全性和完整性的常用方法，Java语言因其平台无关性，在Internet上的应用非常之广泛。使用DES算法加密Java源码在一定程度上能保护软件的产权。</p>
<p>&nbsp;</p><img src ="http://www.blogjava.net/cangshi004/aggbug/369665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-09 13:34 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/09/369665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java如何通过远程方法调用RMI</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/09/369645.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Thu, 09 Feb 2012 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/09/369645.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/369645.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/09/369645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/369645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/369645.html</trackback:ping><description><![CDATA[公司做web service的时候，看了一下资料，当时看见一个叫rmi的东西（远程方法调用）,最近闲着，所以看了一下 ，感觉挺简单的！所以写了一个例子提供给大家把！ 
<p>rmi的服务端，必须要使用接口，同时还有接口的实现类！所以下面的两个文件是接口类和接口的实现类！</p>
<p>UserDao 接口：</p><pre><ol class="dp-j"><li class="alt"><span class="comment">/** </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;远程接口&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;必须继承与Remote对象 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;@author&nbsp;spring&nbsp;sky </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;date:&nbsp;2012年2月7日&nbsp;10:55:05 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;Email:vipa1888@163.com </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;QQ:840950105 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*/</span><span>&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;UserDao&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Remote{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</li><li><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;简单的测试方法 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;name </span>&nbsp;</li><li><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;sayName(String&nbsp;name)&nbsp;</span><span class="keyword">throws</span><span>&nbsp;RemoteException;&nbsp; &nbsp;</span></li><li><span>&nbsp;</span></li><li class="alt"><span>&nbsp;</span></li><li><span>}&nbsp;</span></li></ol></pre>
<p>UserDaoImpl实现类</p><pre><ol class="dp-j"><li class="alt"><span class="comment">/** </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp; </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;&nbsp;接口的实现类&nbsp;&nbsp;&nbsp;&nbsp;必须继承UnicastRemoteObject(单一远程对象)&nbsp;&nbsp;&nbsp;实现UserDao自己的接口 </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;@author&nbsp;spring&nbsp;sky </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;date:&nbsp;2012年2月7日&nbsp;10:56:05 </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;Email:vipa1888@163.com </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;QQ:840950105 </span>&nbsp;</li><li><span class="comment">&nbsp;*/</span><span>&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;UserDaoImpl&nbsp;</span><span class="keyword">extends</span><span>&nbsp;UnicastRemoteObject&nbsp;</span><span class="keyword">implements</span><span>&nbsp;UserDao&nbsp;{ &nbsp;</span></li><li><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;UserDaoImpl()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;RemoteException&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="annotation">@Override</span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;sayName(String&nbsp;name)&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(name!=</span><span class="keyword">null</span><span>&amp;&amp;!name.equals(</span><span class="string">""</span><span>)) &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"我的名字是："</span><span>+name); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span class="keyword">else</span><span>{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"名字不为空...."</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li><span>&nbsp;</span></li><li class="alt"><span>}&nbsp;</span></li></ol></pre>
<p>对外的提供一个服务，服务中已经共享了url给外界访问</p><pre><ol class="dp-j"><li class="alt"><span class="comment">/** </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;使用main方法启动一个服务，用于外界环境访问 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;@author&nbsp;spring&nbsp;sky </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;date:2012年2月7日&nbsp;10:57:37 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;Email:vipa1888@163.com </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;QQ:840950105 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*/</span><span>&nbsp;</span></li><li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;StartService&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;String&nbsp;IP&nbsp;=&nbsp;</span><span class="string">"127.0.0.1"</span><span>; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;PORT&nbsp;=&nbsp;</span><span class="number">9999</span><span>; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;String&nbsp;REMOTE_NAME&nbsp;=&nbsp;</span><span class="string">"userDao"</span><span>; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;String&nbsp;REMOTE_URL&nbsp;=&nbsp;</span><span class="string">"rmi://"</span><span>+IP+</span><span class="string">":"</span><span>+PORT+</span><span class="string">"/"</span><span>+REMOTE_NAME; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserDao&nbsp;userDao&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;UserDaoImpl();&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//实例化对象 </span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocateRegistry.createRegistry(PORT);&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//注册端口 </span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Naming.bind(REMOTE_URL,&nbsp;userDao);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//绑定远程服务对象 </span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"远程"</span><span>+REMOTE_NAME+</span><span class="string">"启动成功...."</span><span>); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(RemoteException&nbsp;e)&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"远程对象出错"</span><span>); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(MalformedURLException&nbsp;e)&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"URL出错了"</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(AlreadyBoundException&nbsp;e)&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"绑定的对象已经存在了"</span><span>); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li><span>}&nbsp;</span></li></ol></pre>
<p>上面是服务端的代码，如果启动没有任何问题，就可以做客户端访问了，其实<font color="black">上海旋塞阀</font>客户端的访问更加的简单，只需要远程的接口类和查询rmi中的url就可以了！</p>
<p>代码如下：</p><pre><ol class="dp-j"><li class="alt"><span class="comment">/** </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;远程方法调用测试 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;@author&nbsp;spring&nbsp;sky </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;date:2012年2月7日&nbsp;11:12:46 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;Email:vipa1888@163.com </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;QQ:840950105 </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;name:石明政 </span>&nbsp;</li><li><span class="comment">&nbsp;*/</span><span>&nbsp;</span></li><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestRemote&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//在rmi服务中查询userdao的对象 </span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserDao&nbsp;userDao&nbsp;=&nbsp;(UserDao)&nbsp;Naming.lookup(</span><span class="string">"rmi://127.0.0.1:9999/userDao"</span><span>);&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//调用远程服务的方法 </span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;userDao.sayName(</span><span class="string">"spring&nbsp;sky"</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(MalformedURLException&nbsp;e)&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"URL出错"</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(RemoteException&nbsp;e)&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"远程对象出错"</span><span>); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(NotBoundException&nbsp;e)&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(</span><span class="string">"没有找到绑定的对象"</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>}&nbsp;</span></li></ol></pre>
<p>以上就是所有的rmi远程调用代码了！运行结果如下：</p>
<p><a href="http://java.itwaka.com/UploadFiles_4554/201202/20120207160348249.jpg" target="_blank"><img class="fit-image" alt="" src="http://java.itwaka.com/UploadFiles_4554/201202/20120207160348249.jpg" border="0" height="104" width="325" /></a></p>
<p>好了，本人也只是简单的了解了rmi，如果以后有项目做rmi就可以深入了！ 呵呵&nbsp; ，在这里我突然感觉，想web service也应该和他一样的原理的把！</p><p><div>	<a href="http://www.ptcm.com/product/product_detail_231.html">卧式自吸泵</a>43 	<a href="http://www.ptcm.com/product/product_detail_182.html">不锈钢转子泵 </a><br /><div><a href="http://www.ptcm.com/product/product_detail_49.html">立式排污泵</a>12 <a href="http://www.ptcm.com/product/product_detail_48.html">管道排污泵</a>26 <a href="http://www.ptcm.com/product/product_detail_50.html">液下排污泵</a></div><br /><a href="http://www.ptcm.com/product/product_detail_182.html"></a></div><br /></p><img src ="http://www.blogjava.net/cangshi004/aggbug/369645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-09 10:53 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/09/369645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA J2ME编程 横竖屏切换知识总结</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/07/369516.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Tue, 07 Feb 2012 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/07/369516.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/369516.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/07/369516.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/369516.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/369516.html</trackback:ping><description><![CDATA[<p>随着手机的功能越来越丰富，支持横竖屏切换的手机越来越多，在手机软件开发中也必须要处理这个功能了。下面对于使用<strong>J2ME</strong>技术进行编程时对于横竖屏(转屏)切换时的相关知识进行一下小结。</p>
<p><strong>1、如何判断横竖屏切换</strong></p>
<p>横竖屏切换由手机系统自动完成的，在J2ME中只能检测到这种变换，判断横竖屏切换的方法有2种：</p>
<p><strong>A)线程中每次检测法(轮询方式)</strong></p>
<p>这种方式是在程序的线程中每隔一定的时间间隔，就获得一次屏幕的宽度和高度，然后判断宽度和高度是否变化，如果宽度和高度和已有的宽度和高度相比发生了变化，至于是变化成横屏还是竖屏则只需要比较宽高就可以实现。在判断到横竖屏切换时，执行逻辑代码即可。</p>
<p>使用这种方式由于每次线程循环都需要检测，所以执行效率不高，但是由于一些转屏手机不支持sizeChanged的方法回调，所以使用这种方式的通用性是最高的，是经常被使用的方法。</p>
<p><strong>B)sizeChanged法(中断方式)</strong></p>
<p>这种方式是指如果转屏手机对于MIDP支持比较规范，则当横竖屏切换时会自动调用Canvas类中的sizeChanged方法，这样就需要在Canvas的子类中覆盖该方法即可，在该方法内部书写横竖屏切换的逻辑处理代码即可。</p>
<p>使用这种方式由于是系统自动调用，所以执行效率很好，但是由于部分手机实现的不规范，所以通用性没有第一种方式高。</p>
<p>说明：高级用户界面自动切换，不需要书写处理的代码。</p>
<p><strong>2、如何处理横竖屏切换</strong></p>
<p>在检测到横竖屏切换以后，就需要对于横竖屏切换进行处理了，处理的方式一般有也有两种：</p>
<p><strong>A)简单提示法</strong></p>
<p>这种处理方式时指只实现一种屏幕模式下的逻辑，而在另外一种屏幕方式下显示提示。例如只实现竖屏模式的界面，在横屏模式下，只出现提示：&#8220;请在竖屏模式下使用本程序&#8221;。</p>
<p>使用这种方式程序实现比较简单，只需要实现一套界面即可，适合于比较简单的程序。</p>
<p><strong>B)实现两套UI法</strong></p>
<p>这种处理方式时指在一个程序中实现两套界面：一套横屏一套竖屏。可以在程序中设置一个screenType的参数，在每个节目的绘制<font color="black">上海电磁阀</font>方法中根据该参数判断是横屏还是竖屏，然后执行不同的绘制代码即可。</p>
<p>使用这种方式程序实现比较友好，但是程序开发和测试的工作量都要稍微大一点，而且横竖屏切换时数据的变换也比较麻烦。</p>
<p><strong>3、其它说明</strong></p>
<p>在实现横竖屏切换时，有些知识会帮助你实现一些很实用的功能：</p>
<p><strong>在Nokia手机上禁止横竖屏切换：</strong></p>
<p>在S60 5th 及以上版本中，可以通过在jad或manifest文件中通过指定如下属性来指定程序运行时的屏幕类型：</p>
<p>竖屏：Nokia-MIDlet-App-Orientation：portrait</p>
<p>横屏：Nokia-MIDlet-App-Orientation：landscape</p>
<p>不足之处希望大家积极指正、交流和完善！</p><p><div>	<a href="http://www.ptcm.com/news/news_detail_1996.html">加药计量泵</a>25 	<a href="http://www.ptcm.com/product/product_detail_114.html">隔膜计量泵</a>35 	<a href="http://www.ptcm.com/news/news_detail_571.html">电磁隔膜计量泵</a>51 	<a href="http://www.ptcm.com/product/product_detail_109.html">液压隔膜计量泵</a>24 	<a href="http://www.ptcm.com/product/product_detail_113.html">机械隔膜计量泵</a>18	 	<a href="http://www.ptcm.com/product/product_detail_83.html">柱塞计量泵</a></div><br /></p><img src ="http://www.blogjava.net/cangshi004/aggbug/369516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-07 10:53 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/07/369516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在NetBeans Java ME polish环境下开发BlackBerry应用</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/03/369347.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Fri, 03 Feb 2012 14:32:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/03/369347.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/369347.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/03/369347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/369347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/369347.html</trackback:ping><description><![CDATA[<p>　　在网上广为流传的一份BlackBerry应用程序开发者指南里边详细介绍如何用BlackBerry API开发BlackBerry application的各方面内容。</p>
<p>　　但是我们一般都是用Java ME开发，开发出来的程序是jar格式，可以运行在大部分型号的手机上。可是BlackBerry是不支持jar的，它支持的是cod格式。所以如果你想你开发的Java ME程序运行在BlackBerry上，就必须先把它转为cod格式。</p>
<p>　　要把一般Java ME程序转为cod可以在程序开发编译过程序中转，也可以对打包好的jar转。</p>
<p>　　&#9670;对已经打包好的jar文件转为BlackBerrycod格式:进入jar文件所在目录，在cmd(命令行)中进入相应目录，输入下边命令就可以了：引用rapc import="C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\lib\net_rim_api.jar" codename=TestBB jad=TestBB.jad TestBB.jar</p>
<p>　　(注：这里rapc 是 C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\bin\ 目录里的 rapc.exe, 如果环境变量没有设置，这里就要用绝对路径：C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\bin\rapc, 当然你可以把它写成一个.bat文件来执行。而网上你可以搜索到一个名为Java2Cod.exe的小程序可以直接转换。)</p>
<p>　　&#9670;在JDE中编译程序:无论你是用BlackBerry API或者Java ME/midp API来开发Java ME程序，都可以在JDE上编译。最终他会自动打包成cod文件。</p>
<p>　　&#9670;在其IDE中编译打包：因为我是用NetBeans来开发的，所以本人只能提供NetBeans开发BlackBerry程序的见解。而本人是在 NetBeans中用Java ME polish来整合开发的。下边介绍Java ME polish中开发BlackBerry程序</p>
<p>　　（可以参考<a href="http://www.j2mepolish.org/docs/platform-blackberry.html" rel="nofollow"><u><font color="#0000ff">http://www.j2mepolish.org/docs/platform-blackberry.html</font></u></a>）</p>
<p>　　一、在Java ME polish安装目录里找到platforms.xml,在里边的BlackBerry部分中，加上&lt;capability name="build.Finalizer" value="jar2cod" /&gt;（我用的是Preview 2.0版本，里边这一句是注释掉，所以要把它activate，也可以在devices.xml中在你想用的emulator 属性里加上这一句。如果没有这一句编译时就不会自动把jar转换为cod文件的.）</p>
<p>　　polish里支持的版本最新系4.2.0,如果你安装BlackBerry版本最新的如4.2.1/4.3.0,哪么你要把${BlackBerry目录}/lib/net_rim_API.jar copy到${Java MEpolish}/import里，在platforms.xml的BlackBerry中修改&lt;capability name="build.BootClassPath" value="net_rim_API.jar" /&gt;</p>
<p>　　二、在工程的build.xml中添加blackberry.home属性（你安装的BlackBerry JDE目录）</p>
<p><strong>　　Java代码</strong></p>
<div align="center">
<div id="dmk">
<div align="left">
<ol><li class="alt"><span>&lt;property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name=</span><span class="string">"blackberry.home"</span><span>&nbsp;</span></li><li><span>&nbsp;location=</span><span class="string">"C:/Program&nbsp;Files/Research&nbsp;In&nbsp;Motion/BlackBerry&nbsp;JDE&nbsp;4.2.1"</span><span>&nbsp;</span><span>/&gt;&nbsp;</span></li></ol></div></div></div>
<p>　　三、如果你编译后打包的jad文件中缺少MicroEdition-Configuration和MicroEdition-Profile两个属性是不能成功转成cod文件的。这可以在工程的build.xml中的&lt;build&gt;属性里的&lt;jad&gt;元素中添加：</p>
<p><strong>　　Java代码</strong></p>
<div align="center">
<div id="dmk">
<div align="left"><pre><li><span>&lt;jad&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;target=</span><span class="string">"jad"</span><span>&nbsp;name=</span><span class="string">"<br />MicroEdition-Configuration"</span><span>&nbsp;value=</span><span class="string">"CLDC-1.1"</span><span>&nbsp;</span></li><li class="alt"><span class="keyword">if</span><span>=</span><span class="string">"polish.cldc11"</span><span>/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute&nbsp;target=</span><span class="string">"jad"</span><span>&nbsp;<br />name=</span><span class="string">"MicroEdition-Profile"</span><span>&nbsp;value=</span><span class="string">"MIDP-2.0"</span><span>/&gt;&nbsp;&nbsp; &nbsp;</span></li><li><span>&lt;/jad&gt;</span></li></pre></div></div></div><br />
<p>　　四、如果你用了混淆器的（obfuscator），要把它unactivate,不要用它，因为BlackBerry中的rapc转换过程中会对程序混淆的。</p>
<p><strong>　　Java代码</strong></p>
<div id="dmk">
<div align="left"><pre><li class="alt"><span>&lt;obfuscator&nbsp;name=</span><span class="string">"ProGuard"</span><span>&nbsp;unless=</span><span class="string">"test&nbsp;or&nbsp;polish.blackberry"</span><span>&nbsp;&gt;&nbsp;&nbsp; &nbsp;</span></li><li><span>&lt;/obfuscator&gt;</span></li></pre></div></div>
<p>　　五、在工程的build.xml中的&lt;Java MEpolish&gt;属性requirements用你想编译的BlackBerryemulator,如：</p>
<p><strong>　　Java代码</strong></p>
<div align="center">
<div id="dmk">
<div align="left"><pre><li class="alt"><span class="tag">&lt;</span><span class="tag-name">deviceRequirements</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span class="tag">&lt;</span><span class="tag-name">requirement</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"Identifier"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"BlackBerry/8800"</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span class="tag">&lt;/</span><span class="tag-name">deviceRequirements</span><span class="tag">&gt;</span></li></pre></div></div></div>
<p>　　如果你的程序是一般的Java ME程序，那么就可以编译运行了。但如果你是用BlackBerry API开发的<font color="black">上海柱塞阀</font>，就要就把build.xml里&lt;build&gt;元素中的&lt;midlet&gt;,改为&lt;main&gt;，同时要添加polish.classes.midlet-1的variable。如：</p>
<p><strong>　　Java代码</strong></p>
<div id="dmk">
<div align="left"><pre><li class="alt"><span>&lt;!--&nbsp;midlets&nbsp;definition&nbsp;--&gt;&nbsp;&nbsp;&nbsp;<br />&lt;main&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"com.protel.BlackBerryim.ui.BlackBerryIMMidlet"</span><span>&nbsp;/&gt;&nbsp;&nbsp;&nbsp; &nbsp;</span></li><li><span>&lt;!--&nbsp;project-wide&nbsp;variables&nbsp;-&nbsp;used&nbsp;</span><span class="keyword">for</span><span>&nbsp;preprocessing&nbsp;&nbsp;--&gt;&nbsp;&nbsp;&nbsp;<br />&lt;variables&gt;&nbsp;&lt;variable&nbsp;name=</span><span class="string">"polish.classes.midlet-1"</span><span>&nbsp;value=</span><span class="string">"&nbsp;"</span><span>&nbsp;/&gt;&nbsp;&nbsp; &nbsp;</span></li><li class="alt"><span>&lt;/variables&gt;</span></li></pre></div></div>
<p>　　(注：polish.classes.midlet-1的value是" "，中间有一个空格的，我试过了，如果没有这个定义变量或者这个值中间没有空格，jar是不能转为cod格式。)</p>
<p>　　这是我初接触BlackBerry时的一点心得。我用BlackBerry API在NetBeans+Java ME polish的环境下写过一个test app，是能成功运行的，希望对初接触BlackBerry的朋友有帮助。</p><p>&nbsp;</p><div><a href="http://www.ptcm.com/product/product_detail_32.html">塑料离心泵</a>83 	<a href="http://www.ptcm.com/product/product_detail_242.html">卧式化工泵</a>15 	<a href="http://www.ptcm.com/news/news_detail_1500.html">不锈钢化工泵</a>45 	<a href="http://www.ptcm.com/product/product_detail_31.html">化工流程泵</a>26 	<a href="http://www.ptcm.com/product/product_detail_29.html">化工离心泵</a></div><br /><p>&nbsp;</p><img src ="http://www.blogjava.net/cangshi004/aggbug/369347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-03 22:32 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/03/369347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何通过Java调用C/C++编写第三方dll动态链接库解决方案分析</title><link>http://www.blogjava.net/cangshi004/archive/2012/02/02/369270.html</link><dc:creator>cangshi</dc:creator><author>cangshi</author><pubDate>Thu, 02 Feb 2012 14:44:00 GMT</pubDate><guid>http://www.blogjava.net/cangshi004/archive/2012/02/02/369270.html</guid><wfw:comment>http://www.blogjava.net/cangshi004/comments/369270.html</wfw:comment><comments>http://www.blogjava.net/cangshi004/archive/2012/02/02/369270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cangshi004/comments/commentRss/369270.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cangshi004/services/trackbacks/369270.html</trackback:ping><description><![CDATA[<p>如何通过Java调用C/C++编写第三方dll动态链接库解决方案分析。<br />最近在用weka做一个数据挖掘相关的项目，不得不说，weka还是一个不错的开放源代码库，提供了很多最常用的分类和聚类算法。</p>
<p>在我的项目中要用到一个聚类算法，Affinity Propagation（AP），由多伦多大学的Brendan J. Frey发表于2007年。相比其他的聚类算法，AP算法的聚类结果更加准确。</p>
<p>在AP的官方网站公布了AP算法的动态链接库，我的目标就是实现在Java工程中调用这个动态链接库。</p>
<p>在网上查了资料，发现，如果仅仅是想调用Windows的Native API还是比较省事的，这里我主要针对第三方dll的调用。</p>
<p>下面进入正题。</p>
<p>这里主要用的方法是JNI。在网上查资料时看到很多人说用JNI非常的复杂，不仅要看很多的文档，而且要非常熟悉C/C++编程。恐怕有很多人在看到诸如此类的评论时已经决定绕道用其他方法了。但是，假如你要实现的功能并不复杂（简单的参数传递，获取返回值等等），我还是支持使用这个方法的。</p>
<p>Java Native Interface，简称JNI，是Java平台的一部分，可用于让Java和其他语言编写的代码进行交互。下面是从网上摘取的JNI工作示意图。</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201201/20120110153807893.gif" target="_blank"><img class="fit-image" border="0" alt="" src="http://java.itwaka.com/UploadFiles_4554/201201/20120110153807893.gif" width="348" height="230" /></a><br />图1 JNI的工作模式</p>
<p>下面就举具体的例子说明一下使<strong>用步骤：</strong></p>
<p><strong>1） 编写一个类，声明native方法</strong></p><pre><ol class="dp-j"><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;APCluster&nbsp;{&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">int</span><span>[]&nbsp;CallAPClusterDll(&nbsp;</span><span class="keyword">int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg_Int,&nbsp; &nbsp;</span></li><li class="alt"><span>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">double</span><span>[]&nbsp;&nbsp;&nbsp;&nbsp;arg_DoubleArray,&nbsp; &nbsp;</span></li><li><span>&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg_boolean); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.loadLibrary(</span><span class="string">"APClusterDllMedium"</span><span>); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>}&nbsp;</span></li></ol></pre>
<p>上面是APCluster.java文件，定义了一个APCluster类，其中有一个方法CallAPClusterDll()，需要传递三种不同类型的参数，并且返回一个整型数组。</p>
<p>注意，这里只需要声明这个方法，并不需要实现，具体实现就在APClusterDllMedium中。</p>
<p>APClusterDllMedium就像中介一样，Java通过调用这个中介Dll中的CallAPClusterDll方法，间接调用真正的第三方Dll。</p>
<p><strong>2）编译生成.h文件</strong></p>
<p>第一步：</p>
<p>javac APCluster.java 生成APCluster.class</p>
<p>第二步：</p>
<p>javah APCluster 生成APCluster.h头文件，内容如下：</p><pre><ol class="dp-j"><li class="alt"><span class="comment">/*&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;*/</span><span>&nbsp;</span></li><li><span>#include&nbsp;&lt;jni.h&gt; &nbsp;</span></li><li class="alt"><span class="comment">/*&nbsp;Header&nbsp;for&nbsp;class&nbsp;APCluster&nbsp;*/</span><span>&nbsp;</span></li><li><span>#ifndef&nbsp;_Included_APCluster &nbsp;</span></li><li class="alt"><span>#define&nbsp;_Included_APCluster &nbsp;</span></li><li><span>#ifdef&nbsp;__cplusplus &nbsp;</span></li><li class="alt"><span>extern&nbsp;</span><span class="string">"C"</span><span>&nbsp;{ &nbsp;</span></li><li><span>#endif10&nbsp;</span><span class="comment">/* </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;Class:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APCluster </span>&nbsp;</li><li><span class="comment">&nbsp;*&nbsp;Method:&nbsp;&nbsp;&nbsp;&nbsp;CallAPClusterDll </span>&nbsp;</li><li class="alt"><span class="comment">&nbsp;*&nbsp;Signature:&nbsp;(I[DZ)[I </span>&nbsp;</li><li><span class="comment">&nbsp;*/</span><span>&nbsp;</span></li><li class="alt"><span>JNIEXPORT&nbsp;jintArray&nbsp;JNICALL&nbsp;Java_APCluster_CallAPClusterDll &nbsp;</span></li><li><span>&nbsp;&nbsp;(JNIEnv&nbsp;*,&nbsp;jobject,&nbsp;jint,&nbsp;jdoubleArray,&nbsp;jboolean); &nbsp;</span></li><li class="alt"><span>#ifdef&nbsp;__cplusplus &nbsp;</span></li><li><span>} &nbsp;</span></li><li class="alt"><span>#endif21</span></li><li class="alt"><span>#endif&nbsp;</span></li></ol></pre>
<p>注意，APCluster.h这个头文件的内容是不能修改的，否则JNI会找不到相对应的CallAPClusterDll()的实现。</p><br />
<p><strong>3）创建C/C++工程，实现CallAPClusterDll()方法。</strong></p>
<p>创建一个C/C++工程，工程名为APClusterDllMedium（其实，生成的dll名为APClusterDllMedium即可），导入APCluster.h这个头文件，并创建一个CPP文件，实现.h文件中的方法。</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201201/20120110153809444.png" target="_blank"><img class="fit-image" border="0" alt="" src="http://java.itwaka.com/UploadFiles_4554/201201/20120110153809444.png" width="279" height="150" /></a>&nbsp;<br />图2 新建工程结构</p>
<p>由于我创建的工程是win32控制台程序，所以最后默认生成的是.exe文件，所以还要做一步工程属性修改，让它生成.dll后缀文件。</p>
<p>打开Project Property -&gt;General，做以下修改：</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201201/20120110153810374.png" target="_blank"><img class="fit-image" border="0" alt="" src="http://java.itwaka.com/UploadFiles_4554/201201/20120110153810374.png" width="498" height="288" /></a>&nbsp;<br /><font size="2">图3 修改工程属性</font></p>
<p>下面就是实现 JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll (JNIEnv *, jobject, jint, jdoubleArray, jboolean); 这个方法了。先贴代码再慢慢解释吧。</p><pre><ol class="dp-j"><li class="alt"><span>#include&nbsp;</span><span class="string">"APCluster.h"</span><span>&nbsp; &nbsp;</span></li><li><span>#include&nbsp;&lt;stdio.h&gt;&nbsp; &nbsp;</span></li><li class="alt"><span>#include&nbsp;&lt;windows.h&gt; &nbsp;</span></li><li><span>#ifdef&nbsp;__cplusplus&nbsp; &nbsp;</span></li><li class="alt"><span>extern&nbsp;</span><span class="string">"C"</span><span>&nbsp;{ &nbsp;</span></li><li><span>#endif &nbsp;</span></li><li class="alt"><span>typedef&nbsp;</span><span class="keyword">int</span><span>*&nbsp;&nbsp;(__stdcall&nbsp;*APCLUSTER32)(</span><span class="keyword">double</span><span>*,&nbsp;unsigned&nbsp;</span><span class="keyword">int</span><span>,&nbsp;bool); &nbsp;</span></li><li><span>JNIEXPORT&nbsp;jintArray&nbsp;JNICALL&nbsp;Java_APCluster_CallAPClusterDll &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;(JNIEnv&nbsp;*env,&nbsp;jobject&nbsp;_obj,&nbsp;jint&nbsp;_arg_int,&nbsp;jdoubleArray&nbsp;_arg_doublearray,&nbsp;jboolean&nbsp;_arg_boolean) &nbsp;</span></li><li><span>{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;HMODULE&nbsp;dlh&nbsp;=&nbsp;NULL; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;APCLUSTER32&nbsp;apcluster32; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!(dlh=LoadLibrary(</span><span class="string">"apclusterwin.dll"</span><span>)))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//第三方DLL位置 </span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span class="string">"LoadLibrary()&nbsp;failed:&nbsp;%d\n"</span><span>,&nbsp;GetLastError());&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!(apcluster32&nbsp;=&nbsp;(APCLUSTER32)GetProcAddress(dlh,&nbsp;</span><span class="string">"apcluster32"</span><span>)))&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//具体调用apcluster32方法 </span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span class="string">"GetProcAddress()&nbsp;failed:&nbsp;%d\n"</span><span>,&nbsp;GetLastError());&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_int&nbsp;=&nbsp;_arg_int;&nbsp;&nbsp;</span><span class="comment">//类型转换 </span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">double</span><span>*&nbsp;&nbsp;&nbsp;&nbsp;m_doublearray&nbsp;=&nbsp;env-&gt;GetDoubleArrayElements(_arg_doublearray,&nbsp;NULL); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_boolean&nbsp;=&nbsp;_arg_boolean; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>*&nbsp;ret&nbsp;=&nbsp;(*apcluster32)(m_doublearray,&nbsp;m_int,&nbsp;m_boolean);&nbsp;</span><span class="comment">/*&nbsp;actual&nbsp;function&nbsp;call&nbsp;*/</span><span>&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;jintArray&nbsp;result&nbsp;=&nbsp;env-&gt;NewIntArray(_arg_int); &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;SetIntArrayRegion(result,&nbsp;</span><span class="number">0</span><span>,&nbsp;_arg_int,&nbsp;(</span><span class="keyword">const</span><span>&nbsp;jint*)ret); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;FreeLibrary(dlh);&nbsp;</span><span class="comment">/*&nbsp;unload&nbsp;DLL&nbsp;and&nbsp;free&nbsp;memory&nbsp;*/</span><span>&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(ret)&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;free(ret);&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;result; &nbsp;</span></li><li class="alt"><span>} &nbsp;</span></li><li><span>#ifdef&nbsp;__cplusplus &nbsp;</span></li><li class="alt"><span>} &nbsp;</span></li><li><span>#endif&nbsp;</span></li></ol></pre>
<p>a）首先为了#include &lt;jni.h&gt;，必须添加JNI所在的目录。</p>
<p>打开Project Property -&gt; C/C++ -&gt; General -&gt; Additional Include Directories添加相应目录：</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201201/20120110153810441.png" target="_blank"><img class="fit-image" border="0" alt="" src="http://java.itwaka.com/UploadFiles_4554/201201/20120110153810441.png" width="498" height="467" /></a>&nbsp;<br />图4 添加JNI目录</p>
<p>b）在APCluster.h文件中自动生成的函数，只标识了函数参数类型，为了引用这些参数，自己起一个相应的名字：</p>
<p>JNIEXPORT jintArray JNICALL Java_APCluster_CallAPClusterDll<br />(JNIEnv *env, jobject _obj, jint _arg_int, jdoubleArray _arg_doublearray, jboolean _arg_boolean) ......</p>
<p>c）声明函数指针，就是你要调用的第三方dll中函数的类型。</p>
<p>d）LoadLibrary，导入真正的第三方Dll，并找到要调用的方法的函数地址。</p>
<p>把这个函数地址赋值给函数指针，接下来就可以通过这个函数指针调用真正的apcluster函数了！</p>
<p>e）类型转换：</p>
<p>读读jni.h文件就知道jdouble和double其实是一个东西，jboolean就是unsigned char类型，jni.h中是这么声明的：</p><pre><ol class="dp-j"><li class="alt"><span>typedef&nbsp;unsigned&nbsp;</span><span class="keyword">char</span><span>&nbsp;&nbsp;&nbsp;&nbsp;jboolean; &nbsp;</span></li><li><span>typedef&nbsp;unsigned&nbsp;</span><span class="keyword">short</span><span>&nbsp;&nbsp;&nbsp;jchar; &nbsp;</span></li><li class="alt"><span>typedef&nbsp;</span><span class="keyword">short</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jshort; &nbsp;</span></li><li><span>typedef&nbsp;</span><span class="keyword">float</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jfloat; &nbsp;</span></li><li class="alt"><span>typedef&nbsp;</span><span class="keyword">double</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jdouble;&nbsp;</span></li></ol></pre>
<p>但是数组类型就没有这么简单，获取数组要使用类型相对应的env-&gt;GetTypeArrayElement(jTypeArray...)。</p>
<p>最后，要返回一个jint类型的数组，就要新创建一个此类型的数组，再为其赋值：</p><pre><ol class="dp-j"><li class="alt"><span>jintArray&nbsp;result&nbsp;=&nbsp;env-&gt;NewIntArray(_arg_int); &nbsp;</span></li><li><span>env-&gt;SetIntArrayRegion(result,&nbsp;</span><span class="number">0</span><span>,&nbsp;_arg_int,&nbsp;(</span><span class="keyword">const</span><span>&nbsp;jint*)ret);&nbsp;</span></li></ol></pre>
<p>其中，_arg_int代表的是创建数组的长度。</p>
<p>最后return result。</p>
<p><strong>4）Build这个工程。</strong></p>
<p>Build，生成相应的APCluster.dll文件，将这个dll放到java工程目录下。</p>
<p style="text-align: center"><a href="http://java.itwaka.com/UploadFiles_4554/201201/20120110153811688.png" target="_blank"><img class="fit-image" border="0" alt="" src="http://java.itwaka.com/UploadFiles_4554/201201/20120110153811688.png" width="383" height="124" /></a>&nbsp;<br />图5 将生成的dll放到java工程下</p>
<p><strong>5）编写测试java程序，调用dll库。</strong></p>
<p>以下为测试程序，Test.java：</p><pre><ol class="dp-j"><li class="alt"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Test&nbsp;&nbsp; &nbsp;</span></li><li><span>{ &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">double</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg_doublearray[]&nbsp;=&nbsp;{</span><span class="number">0.1</span><span>,&nbsp;</span><span class="number">0.2</span><span>,&nbsp;</span><span class="number">0.3</span><span>};&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg_int&nbsp;=&nbsp;</span><span class="number">3</span><span>;&nbsp; &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;&nbsp;&nbsp;&nbsp;arg_boolean&nbsp;=&nbsp;</span><span class="keyword">true</span><span>;&nbsp; &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>[]&nbsp;&nbsp;result&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;APCluster().CallAPClusterDll(arg_int,&nbsp;arg_doublearray,&nbsp;arg_boolean); &nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;..... &nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;</span></li><li class="alt"><span>}&nbsp;</span></li></ol></pre>
<p>到此，java调用第三方dll就基本完成了。</p>
<p>本文也主要是介绍大概的操作流程，至于具体应该使用哪些API就只有去研究官方文档了。</p>
<p>另外还有一些需要注意的问题，比如64位的程序去调用32位的dll会报错啊等等...这些都是细节问题了。</p>
<p>最后，个人认为，自己动手实践还是很重要，网上都说这个复杂那个难，但是至于难还是不难，还是要实践了才知道...不能不去尝试...</p><img src ="http://www.blogjava.net/cangshi004/aggbug/369270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cangshi004/" target="_blank">cangshi</a> 2012-02-02 22:44 <a href="http://www.blogjava.net/cangshi004/archive/2012/02/02/369270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>