﻿<?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://www2.blogjava.net/neumqp/category/4361.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 03 Jul 2007 17:11:52 GMT</lastBuildDate><pubDate>Tue, 03 Jul 2007 17:11:52 GMT</pubDate><ttl>60</ttl><item><title>filter得到request的body/content</title><link>http://www.blogjava.net/neumqp/archive/2006/10/25/77235.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Wed, 25 Oct 2006 09:01:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/10/25/77235.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/77235.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/10/25/77235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/77235.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/77235.html</trackback:ping><description><![CDATA[
		<p>
				<br />    public void doFilter(ServletRequest request, ServletResponse response,<br />            FilterChain chain) throws IOException, ServletException {</p>
		<p>        HttpServletRequest req = (HttpServletRequest) request;</p>
		<p>        int length = req.getContentLength();<br />        if (length &gt; 0) {<br />            BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(req,length);</p>
		<p>            InputStream is = bufferedRequest.getInputStream();<br />            byte[] content = new byte[length];<br />            <br />            int pad = 0;<br />            while(pad &lt; length){<br />                pad += is.read(content, pad, length);<br />            }<br /><br />            request = bufferedRequest;<br />        }<br />        chain.doFilter(request, response);      <br />    }<br /><br /><br />BufferedRequestWrapper .java<br /><br />import java.io.ByteArrayInputStream;<br />import java.io.ByteArrayOutputStream;<br />import java.io.IOException;<br />import java.io.InputStream;</p>
		<p>import javax.servlet.ServletInputStream;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletRequestWrapper;</p>
		<p>public class BufferedRequestWrapper extends HttpServletRequestWrapper {</p>
		<p>    ByteArrayInputStream bais;</p>
		<p>    BufferedServletInputStream bsis;</p>
		<p>    byte[] buffer;</p>
		<p>    public BufferedRequestWrapper(HttpServletRequest req,int length) throws IOException {<br />        super(req);<br />        // Read InputStream and store its content in a buffer.<br />        InputStream is = req.getInputStream();<br />        buffer = new byte[length];</p>
		<p>        int pad = 0;<br />        while(pad &lt; length){<br />            pad += is.read(buffer, pad, length);<br />        }<br />    }</p>
		<p>    public ServletInputStream getInputStream() {<br />        try {<br />            // Generate a new InputStream by stored buffer<br />            bais = new ByteArrayInputStream(buffer);<br />            // Istantiate a subclass of ServletInputStream<br />            // (Only ServletInputStream or subclasses of it are accepted by the<br />            // servlet engine!)<br />            bsis = new BufferedServletInputStream(bais);<br />        } catch (Exception ex) {<br />            ex.printStackTrace();<br />        } finally {<br />        }<br />        return bsis;<br />    }</p>
		<p>}<br /><br /><br /><br /><br />BufferedServletInputStream .java<br /><br />import java.io.*;<br />import javax.servlet.ServletInputStream;</p>
		<p>/*<br /> Subclass of ServletInputStream needed by the servlet engine.<br /> All inputStream methods are wrapped and are delegated to <br /> the ByteArrayInputStream (obtained as constructor parameter)!<br /> */<br />public class BufferedServletInputStream extends ServletInputStream {</p>
		<p>    ByteArrayInputStream bais;</p>
		<p>    public BufferedServletInputStream(ByteArrayInputStream bais) {<br />        this.bais = bais;<br />    }</p>
		<p>    public int available() {<br />        return bais.available();<br />    }</p>
		<p>    public int read() {<br />        return bais.read();<br />    }</p>
		<p>    public int read(byte[] buf, int off, int len) {<br />        return bais.read(buf, off, len);<br />    }</p>
		<p>}</p>
<img src ="http://www.blogjava.net/neumqp/aggbug/77235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-10-25 17:01 <a href="http://www.blogjava.net/neumqp/archive/2006/10/25/77235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 发mail</title><link>http://www.blogjava.net/neumqp/archive/2006/05/10/45516.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Wed, 10 May 2006 10:02:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/05/10/45516.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/45516.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/05/10/45516.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/45516.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/45516.html</trackback:ping><description><![CDATA[
		<p>有发送人名称中文支持，支持bytes格式附件，附件中文支持<br /><br />  public static boolean send(String fromName, String fromAddr, String to, String subject, String<br />                             body, String fileName, byte[] file) throws<br />      Exception {<br />        //发送人名称，用base64编码，再加上特殊标志<br />        fromName = "=?GB2312?B?" + new String(base64.encode((fromName).getBytes()))  + "?=";<br />    Properties props = new Properties();<br />    Session session = Session.getInstance(props, null);<br />    props.put("mail.smtp.host", Constants.mailhost);<br />    props.put("mail.smtp.auth", "false"); <br />    Message msg = new MimeMessage(session);<br />      msg.setFrom(new InternetAddress(fromAddr,fromName));<br />//后面的BodyPart将加入到此处创建的Multipart中<br />    Multipart mp = new MimeMultipart();<br />// Create the message part<br />    BodyPart messageBodyPart = new MimeBodyPart();</p>
		<p>    // Fill the message<br />    messageBodyPart.setText(body);</p>
		<p>    mp.addBodyPart(messageBodyPart);<br /><br />      /*发送附件*/<br />     if (file != null &amp;&amp; file.length &gt; 0) {<br />       //利用枚举器方便的遍历集合<br />         MimeBodyPart mbp = new MimeBodyPart();  <br />//         File fileTmp = null;<br />         //得到数据源<br />//         FileDataSource fds = new FileDataSource(fileTmp);<br />         //得到附件本身并至入BodyPart<br />         mbp.setDataHandler(new DataHandler(new ByteArrayDataSource(file,"application/octet-stream")));<br />         //得到文件名同样至入BodyPart<br />         mbp.setFileName(MimeUtility.encodeWord(fileName,"GB2312",null));<br />         mp.addBodyPart(mbp);<br />     }<br />    <br />    //Multipart加入到信件<br />    msg.setContent(mp);</p>
		<p>    msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));<br />    msg.setSubject(subject);</p>
		<p>    msg.setHeader("X-Mailer", "personal Email Sender");<br />    msg.setSentDate(new Date());</p>
		<p>    Transport transport = session.getTransport("smtp");<br /><br />    //添加认证信息<br />    transport.connect(Constants.mailhost, Constants.user, Constants.pwd);<br />    transport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));<br />    transport.close();<br />    return true;<br />  }<br /><br /><br /><br /><br /></p>
		<p>import java.io.*;<br />import javax.activation.*;</p>
		<p>public class ByteArrayDataSource implements DataSource {<br />    /** * Data to write. */<br />    private byte[] _data;</p>
		<p>    /** * Content-Type. */<br />    private String _type;</p>
		<p>    /* Create a datasource from an input stream */<br />    public ByteArrayDataSource(InputStream is, String type) {<br />        _type = type;<br />        try {<br />            ByteArrayOutputStream os = new ByteArrayOutputStream();<br />            int ch;</p>
		<p>            // XXX : must be made more efficient by<br />            // doing buffered reads, rather than one byte reads<br />            while ((ch = is.read()) != -1)<br />                os.write(ch);<br />            _data = os.toByteArray();<br />        } catch (IOException ioe) {<br />        }<br />    }</p>
		<p>    /* Create a datasource from a byte array */<br />    public ByteArrayDataSource(byte[] data, String type) {<br />        _data = data;<br />        _type = type;<br />    }</p>
		<p>    /* Create a datasource from a String */<br />    public ByteArrayDataSource(String data, String type) {<br />        try {<br />            // Assumption that the string contains only ascii<br />            // characters ! Else just pass in a charset into this<br />            // constructor and use it in getBytes()<br />            _data = data.getBytes("iso-8859-1");<br />        } catch (UnsupportedEncodingException uee) {<br />        }<br />        _type = type;<br />    }</p>
		<p>    public InputStream getInputStream() throws IOException {<br />        if (_data == null)<br />            throw new IOException("no data");<br />        return new ByteArrayInputStream(_data);<br />    }</p>
		<p>    public OutputStream getOutputStream() throws IOException {<br />        throw new IOException("cannot do this");<br />    }</p>
		<p>    public String getContentType() {<br />        return _type;<br />    }</p>
		<p>    public String getName() {<br />        return "dummy";<br />    }<br />}<br /></p>
<img src ="http://www.blogjava.net/neumqp/aggbug/45516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-05-10 18:02 <a href="http://www.blogjava.net/neumqp/archive/2006/05/10/45516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j资料</title><link>http://www.blogjava.net/neumqp/archive/2006/03/09/34478.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Thu, 09 Mar 2006 07:08:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/03/09/34478.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/34478.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/03/09/34478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/34478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/34478.html</trackback:ping><description><![CDATA[<A href="http://dev.csdn.net/article/82070.shtm">http://dev.csdn.net/article/82070.shtm</A><BR><A href="http://blog.csdn.net/lxblg/archive/2004/09/14/104207.aspx">http://blog.csdn.net/lxblg/archive/2004/09/14/104207.aspx</A><img src ="http://www.blogjava.net/neumqp/aggbug/34478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-03-09 15:08 <a href="http://www.blogjava.net/neumqp/archive/2006/03/09/34478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rmi找不到stub问题</title><link>http://www.blogjava.net/neumqp/archive/2006/03/08/34203.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Wed, 08 Mar 2006 03:20:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/03/08/34203.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/34203.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/03/08/34203.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/34203.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/34203.html</trackback:ping><description><![CDATA[<P>启动server时如果遇到找不到stub问题，原因是rmiregistry找不到stub，而不是java com.Server找不到stub，解决方法，在stub的类同一个目录下启动rmiregistry</P><img src ="http://www.blogjava.net/neumqp/aggbug/34203.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-03-08 11:20 <a href="http://www.blogjava.net/neumqp/archive/2006/03/08/34203.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jni内存泄露</title><link>http://www.blogjava.net/neumqp/archive/2006/03/02/33152.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Thu, 02 Mar 2006 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/03/02/33152.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/33152.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/03/02/33152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/33152.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/33152.html</trackback:ping><description><![CDATA[在c++中new的对象，如果不返回java，必须用release掉，否则内存泄露。包括NewStringUTF，NewObject<BR>。如果返回java不必release，java会自己回收。<BR><BR>&nbsp;jstring jstr = env-&gt;NewStringUTF((*p).sess_id);<BR>&nbsp;&nbsp;&nbsp;...<BR>&nbsp;env-&gt;DeleteLocalRef( jstr);<BR><BR>jobject jobj = env-&gt;NewObject(clazz,midInit);<BR>return jobj;<BR><BR>内存泄露可以先从windows资源管理器中，看到随程序运行，内存不断增长的趋势，具体可以用<STRONG>hp jmeter</STRONG>检测<STRONG>。</STRONG>在运行程序时，加jvm参数 <STRONG>-Xrunhprof:heap=all,cutoff=0</STRONG> ，生成java.hprof.txt，用jmeter打开，<STRONG>Metric -&gt; Residual Objects (Count)</STRONG>，可以看到未回收的对象，选中要查看的对象，点<STRONG>Mark</STRONG>记录下要查看的对象，<STRONG>Window -&gt; New Window</STRONG> 打开新窗口，用<STRONG>Metric -&gt; Reference Graph Tree，</STRONG>然后点<STRONG>Find Immediately</STRONG>可以看到对象被哪里引用。<BR><BR><BR>
<P><A name=2.0><SPAN class=atitle><FONT face=Arial size=4>找出内存泄漏</FONT></SPAN></A>另一方法</P>
<P>程序有内存泄漏的第一个迹象通常是它抛出一个 <CODE>OutOfMemoryError</CODE>，或者因为频繁的垃圾收集而表现出糟糕的性能。幸运的是，垃圾收集可以提供能够用来诊断内存泄漏的大量信息。如果以 <CODE>-verbose:gc</CODE> 或者 <CODE>-Xloggc</CODE> 选项调用 JVM，那么每次 GC 运行时在控制台上或者日志文件中会打印出一个诊断信息，包括它所花费的时间、当前堆使用情况以及恢复了多少内存。记录 GC 使用情况并不具有干扰性，因此如果需要分析内存问题或者调优垃圾收集器，在生产环境中默认启用 GC 日志是值得的。 </P>
<P>有工具可以利用 GC 日志输出并以图形方式将它显示出来，JTune 就是这样的一种工具（请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/j-jtp11225/#resources"><FONT color=#996699>参考资料</FONT></A>）。观察 GC 之后堆大小的图，可以看到程序内存使用的趋势。对于大多数程序来说，可以将内存使用分为两部分：<I>baseline</I> 使用和 <I>current load</I> 使用。对于服务器应用程序，baseline 使用就是应用程序在没有任何负荷、但是已经准备好接受请求时的内存使用，current load 使用是在处理请求过程中使用的、但是在请求处理完成后会释放的内存。只要负荷大体上是恒定的，应用程序通常会很快达到一个稳定的内存使用水平。如果在应用程序已经完成了其初始化并且负荷没有增加的情况下，内存使用持续增加，那么程序就可能在处理前面的请求时保留了生成的对象。 </P><BR>
<P>图 1 显示&nbsp; GC 之后应用程序堆大小随着时间的变化图。上升趋势是存在内存泄漏的警示信号。（在真实的应用程序中，坡度不会这么大，但是在收集了足够长时间的 GC 数据后，上升趋势通常会表现得很明显。） </P><BR><A name=figure1><B>图 1. 持续上升的内存使用趋势</B></A><BR><IMG alt="" src="http://www-128.ibm.com/developerworks/cn/java/j-jtp11225/heapsize.gif"> <BR>
<P>确信有了内存泄漏后，下一步就是找出哪种对象造成了这个问题。所有内存分析器都可以生成按照对象类进行分解的堆快照。有一些很好的商业堆分析工具，但是找出内存泄漏不一定要花钱买这些工具 —— 内置的 <CODE>hprof</CODE> 工具也可完成这项工作。要使用 <CODE>hprof</CODE> 并让它跟踪内存使用，需要以 <CODE>-Xrunhprof:heap=sites</CODE> 选项调用 JVM。 </P>
<P>清单 3 显示分解了应用程序内存使用的 <CODE>hprof</CODE> 输出的相关部分。（<CODE>hprof</CODE> 工具在应用程序退出时，或者用 <CODE>kill -3</CODE> 或在 Windows 中按 Ctrl+Break 时生成使用分解。）注意两次快照相比，<CODE>Map.Entry</CODE>、<CODE>Task</CODE> 和 <CODE>int[]</CODE> 对象有了显著增加。 </P>
<P>请参阅 <A href="http://www-128.ibm.com/developerworks/cn/java/j-jtp11225/sidefile1.html"><FONT color=#996699>清单 3</FONT></A>。</P>
<P>清单 4 展示了 <CODE>hprof</CODE> 输出的另一部分，给出了 <CODE>Map.Entry</CODE> 对象的分配点的调用堆栈信息。这个输出告诉我们哪些调用链生成了 <CODE>Map.Entry</CODE> 对象，并带有一些程序分析，找出内存泄漏来源一般来说是相当容易的。 </P><BR><A name=listing4><B>清单 4. HPROF 输出，显示 Map.Entry 对象的分配点</B></A><BR>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#eeeeee border=1>
<TBODY>
<TR>
<TD><PRE><CODE class=section>

<FONT face="Lucida Console">TRACE 300446:
	java.util.HashMap$Entry.&lt;init&gt;(&lt;Unknown Source&gt;:Unknown line)
	java.util.HashMap.addEntry(&lt;Unknown Source&gt;:Unknown line)
	java.util.HashMap.put(&lt;Unknown Source&gt;:Unknown line)
	java.util.Collections$SynchronizedMap.put(&lt;Unknown Source&gt;:Unknown line)
	com.quiotix.dummy.MapLeaker.newTask(MapLeaker.java:48)
	com.quiotix.dummy.MapLeaker.main(MapLeaker.java:64)
</FONT></CODE></PRE></TD></TR></TBODY></TABLE><BR><BR><BR><BR>另外<BR>jstring jstr = (jstring)env-&gt;CallObjectMethod(authenRequest, mid_authenReq_getSdId_S);<BR>&nbsp;env-&gt;GetStringUTFRegion(jstr,0,env-&gt;GetStringLength(jstr),authenReq.sd_id);<BR>当jstr是null时，env-&gt;GetStringLength(jstr)会出错，导致jvm崩溃<BR><img src ="http://www.blogjava.net/neumqp/aggbug/33152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-03-02 11:23 <a href="http://www.blogjava.net/neumqp/archive/2006/03/02/33152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：HP-UX下使用JNI访问标准C++程序</title><link>http://www.blogjava.net/neumqp/archive/2006/02/27/32669.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Mon, 27 Feb 2006 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/02/27/32669.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/32669.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/02/27/32669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/32669.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/32669.html</trackback:ping><description><![CDATA[<TABLE style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellSpacing=0 cellPadding=0 width=760 bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD align=middle height=25><FONT style="FONT-SIZE: 14pt" color=#02368d><B>HP-UX下使用JNI访问标准C++程序</B></FONT><BR></TD></TR>
<TR>
<TD align=middle height=9><IMG height=9 alt="" src="http://blog.chinaunix.com/templates/default/images/right_line.gif" width=502 border=0></TD></TR>
<TR>
<TD align=middle>
<TABLE style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellSpacing=0 cellPadding=0 width=740 border=0>
<TBODY>
<TR>
<TD width=740>
<DIV id=art style="MARGIN: 15px; LINE-HEIGHT: 150%" width="560">
<DIV>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">问题的关键在于用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">aCC</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编译时的参数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;<BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">根据</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">HP</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">网站上的两篇文章可以很容易的使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JNI</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">访问传统</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">C++(Classical&nbsp;C++)</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">程序</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>http://www.hp.com/products1/unix/java/infolibrary/prog_guide/JNI_java2.html&nbsp;<BR>http://forums1.itrc.hp.com/service/forums/questionanswer.do?admit=716493758+1092296929165+28353475&amp;threadId=245738&nbsp;<BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">但是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">如果代码中使用到了标准</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">C++,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">也就是用到了</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">STL,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">就会出现莫名其妙的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JVM&nbsp;crash.&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">而且一般的现象是使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">string</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的时候出错</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;<BR><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">最后发现是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JVM</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的多线程机制和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">aCC</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编译的缺省的多线程机制不一样</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">所以编译时需要加参数指定</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;<BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">总的说来</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编译参数为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>OPTS=-AA&nbsp;+z&nbsp;+u4&nbsp;-D_RWSTD_MULTI_THREAD&nbsp;-D_REENTRANT&nbsp;-D_HPUX&nbsp;-D_HPUX_SOURCE&nbsp;-D_POSIX_C_SOURCE=199506L&nbsp;-D_XOPEN_SOURCE_EXTENDED&nbsp;<BR><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">其中</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,-D_RWSTD_MULTI_THREAD&nbsp;-D_REENTRANT&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">是指定多线程机制</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">同时必须添加</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">-D_HPUX_SOURCE&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">参数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">否则</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编译时会出现奇怪的错误</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;<BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">连接参数为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>-AA&nbsp;-b&nbsp;-lCsup_v2&nbsp;-lstd_v2&nbsp;<BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">值得注意的是根据上面所说的第二篇文章可知使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">-AA</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编译连接时</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">要连的库是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">libCsup_v2.sl</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">libstd_v2.sl(</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这两个库是支持标准</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">C++</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的库</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">),</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">而不是第一篇文章中提到的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">libCsup.sl</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">libstd.sl(</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">这两个库是支持传统</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">C++</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的库</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">).&nbsp;<BR><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">另外</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">有几个碰到的问题</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>1.&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">如果编译参数没有指定多线程机制</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">禁用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JIT(</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">启动</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JVM</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">加参数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:-Djava.compiler=none&nbsp;-Xint&nbsp;)</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">可以使简单的例子通过</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">但是有些情况下还是会出错</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;<BR><BR>2.&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">当</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">null</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">作为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">String</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">传入</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JNI&nbsp;native</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">接口代码中是</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">env-&gt;GetStringUTFChars(jstring)</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">会出现如下错误导致虚拟机崩溃</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>Function=verify_instance_jfieldID__18jfieldIDWorkaroundSFP12klassOopDescP9_jfieldID&nbsp;<BR><BR>3.&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">在使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">String</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">作为</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">JNI</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的传入传出参数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">GetStringUTFChars</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">解决不了中文问题</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">,</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">还是会有乱码</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">.&nbsp;</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">正确的解决方法是使用以下两个函数</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">:&nbsp;<BR>void&nbsp;JNU_ThrowByName(JNIEnv&nbsp;*env,&nbsp;const&nbsp;char&nbsp;*name,&nbsp;const&nbsp;char&nbsp;*msg)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;jclass&nbsp;cls&nbsp;=&nbsp;env-&gt;FindClass(name);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;if&nbsp;cls&nbsp;is&nbsp;NULL,&nbsp;an&nbsp;exception&nbsp;has&nbsp;already&nbsp;been&nbsp;thrown&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(cls&nbsp;!=&nbsp;NULL)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;ThrowNew(cls,&nbsp;msg);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;free&nbsp;the&nbsp;local&nbsp;ref&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(cls);&nbsp;<BR>}&nbsp;<BR><BR>jstring&nbsp;JNU_NewStringNative(JNIEnv&nbsp;*env,&nbsp;const&nbsp;char&nbsp;*str)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(str==NULL)&nbsp;<BR>&nbsp;&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;return&nbsp;NULL;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;jclass&nbsp;jcls_str&nbsp;=&nbsp;env-&gt;FindClass("java/lang/String");&nbsp;<BR>&nbsp;&nbsp;jmethodID&nbsp;jmethod_str&nbsp;=&nbsp;env-&gt;GetMethodID(jcls_str,&nbsp;"<INIT>",&nbsp;"([B)V");&nbsp;<BR><BR>&nbsp;&nbsp;jstring&nbsp;result;&nbsp;<BR>&nbsp;&nbsp;jbyteArray&nbsp;bytes&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;int&nbsp;len;&nbsp;<BR><BR>&nbsp;&nbsp;if&nbsp;(env-&gt;EnsureLocalCapacity(2)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NULL;&nbsp;/*&nbsp;out&nbsp;of&nbsp;memory&nbsp;error&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;len&nbsp;=&nbsp;strlen(str);&nbsp;<BR>&nbsp;&nbsp;bytes&nbsp;=&nbsp;env-&gt;NewByteArray(len);&nbsp;<BR>&nbsp;&nbsp;if&nbsp;(bytes&nbsp;!=&nbsp;NULL)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;SetByteArrayRegion(bytes,&nbsp;0,&nbsp;len,(jbyte&nbsp;*)str);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;(jstring)env-&gt;NewObject(jcls_str,&nbsp;jmethod_str,&nbsp;bytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(bytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result;&nbsp;<BR>&nbsp;&nbsp;}&nbsp;/*&nbsp;else&nbsp;fall&nbsp;through&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;return&nbsp;NULL;&nbsp;<BR>]&nbsp;<BR><BR><BR>char&nbsp;*JNU_GetStringNativeChars(JNIEnv&nbsp;*env,&nbsp;jstring&nbsp;jstr)&nbsp;<BR>{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;jbyteArray&nbsp;bytes&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;jthrowable&nbsp;exc;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*result&nbsp;=&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(env-&gt;EnsureLocalCapacity(2)&nbsp;&lt;&nbsp;0)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;&nbsp;/*&nbsp;out&nbsp;of&nbsp;memory&nbsp;error&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>jclass&nbsp;jcls_str&nbsp;=&nbsp;env-&gt;FindClass("java/lang/String");&nbsp;<BR>jmethodID&nbsp;MID_String_getBytes&nbsp;=&nbsp;env-&gt;GetMethodID(jcls_str,&nbsp;"getBytes",&nbsp;"()[B"];&nbsp;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;bytes&nbsp;=&nbsp;(jbyteArray)env-&gt;CallObjectMethod(jstr,&nbsp;MID_String_getBytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;exc&nbsp;=&nbsp;env-&gt;ExceptionOccurred();&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!exc)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jint&nbsp;len&nbsp;=&nbsp;env-&gt;GetArrayLength(&nbsp;bytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;(char&nbsp;*)malloc(len&nbsp;+&nbsp;1);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(result&nbsp;==&nbsp;0)&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JNU_ThrowByName(env,&nbsp;"java/lang/OutOfMemoryError",&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(bytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;GetByteArrayRegion(bytes,&nbsp;0,&nbsp;len,&nbsp;(jbyte&nbsp;*)result);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result[len]&nbsp;=&nbsp;0;&nbsp;/*&nbsp;NULL-terminate&nbsp;*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(exc);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;env-&gt;DeleteLocalRef(bytes);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(char*)result;&nbsp;<BR>)&nbsp;<BR><BR></SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">★注意：使用</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">char&nbsp;*JNU_GetStringNativeChars()</SPAN><SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">获得的指针用完后要显式的</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9pt; FONT-FAMILY: Arial">free().</SPAN></P></DIV></DIV></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/neumqp/aggbug/32669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-02-27 15:54 <a href="http://www.blogjava.net/neumqp/archive/2006/02/27/32669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：如何使用Axis传送附件 </title><link>http://www.blogjava.net/neumqp/archive/2006/02/20/31665.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Mon, 20 Feb 2006 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/02/20/31665.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/31665.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/02/20/31665.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/31665.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/31665.html</trackback:ping><description><![CDATA[<P>使用Axis传送附件有两种方式：</P>
<P>1. 将你要传送的文件封装在DataHandler中，然后将DataHandler对象或DataHandler数组（多个文件传送的时候）作为客户端调用函数的参数（从客户端上传文件到服务器）Axis服务的返回类型（从服务器端下载文件到客户端）进行传输。</P>
<P>2. 还有一种方式是直接修改soap信封的内容，将附件信息加到soap信封中发送。</P>
<P>这里我们只讨论第一种方法，因为它实现起来非常简单。关于第二种方法在Axis包的webapps/attachments/TestRf.java中有详细的原码可以参考。</P>
<P>下面的例子是把文件从服务器端下载到客户端：</P>
<P>1.服务端程序：</P>
<P>假设传输多个文件：在服务器端将文件取出来，并将文件封装在DataHandler数组中。<BR>代码如下：</P>
<P>&nbsp;DataHandler[] ret = new DataHandler[totalFileNum];<BR>&nbsp;... ...<BR>&nbsp;java.io.File myFile = new java.io.File(filePath);<BR>&nbsp;if(myFile.isFile() &amp;&amp; myFile.canRead())<BR>&nbsp;{<BR>&nbsp;&nbsp;String fname = myFile.getAbsoluteFile().getCanonicalPath();<BR>&nbsp;&nbsp;DataHandler[0] = new DataHandler(new FileDataSource(fname));<BR>&nbsp;}<BR>&nbsp;... ...</P>
<P>&nbsp;return ret;</P>
<P>上面的代码将所有的文件封装在了DataHandler数组中，并返回。</P>
<P>2. 客户端的访问：</P>
<P>代码如下：<BR>&nbsp;Service service = new Service();<BR>&nbsp;Call call = (Call) service.createCall();</P>
<P>&nbsp;URL myURL = new URL("<A href="http://192.168.0.26:8080/axis/servlet/AxisServlet"><U>http://192.168.0.26:8080/axis/servlet/AxisServlet</U></A>");<BR>&nbsp;call.setTargetEndpointAddress(myURL); //设定服务的主机和位置<BR>&nbsp;call.setOperationName(new QName("urn:MyAttachServer","echoDir")); //设置要调用的服务的方法<BR>&nbsp;QName qnameAttachment = new QName("urn:MyAttachServer","DataHandler");</P>
<P>&nbsp;call.registerTypeMapping(DataHandler.class, qnameAttachment, JAFDataHandlerSerializerFactory.class,JAFDataHandlerDeserializerFactory.class); //为附件（即DataHandler类）创建序列化生成器</P>
<P>&nbsp;call.addParameter("source", XMLType.XSD_STRING ,ParameterMode.IN);&nbsp;//设置服务调用方法的传入参数类型<BR>&nbsp;call.setReturnType(XMLType.SOAP_ARRAY);&nbsp;//设置调用服务方法的返回类型，由于返回的是DataHandler数组，所以设置为SOAP_ARRAY类型<BR>&nbsp;javax.activation.DataHandler[] ret = (javax.activation.DataHandler[])call.invoke(new Object[]{null}); //调用方法</P>
<P>&nbsp;for (i = 0; i &lt; ret.length; ++i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataHandler recDH = ret[i];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.io.File receivedFile = new java.io.File(recDH.getName());&nbsp;//文件生成<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>3. 服务的部署：</P>
<P>注意：你要在部署的时候，定义DataHandler的序列化生成器。</P>
<P><DEPLOYMENT xmlns="”http://xml.apache.org/axis/wsdd/”">&nbsp; 编写deploy.wsdd文件：</SERVICE></P>
<P></DEPLOYMENT></P>
<P>&nbsp;&lt;deployment xmlns="<A href="http://xml.apache.org/axis/wsdd/"><U>http://xml.apache.org/axis/wsdd/</U></A>" xmlns:java="<A href="http://xml.apache.org/axis/wsdd/providers/java"><U>http://xml.apache.org/axis/wsdd/providers/java</U></A>" xmlns:ns1="urn:att_STC_Server" &gt;<BR>&nbsp; &lt;service name="urn:att_STC_Server" provider="java:RPC" &gt;<BR>&nbsp;&nbsp;&nbsp; &lt;parameter name="className" value="samples.att_STC.att_STC_Server"/&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;parameter name="allowedMethods" value="echoDir"/&gt;</P>
<P>&nbsp;&lt;typeMapping deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"<BR>&nbsp;&nbsp; languageSpecificType="java:javax.activation.DataHandler" qname="ns1:DataHandler"<BR>&nbsp;&nbsp;&nbsp; serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" <BR>&nbsp;&nbsp;&nbsp; encodingStyle="<A href="http://blog.csdn.net/tenwang1977/archive/2004/07/08/'http://schemas.xmlsoap.org/soap/encoding/" ??><U>http://schemas.xmlsoap.org/soap/encoding/"/</U></A>&gt;<BR>&nbsp; &lt;/service&gt;</P>
<P>&lt;/deployment&gt;</SERVICE></P>
<P></DEPLOYMENT></SERVICE></P>
<P></DEPLOYMENT></P>
<P>运行java org.apache.axis.client.AdminClient %* deploy.wsdd，部署服务。</P><img src ="http://www.blogjava.net/neumqp/aggbug/31665.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-02-20 16:28 <a href="http://www.blogjava.net/neumqp/archive/2006/02/20/31665.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：使用Java实现CA</title><link>http://www.blogjava.net/neumqp/archive/2006/02/20/31605.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Mon, 20 Feb 2006 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2006/02/20/31605.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/31605.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2006/02/20/31605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/31605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/31605.html</trackback:ping><description><![CDATA[<P class=date>2004-05-29 17:39:53</P>
<P class=content><STRONG>主题: </STRONG><A href="http://www.newsmth.net/pc/pccon.php?id=1904&amp;nid=38722&amp;s=all">使用Java实现CA(四)</A><BR><FONT class=content>
<P>&nbsp;&nbsp;&nbsp; 前面几篇文章已经把如何用Java实现一个CA基本上讲完了.但是他们都有一个特点,就是用户的信息都是在现场获取的,不能做申请和签发相分离.今天我们要讲述的是PKCS#10证书请求文件.它的作用就是可以使申请和签发相分离.</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;PKCS#10证书请求结构中的主要信息包含了被签发者(证书申请者)的主体名称(DN)和他的公钥.因此一个CA在获取到一个PKCS#10证书请求后,就可以从中获取到任何和签发证书有关的信息,然后用它自己的私钥签发证书.</P>
<P>&nbsp;&nbsp;&nbsp; 使用BC Provider在Java中构造一个证书请求格式的对象调用其构造函数即可,这个函数如下:</P>
<P>&nbsp;&nbsp;&nbsp; PKCS10CertificationRequest(java.lang.String signatureAlgorithm, X509Name subject, java.security.PublicKey key, ASN1Set attributes, java.security.PrivateKey signingKey)</P>
<P>&nbsp;&nbsp;&nbsp; 它的参数是自签名算法,证书申请者的DN,证书申请者的公钥,额外的属性集(就是要申请的证书的扩展信息),申请证书者的私钥.申请证书者的私钥仅仅是用来进行一下自签名,并不出现在证书请求中,需要自签名的目的是保证该公钥确实为申请者所有.</P>
<P>&nbsp;&nbsp;&nbsp; 调用该对象的getEncoded()方法可以将其进行DER编码,然后储存起来,该对象还有另一个构造函数:<BR>&nbsp;&nbsp;&nbsp; PKCS10CertificationRequest(byte[] bytes)<BR>&nbsp;&nbsp;&nbsp; 这个构造函数的作用就是直接从储存的DER编码中把这个对象还原出来.</P>
<P>&nbsp;&nbsp;&nbsp; 利用证书请求结构进行证书签发的代码如下,这里假设CSR是一个已经获取出来的PKCS10CertificationRequest结构:</P>
<P>&nbsp;&nbsp;&nbsp; PublicKey SubjectPublicKey = CSR.getPublicKey();<BR>&nbsp;&nbsp;&nbsp; CertificationRequestInfo CSRInfo = CSR.getCertificationRequestInfo();<BR>&nbsp;&nbsp;&nbsp; X509Name SubjectDN = CSRInfo.getSubject();<BR>&nbsp;&nbsp;&nbsp; ASN1Set Attributes = CSRInfo.getAttributes();</P>
<P>&nbsp;&nbsp;&nbsp; 这样,申请者的主体DN,申请者的公钥,申请者希望在证书扩展信息中填写的属性都得到了,剩下的事情就和用户在现场输入时一样了,其它的信息一般是申请者不能决定的.另外证书请求格式中有一样信息没有明确给出来,那就是证书的有效期,这个应该单独询问用户,或者用其它的方法保存起来.</P>
<P></FONT><BR><BR><A href="http://www.newsmth.net/pc/pcarch.php?userid=wolfenstein&amp;y=2004&amp;m=5#top">[返回顶部]</A></P>
<HR SIZE=1>

<P class=date>2004-05-28 16:46:12</P>
<P class=content><STRONG>主题: </STRONG><A href="http://www.newsmth.net/pc/pccon.php?id=1904&amp;nid=38337&amp;s=all">使用Java实现CA(三)</A><BR><FONT class=content>
<P>&nbsp;&nbsp;&nbsp; 前几次我已经基本上把如何做CA所需要的基础知识讲得差不多了,今天直接讲如何用Java程序来实现一个CA应该就不是什么太困难的事情了.</P>
<P>&nbsp;&nbsp;&nbsp; 要做CA,第一步要准备好自己的证书和私钥.私钥如何从文件里面读取出来前面已经讲过了.从文件系统中读出证书的代码如下:</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;CertificateFactory certCF = CertificateFactory.getInstance("X.509");<BR>&nbsp;&nbsp;&nbsp;&nbsp;X509Certificate caCert =&nbsp;certCF.generateCertificate(certBIS);</P>
<P>&nbsp;&nbsp;&nbsp; 这里cerBIS是一个InputStream类型的对象.例如一个标准的X509v3格式的证书文件所形成的输入流.</P>
<P>&nbsp;&nbsp;&nbsp; 第二步就是从用户那里获取输入,然后构造主体名称结构DN,如何构造DN上次已经说过了,如何从用户那里获取输入,这个不在本文讨论范围之内.</P>
<P>&nbsp;&nbsp;&nbsp; 下一步就是获取用户的公钥,好和他所需要的证书对应起来.也有不少CA的做法就是在这里替用户现场生成一对密钥对,然后把公钥放到证书中签发给用户.这个应该看实际需要选择合适的方式.</P>
<P>&nbsp;&nbsp;&nbsp; 现在一切信息都已经准备好了,可以签发证书了,下面的代码说明了这个过程:</P>
<P>&nbsp;&nbsp;&nbsp; //构造一个证书生成器对象</P>
<P>&nbsp;&nbsp;&nbsp; X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();</P>
<P>&nbsp;&nbsp;&nbsp; //&nbsp;从CA的证书中获取签发者的主体名称(DN)<BR>&nbsp;&nbsp;&nbsp; //&nbsp;这里有一点小技巧,我们要把JCE中定义的<BR>&nbsp;&nbsp;&nbsp; // 用来表示DN的对象<FONT face=新宋体 size=2>X500Principal</FONT>转化成在<BR>&nbsp;&nbsp;&nbsp; // BC Provider中的相应的对象<FONT face=新宋体 size=2>X509Name</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;先从CA的证书中读取出CA的DN进行DER编码<BR>&nbsp;&nbsp;&nbsp;&nbsp;DERInputStream dnStream =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;new DERInputStream(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new ByteArrayInputStream(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;caCert.getSubjectX500Principal().<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getEncoded()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;马上又从编码后的字节流中读取DER编码对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;DERConstructedSequence&nbsp; dnSequence =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(DERConstructedSequence)dnStream.readObject();<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;利用读取出来的DER编码对象创建X509Name<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;对象,并设置为证书生成器中的"签发者DN"<BR>&nbsp;&nbsp;&nbsp;&nbsp;certGen.setIssuerDN(new X509Name(dnSequence));<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置好证书生成器中的"接收方DN"<BR>&nbsp;&nbsp;&nbsp; certGen.setSubjectDN(subjectDN);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置好一些扩展字段,包括签发者和<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;接收者的公钥标识<BR>&nbsp;&nbsp;&nbsp;&nbsp;certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,<BR>&nbsp;&nbsp;&nbsp; createSubjectKeyId(keyToCertify));<BR>&nbsp;&nbsp;&nbsp; certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,<BR>&nbsp;&nbsp;&nbsp;&nbsp;createAuthorityKeyId(caCert.getPublicKey()));<BR>&nbsp;&nbsp;&nbsp; //&nbsp;设置证书的有效期和序列号<BR>&nbsp;&nbsp;&nbsp; certGen.setNotBefore(startDate);<BR>&nbsp; &nbsp;&nbsp;certGen.setNotAfter(endDate);<BR>&nbsp;&nbsp;&nbsp; certGen.setSerialNumber(serialNumber);<BR>&nbsp; &nbsp;&nbsp;//&nbsp;设置签名算法,本例中使用MD5hash后RSA<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;签名,并且设置好主体的公钥<BR>&nbsp;&nbsp;&nbsp;&nbsp;certGen.setSignatureAlgorithm("MD5withRSA");<BR>&nbsp; &nbsp;&nbsp;certGen.setPublicKey(keyToCertify);</P>
<P>&nbsp; &nbsp;&nbsp;//&nbsp;如果以上一切都正常地话,就可以生成证书了<BR>&nbsp; &nbsp;&nbsp;X509Certificate cert = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;cert = certGen.generateX509Certificate(caPrivateKey);</P>
<P>&nbsp;&nbsp;&nbsp; 这里是上面用到的生成签发者公钥标识的函数:&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;protected AuthorityKeyIdentifier createAuthorityKeyId(PublicKey pubKey)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;AuthorityKeyIdentifier authKeyId = null;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; ByteArrayInputStream bIn = new ByteArrayInputStream(pubKey.getEncoded());<BR>&nbsp;&nbsp;&nbsp;&nbsp;SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (DERConstructedSequence)new DERInputStream(bIn).readObject());<BR>&nbsp; &nbsp;&nbsp;authKeyId = new AuthorityKeyIdentifier(info);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch (IOException e)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("Error generating SubjectKeyIdentifier:&nbsp; " +<BR>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;e.toString());<BR>&nbsp;&nbsp;&nbsp;&nbsp;System.exit(1);<BR>&nbsp; &nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; return authKeyId;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; 生成主体公钥标识的函数和上面的类似,把AuthorityKeyIdentifier替换成SubjectKeyIdentifier就可以了.</P>
<P>&nbsp;&nbsp;&nbsp; 这里要注意的是,CA的公钥也是在一份证书里,这种证书的特点是签发者DN和接收者DN一样,也就是说,这种证书是CA自己给自己颁发的证书,也就是"自签名证书",它上面的公钥是CA自身的公钥,用来签名的私钥就是该公钥对应的私钥.一般每个CA都要有这么一份证书,除非该CA不是根CA,即它的权威性不是由它自己证明,而是由它的上级CA证明.但是,最后总归要有一个根CA,它为各个安全应用程序的用户所信赖.</P>
<P>&nbsp;&nbsp;&nbsp; 到这里我们已经把CA最基本的功能如何用Java实现讲完了,下一次讲如何从PKCS#10格式证书请求文件中读取出用户信息,然后直接签发公钥.<BR></P></FONT><BR><BR><A href="http://www.newsmth.net/pc/pcarch.php?userid=wolfenstein&amp;y=2004&amp;m=5#top">[返回顶部]</A> 
<P></P>
<HR SIZE=1>

<P class=date>2004-05-27 15:34:59</P>
<P class=content><STRONG>主题: </STRONG><A href="http://www.newsmth.net/pc/pccon.php?id=1904&amp;nid=37919&amp;s=all">使用Java实现CA(二)</A><BR><FONT class=content>
<P>&nbsp;&nbsp;&nbsp; 昨天本来快写完了,结果不小心按了"tab"键,然后向按退格键,结果退到前一个页面了,然后全部都白写了,不爽.只好今天重新写了.</P>
<P>&nbsp;&nbsp;&nbsp; 上次我们讲到如何生成密钥对,以及如何将诸如公钥,私钥,证书等这一类安全对象在文件系统和内存之间来回转换.这些是准备开CA的基本功,今天我们讲一下CA的基本原理以及如何使用主体名称结构DN(Distinguish Name)来表示每一个证书中的主体.</P>
<P>&nbsp;&nbsp;&nbsp; 一份证书就是一个权威机构对一个主体的身份的确认的证明.即一份证书表示一个权威机构确认了一个主体就是它自己,而不是其它的冒名顶替者.主体可以是一个个人,也可以不是,例如,在需要安全服务的时候,需要为一台网站的服务器颁发证书,这种证书的主体就是一台服务器.签署证书的权威机构就叫做CA,该权威机构本身也是一个主体.权威机构通过对包含有待认证的主体的一系列信息的待签名证书"(TBS,to be signed)进行数字签名来表示该机构对它的认可.一份包含了待认证的主体的相关信息的TBS再加上CA使用自己的私钥进行签名产生的字节流放在一起,就构成了一份标准的X509证书.</P>
<P>&nbsp;&nbsp;&nbsp; 一个TBS中包含了以下这些主要信息:</P>
<P>&nbsp;&nbsp;&nbsp; 证书的版本,通常是3(X509v3)</P>
<P>&nbsp;&nbsp;&nbsp; 证书的序列号,RFC3280中规定,每个CA必须确保它颁发的每一份证书的序列号都是唯一的,并且序列号只能使用非负整数.</P>
<P>&nbsp;&nbsp;&nbsp; 签发者(CA)的主体名称,一个DN对象.</P>
<P>&nbsp;&nbsp;&nbsp; 证书的有效期,表示方法是两个时间值,表示了该证书从何时开始生效,何时开始作废.</P>
<P>&nbsp;&nbsp;&nbsp; 待认证的主体的主体名称,也是一个DN对象.</P>
<P>&nbsp;&nbsp;&nbsp; 待认证的主体的公钥,任何安全应用在确认完证书的有效性后,就可以开始使用该主体的公钥与之进行安全通信.</P>
<P>&nbsp;&nbsp;&nbsp; 如果是X509v3证书,即版本号是3的话,后面还有一个证书扩展信息字段,可以在证书里面添加一些其它的信息.</P>
<P>&nbsp;&nbsp;&nbsp; 下面我们来看一下表示主体的主体名称结构:DN.这个结就构是一个属性的集合.每个属性有属性名称和属性值.它的作用就是用来表示"我是谁",也就是说,这个证书到底是谁颁发给谁的,这个证书对应的公钥是谁拥有的.</P>
<P>&nbsp;&nbsp;&nbsp; 通常使用一个字符串来表示DN结构,这种字符串说明了这种结构中的各个属性的类型和值:</P>
<P>&nbsp;&nbsp;&nbsp; C=CN;S=BeiJing;L=BeiJing;O=PKU;OU=ICST;CN=wolfenstein</P>
<P align=left>&nbsp;&nbsp;&nbsp; 这里C是国家和地区代码,S和L都是地区代码,S相当于省或者州这样的级别,L相当于城市级别,O是组织机构名称,OU是次级组织机构名称,CN是主体的通用名(common name).在这里,C,S,L等等属性的类型都是相对固定的,例如C一般就是用来表示国家和地区代码,在DN结构中还可以添加一些其它类型的信息,一般也都是以"xxx=xxx"这样来表示的.</P>
<P align=left>&nbsp;&nbsp;&nbsp; 下面我们来说明如何在Java语言中构造出一个主体名称对象.</P>
<P align=left>&nbsp;&nbsp;&nbsp; BC Provider中使用X509Name对象来表示DN,构造一个X509Name的步骤大体如下:</P>
<P align=left>&nbsp;&nbsp;&nbsp; 先构造两个vector对象,用来表示属性名称和属性值:</P>
<P align=left>&nbsp;&nbsp;&nbsp; Vector oids = new Vector();<BR>&nbsp;&nbsp;&nbsp; Vector attributes = new Vector();</P>
<P align=left>&nbsp;&nbsp;&nbsp; 然后在oids这个用来表示属性名称的vector对象中将属性名称一个一个添加进去:</P>
<P align=left>&nbsp;&nbsp;&nbsp; oids.addElement(X509Name.C);</P>
<P align=left>&nbsp;&nbsp;&nbsp; ......</P>
<P align=left>&nbsp;&nbsp;&nbsp; oids.addElement(X509Name.CN);</P>
<P align=left>&nbsp;&nbsp;&nbsp; X509Name对象里面有若干常量,例如上面的X509Name.C.还有X509Name.ST等等,都可以和上面举的例子对应起来.</P>
<P align=left>&nbsp;&nbsp;&nbsp; 然后将属性值添加到attributes对象中:</P>
<P align=left>&nbsp;&nbsp;&nbsp; attributes.addElement("CN");</P>
<P align=left>&nbsp;&nbsp;&nbsp; ......</P>
<P align=left>&nbsp;&nbsp;&nbsp; attributes.addElement("Wolfenstein");</P>
<P align=left>&nbsp;&nbsp;&nbsp; 最后就可以构造出一个X509Name对象:</P>
<P align=left>&nbsp;&nbsp;&nbsp; X509Name SubjectDN = new X509Name(oids, attributes);</P>
<P align=left>&nbsp;&nbsp;&nbsp; 这样,我们的主体名称结构就确立起来了.</P>
<P align=left>&nbsp;&nbsp;&nbsp; 下次我们就可以讲关键的部分了,那就是如何用Java程序完成CA最重要的功能,签署证书.</P></FONT><BR><BR><A href="http://www.newsmth.net/pc/pcarch.php?userid=wolfenstein&amp;y=2004&amp;m=5#top">[返回顶部]</A> 
<P></P>
<HR SIZE=1>

<P class=date>2004-05-25 21:23:52</P>
<P class=content><STRONG>主题: </STRONG><A href="http://www.newsmth.net/pc/pccon.php?id=1904&amp;nid=37310&amp;s=all">使用Java实现CA(一)</A><BR><FONT class=content>
<P>&nbsp;&nbsp;&nbsp; 通过我昨天的文章大家应该已经清楚了,用Java写信息安全方面的程序需要做的准备工作.好了,现在假设你已经是一个对Java语言本身比较熟悉,能够用Java写一些程序的人,并且这些该下载的jar包已经下载好了,可以正式开工了.</P>
<P>&nbsp;&nbsp;&nbsp; 在所有的此类程序的开头(无论是在类的构造函数中也好,在初始化函数中也好),都要先来上这么一句:Security.addProvider(new BouncyCastleProvider());将BouncyCaslte的Provider添加到系统中,这样以后系统在运行相关程序的时候调用的就是这个Provider中的加密算法.</P>
<P>&nbsp;&nbsp;&nbsp; 然后我们就可以开始开CA了.首先,作为一个CA要有自己的一对公钥和私钥,我们先要生成这么一对.使用KeyPairGenerator对象就可以了,调用KeyPairGenerator.getInstance方法可以根据要生成的密钥类型来产生一个合适的实例,例如常用的RSA,DSA等.然后调用该对象的initialize方法和generateKeyPair方法就可以产生一个KeyPair对象了.然后调用KeyPair对象中的相应方法就可以获取生成的密钥对中的公钥和私钥了.</P>
<P>&nbsp;&nbsp;&nbsp; 有了公钥和私钥对以后,下面的一个很现实问题就是如何把它们储存起来.通常我们要对这些安全对象,如公钥,私钥,证书等先进行编码.编码的目的是为了把结构复杂的安全对象变成字节流以便存储和读取,如DER编码.另外,通常还把DER编码后的字节流再次进行base64编码,以便使字节流中所有的字节都变成可打印的字节.</P>
<P>&nbsp;&nbsp;&nbsp; 在Java语言中,这些安全对象基本上都有getEncoded()方法.例如:</P>
<P>&nbsp;&nbsp;&nbsp; byte[] keyBytes = privateKey.getEncoded();</P>
<P>&nbsp;&nbsp;&nbsp; 这样就把一个私钥进行了DER编码后的结果保存到一个byte数组中了.然后就可以把这个byte数组保存到任何介质中.如果有必要的话,可以使用BC Provider中的Base64编码解码器类进行编码,就像这样:</P>
<P>&nbsp;&nbsp;&nbsp; byte data[] = Base64.encode(keyBytes);</P>
<P>&nbsp;&nbsp;&nbsp; 要从文件中读取私钥则应该这样:</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyData);<BR>&nbsp;&nbsp;&nbsp;&nbsp;KeyFactory kfac = KeyFactory.getInstance("RSA");<BR>&nbsp;&nbsp;&nbsp;&nbsp;privateKey = kfac.generatePrivate(spec);</P>
<P>&nbsp;&nbsp;&nbsp; 这里说明一下,对RSA私钥进行编码就会自动地按照PKCS8进行.因此读取的时候将包含编码的字节数组作为PKCS8EncodedKeySpec对象的构造函数的参数就可以生成一个该类型的对象.然后创建一个密钥工厂对象就可以按照要求生成一个RSA私钥了.很显然这里的keyData应该是和上面的keyBytes内容相同.</P>
<P>&nbsp;&nbsp;&nbsp; 为了提高系统的安全性,通常私钥在经过DER编码后,还会使用一个口令进行加密,然后再储存在文件系统中.在使用私钥的时候,如果没有正确的口令,是无法把私钥还原出来的.</P>
<P>&nbsp;&nbsp;&nbsp; 保存证书和保存私钥类似.Certificate对象中也有一个getEncoded的方法.</P>
<P>&nbsp;&nbsp;&nbsp; 这次就讲这些.大家应该可以把这些安全对象很熟练地从文件系统和内存之间来回地折腾了吧.这对以后实现CA是很重要的.下次我会讲一下证书中表示主体的方法:DN.<BR></P></FONT><BR><BR><A href="http://www.newsmth.net/pc/pcarch.php?userid=wolfenstein&amp;y=2004&amp;m=5#top">[返回顶部]</A> 
<P></P>
<HR SIZE=1>

<P class=date>2004-05-24 17:23:06</P>
<P class=content><STRONG>主题: </STRONG><A href="http://www.newsmth.net/pc/pccon.php?id=1904&amp;nid=36774&amp;s=all">使用Java开发和信息安全相关的程序</A><BR><FONT class=content>
<P>&nbsp;&nbsp;&nbsp; 这里说的信息安全是相对于系统安全而言的,它更侧重于加密,解密,数字签名,验证,证书等等.而系统安全主要侧重于系统本身是否有安全漏洞,如常见的由于软件设计的不完善而导致的满天飞的缓冲区溢出等等.</P>
<P>&nbsp;&nbsp;&nbsp; Java语言中负责加密功能的部件是JCE(Java Crypto Extenstion),它使用开放式的思想,可以允许用户自己编写加密算法的具体实现的模块等.这些东西被称为JCE Provider,JCE的提供者.SUN公司本身提供了一些Provider.不过我推荐使用Bouncy Castle的Provider.原因是它实现的加密算法多,连比较新的椭圆曲线(ECC)算法都有了.去<A href="http://www.bouncycastle.org/">http://www.bouncycastle.org/</A>可以找到你所希望的.Bouncy Castle除了提供Provider本身以外,还包括了一个S/MIME和一个open pgp&nbsp;的jar包只有Provider本身是必要的,后两个包是方便你编程而提供的.例如有了S/MIME包后,你就不再需要为诸如"加密一个字符串或者一片文章然后签名"之类的很现实的应用程序写上一大堆代码了,只要引用S/MIME包中的某几个类,很快就可以搞定.而open pgp的存在,使你在用Java编写和PGP/GPG交互的程序时方便多了.</P>
<P>&nbsp;&nbsp;&nbsp; 这次先写这么多了,下次开始具体讲把这些东西搞下来后怎么开始干活吧.我以我现在手头上正在做的事情告诉大家,如何做一个CA.</P>
<P>&nbsp;&nbsp;&nbsp; 有了BC Provider,开CA,真的就是这么简单!</P></FONT><img src ="http://www.blogjava.net/neumqp/aggbug/31605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2006-02-20 11:07 <a href="http://www.blogjava.net/neumqp/archive/2006/02/20/31605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在oracle as数据源中配load balance</title><link>http://www.blogjava.net/neumqp/archive/2005/12/14/23773.html</link><dc:creator>小铁匠</dc:creator><author>小铁匠</author><pubDate>Wed, 14 Dec 2005 02:12:00 GMT</pubDate><guid>http://www.blogjava.net/neumqp/archive/2005/12/14/23773.html</guid><wfw:comment>http://www.blogjava.net/neumqp/comments/23773.html</wfw:comment><comments>http://www.blogjava.net/neumqp/archive/2005/12/14/23773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/neumqp/comments/commentRss/23773.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/neumqp/services/trackbacks/23773.html</trackback:ping><description><![CDATA[jdbc url：jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=10.0.0.1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.0.0.2)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=sa)))<BR>其他照常<img src ="http://www.blogjava.net/neumqp/aggbug/23773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/neumqp/" target="_blank">小铁匠</a> 2005-12-14 10:12 <a href="http://www.blogjava.net/neumqp/archive/2005/12/14/23773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>