<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>liyong0527</title>
    <description></description>
    <link>http://liyong0527.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Swing技巧8:完美的LookAndFeel解决方案(转存)</title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/154634" style="color:red;">http://liyong0527.javaeye.com/blog/154634</a>&nbsp;
          发表时间: 2008年01月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Swing技巧8:完美的LookAndFeel解决方案<br /><br />在<br />Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮<br />和<br />Swing技巧5:运行中重设LookAndFeel<br />中,我使用<br />if(currentLookAndFeel.getSupportsWindowDecorations()){<br />   frame.setUndecorated(true);<br />   frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />}<br />和<br />public static void setLookAndFeel(Component target, LookAndFeel lnf){<br />    try{<br />        UIManager.setLookAndFeel(lnf);<br />        SwingUtilities.updateComponentTreeUI(target);<br />    }catch(Exception e){<br />        System.out.println("ERROR: " + e);<br />    }<br />}<br />达到不但设置LookAndFeel,更使系统窗口,边框,标题,最小化,还原,最大化按钮也有LookAndFeel的目的.<br /><br />但此种方法缺点也很明显:<br />1.Matrix网友sslazio21反映新弹出的JFileChooser的系统窗口边框任为System LookAndFeel<br />2.对没有系统窗口,边框,标题的LookAndFeel,比如Windows,Motif及他们的子类,根JFrame也就没有系统窗口,边框,标题,导致无法最小化,还原,最大,改变大小.<br /><br />1的解决方法是我在Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮中提到的方法1:全局设置<br />//JFrame,JDialog.setDefaultLookAndFeelDecorated<br />//static global setting<br />//Provides a hint as to whether or not newly created JDialogs and JFrames should have their Window decorations<br />//(such as borders, widgets to close the window, title...) provided by the current look and feel. <br />JFrame.setDefaultLookAndFeelDecorated(true);<br /><br /><br />完整的初始化是<br />try{<br />    Class lafClass=Class.forName(currentLookAndFeel);<br />    LookAndFeel laf=(LookAndFeel)(lafClass.newInstance());<br />    JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />    JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />}catch(Exception e){}<br /><br />必须对JFrame和JDialog都设置.<br /><br />注意frame.setUndecorated(true)和JFrame.setDefaultLookAndFeelDecorated(true)必须在窗口显示之前,也就是frame.show()或frame.setVisible(true)之前.<br />因为setUndecorated的java doc说This method can only be called while the frame is not displayable.<br />setDefaultLookAndFeelDecorated的java doc说newly created JDialogs and JFrames,对新建窗口有效.<br /><br />对于2,我希望窗口,边框,标题的LookAndFeel随着setLookAndFeel而更改,如果是对没有窗口,边框,标题的LookAndFeel那么就使用System的系统窗口,边框,标题.<br />除了前面的初始化以外,我还改一下setLookAndFeel:<br />public static void setLookAndFeel(Component target, LookAndFeel lnf){<br />    try{<br />        JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        UIManager.setLookAndFeel(lnf);<br />        SwingUtilities.updateComponentTreeUI(target);<br />    }catch(Exception e){<br />        System.out.println("ERROR: " + e);<br />    }<br />}<br />对新建窗口(新弹出的JFileChooser)是有效了,但对已经存在的窗口,边框,标题不会改变.<br />看来对已经存在的窗口,必须使用<br />frame.setUndecorated(true);<br />frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />但有setUndecorated:This method can only be called while the frame is not displayable.<br />试试<br />frame.hide();<br />frame.setUndecorated(true);<br />frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />frame.show();<br />不但没有效果,在setLookAndFeel时还失去响应.<br /><br />查java doc发现the frame is not displayable的状态只有在frame的第一次show()之前和dispose()以后.<br />只有dispose()以后了:<br />frame.dispose();<br />frame.setUndecorated(true);<br />frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />frame.show();<br /><br /><br />这样可以说是Swing LookAndFeel的完美解决方案,最终代码如下:<br /><br />初始化时,第一个窗口建立之前:<br />try{<br />    Class lafClass=Class.forName(currentLookAndFeel);<br />    LookAndFeel laf=(LookAndFeel)(lafClass.newInstance());<br />    JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />    JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />}catch(Exception e){}<br /><br />public static void setLookAndFeel(JFrame frame, LookAndFeel lnf){<br />    try{<br />        //改变全局设置<br />        JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        UIManager.setLookAndFeel(lnf);<br />        <br />        //改变当前frame的窗口,边框,标题<br />        frame.dispose();<br />        frame.setUndecorated(lnf.getSupportsWindowDecorations());<br />        frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />        frame.show();<br /><br />        SwingUtilities.updateComponentTreeUI(frame);<br />    }catch(Exception e){<br />        System.out.println("ERROR: " + e);<br />    }<br />}<br />很不幸,对JDialog必须也有一个,虽然只改了一个单词,还是要有.<br />public static void setLookAndFeel(JDialog frame, LookAndFeel lnf){<br />    try{<br />        //改变全局设置<br />        JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations());<br />        UIManager.setLookAndFeel(lnf);<br />        <br />        //改变当前frame的窗口,边框,标题<br />        frame.dispose();<br />        frame.setUndecorated(lnf.getSupportsWindowDecorations());<br />        frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);<br />        frame.show();<br /><br />        SwingUtilities.updateComponentTreeUI(frame);<br />    }catch(Exception e){<br />        System.out.println("ERROR: " + e);<br />    }<br />}<br /><br />参考资料:<br />1.Java Docs<br />2.Swing技巧5:运行中重设LookAndFeel,来自SwingSet2源码<br />3.Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮,中第二种方法,来自BeanBuilder源码<br /><br />PS:<br />1.用此种方法改造的SwingSet2:<br /> 『 点击下载 』<br />可以用ant编译.<br />只改了SwingSet2.java文件,大家可以用Windiff(Vc6中有)或WinMerge与原始文件(在%Java_home%\demo\jfc\SwingSet2\SwingSet2.jar\src\中)比较.<br />第三方LookAndFeel,可以到 www.javootoo.com 下载,放在%Java_home%\jre\lib\ext\中.中<br /><br />2.为什么对JFrame和JDialog,有一个完全相同的setLookAndFeel?<br />因为Swing的继承体系:<br />         Window<br />        /   |         Frame |  Dialog<br />       |    |     |<br />       | JWindow  |<br />       |          |<br />     JFrame   JDialog<br />setUndecorated只有JFrame和JDialog中有.<br />很奇怪的继承体系,不是吗?JFrame和JDialog也应该是JWindow的子类,这样才符合直觉.但java是单根继承的,sun又该死的弄了两套gui,awt和swing.
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/154634#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Jan 2008 10:06:15 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/154634</link>
        <guid>http://liyong0527.javaeye.com/blog/154634</guid>
      </item>
      <item>
        <title>JDK1.6新特征 </title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/151131" style="color:red;">http://liyong0527.javaeye.com/blog/151131</a>&nbsp;
          发表时间: 2007年12月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1:对Console的支持<br /><br />  对于一些需要Dos窗口或者是Linux的管理台的程序来说,这是非常不错的消息.<br /> <br />    演示代码:<br /><br />import java.io.*;<br />public class ConsoleTest {<br />public static void main(String[] args) {<br />Console console = System.console();//获得Console实例<br />Object[] a1={};<br />Object[] a2={};<br />if(console!=null){//判断console是否可用<br />String user = new String(console.readLine("Enter user:",a1)); //读取整行字符<br />String pwd = new String(console.readPassword("Enter passowrd:",a2)); //读取密码,密码输入时不会显示<br />console.printf("User is:"+user+"\n",a1);<br />console.printf("Password is:"+pwd+"\n",a2);<br />}else{<br />System.out.println("Console is unavailable");<br />}<br />}<br /><br />}<br /><br /><br />当然如果你在IDE开发环境下运行可能报错哦。不过你在windows 的CMD下运行.你就可以发现:<br /><br />Enter user:chinajash<br />Enter passowrd:<br />User is:chinajash<br />Password is:chinajash<br /><br />2:对动态编辑技术的支持。<br /><br />    我们在使用Eclipse开发Jsp的时候就会发现,如果你修改了java代码,每次都要从新发布一次,真是非常麻烦,所以如果能支持动态编译那将是多么的好啊。<br /><br />    一看以下代码那将全明白啦.<br /><br />      public class CompilerAPITester {<br />　private static String JAVA_SOURCE_FILE = "DynamicObject.java";<br />　private static String JAVA_CLASS_FILE = "DynamicObject.class";<br />　private static String JAVA_CLASS_NAME = "DynamicObject";<br />　public static void main(String[] args) {<br />　　JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();<br />　　StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);<br />　　generateJavaClass();<br />　　try {<br />　　　//将产生的类文件拷贝到程序的ClassPath下面,下面这一行代码是特定于Windows＋IntelliJ IDEA 6.0项目,不具有移植性<br />　　　Runtime.getRuntime().exec("cmd /c copy "+JAVA_CLASS_FILE+" classes\\production\\JDK6Features");<br />　　　Iterable sourcefiles = fileManager.getJavaFileObjects(JAVA_SOURCE_FILE);<br />　　　compiler.getTask(null, fileManager, null, null, null, sourcefiles).call();<br />　　　fileManager.close();<br />　　　Class.forName(JAVA_CLASS_NAME).newInstance();//创建动态编译得到的DynamicObject类的实例<br />　　} catch (Exception ex) {<br />　　　ex.printStackTrace();<br />　　}<br />　}<br /><br />　public static void generateJavaClass(){<br />　　try {<br />　　　FileWriter fw = new FileWriter(JAVA_SOURCE_FILE);<br />　　　BufferedWriter bw = new BufferedWriter(fw);<br />　　　bw.write("public class "+JAVA_CLASS_NAME+"{");<br />　　　bw.newLine();<br />　　　bw.write("public "+JAVA_CLASS_NAME+"(){System.out.println(\"In the constructor of DynamicObject\");}}");<br />　　　bw.flush();<br />　　　bw.close();<br />　　} catch (IOException ex) {<br />　　　ex.printStackTrace();<br />　　}<br />　}<br />}<br /><br /><br />程序运行后，会产生DynamicObject.java和DynamicObject.class两个文件，并在控制台输出：<br /><br />　　In the constructor of DynamicObject<br /><br />加上classloader使用那将使你的程序将完全具备动态的能力!
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/151131#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Dec 2007 10:17:39 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/151131</link>
        <guid>http://liyong0527.javaeye.com/blog/151131</guid>
      </item>
      <item>
        <title>Java SE 6 新特性: HTTP 增强(转载)</title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/151130" style="color:red;">http://liyong0527.javaeye.com/blog/151130</a>&nbsp;
          发表时间: 2007年12月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          概述<br /><br />　　Java 语言从诞生的那天起，就非常注重网络编程方面的应用。随着互联网应用的飞速发展，Java 的基础类库也不断地对网络相关的 API 进行加强和扩展。在 Java SE 6 当中，围绕着 HTTP 协议出现了很多实用的新特性：NTLM 认证提供了一种 Window 平台下较为安全的认证机制；JDK 当中提供了一个轻量级的 HTTP 服务器；提供了较为完善的 HTTP Cookie 管理功能；更为实用的 NetworkInterface；DNS 域名的国际化支持等等。<br /><br />　　NTLM 认证<br /><br />　　不可避免，网络中有很多资源是被安全域保护起来的。访问这些资源需要对用户的身份进行认证。下面是一个简单的例子：<br /><br /><br />import java.net.*;<br />import java.io.*;<br /><br />public class Test {<br />　public static void main(String[] args) throws Exception {<br />　　URL url = new URL("http://PROTECTED.com");<br />　　URLConnection connection = url.openConnection();<br />　　InputStream in = connection.getInputStream();<br />　　byte[] data = new byte[1024];<br />　　while(in.read(data)>0)<br />　　{<br />　　　//do something for data<br />　　}<br />　　in.close();<br />　}<br />} <br /><br /><br />　　当 Java 程序试图从一个要求认证的网站读取信息的时候，也就是说，从联系于 http://Protected.com 这个 URLConnection 的 InputStream 中 read 数据时，会引发 FileNotFoundException。尽管笔者认为，这个 Exception 的类型与实际错误发生的原因实在是相去甚远；但这个错误确实是由网络认证失败所导致的。 <br /><br />　　要解决这个问题，有两种方法：<br /><br />　　其一，是给 URLConnection 设定一个“Authentication”属性：<br /><br /><br />String credit = USERNAME + ":" + PASSWORD;<br />String encoding = new sun.misc.BASE64Encoder().encode (credit.getBytes());<br />connection.setRequestProperty ("Authorization", "Basic " + encoding); <br /><br /><br />　　这里假设 http://PROTECTED.COM 使用了基本（Basic）认证类型。<br /><br />　　从上面的例子，我们可以看出，设定 Authentication 属性还是比较复杂的：用户必须了解认证方式的细节，才能将用户名/密码以一定的规范给出，然后用特定的编码方式加以编码。Java 类库有没有提供一个封装了认证细节，只需要给出用户名/密码的工具呢？<br /><br />　　这就是我们要介绍的另一种方法，使用 java.net.Authentication 类。<br /><br />　　每当遇到网站需要认证的时候，HttpURLConnection 都会向 Authentication 类询问用户名和密码。<br /><br />　　Authentication 类不会知道究竟用户应该使用哪个 username/password 那么用户如何向 Authentication 类提供自己的用户名和密码呢?<br /><br />　　提供一个继承于 Authentication 的类，实现 getPasswordAuthentication 方法，在 PasswordAuthentication 中给出用户名和密码：<br /><br /><br />class DefaultAuthenticator extends Authenticator {<br />　public PasswordAuthentication getPasswordAuthentication () {<br />　　return new PasswordAuthentication ("USER", "PASSWORD".toCharArray());<br />　}<br />} <br /><br /><br />　　然后，将它设为默认的（全局）Authentication:<br /><br /><br />Authenticator.setDefault (new DefaultAuthenticator()); <br /><br /><br />　　那么，不同的网站需要不同的用户名/密码又怎么办呢?<br /><br />　　Authentication 提供了关于认证发起者的足够多的信息，让继承类根据这些信息进行判断，在 getPasswordAuthentication 方法中给出了不同的认证信息：<br /><br /><br />getRequestingHost() <br />getRequestingPort() <br />getRequestingPrompt() <br />getRequestingProtocol() <br />getRequestingScheme() <br />getRequestingURL() <br />getRequestingSite() <br />getRequestorType()  <br /><br /><br />　　另一件关于 Authentication 的重要问题是认证类型。不同的认证类型需要 Authentication 执行不同的协议。至 Java SE 6.0 为止，Authentication 支持的认证方式有：<br /><br /><br />HTTP Basic authentication <br />HTTP Digest authentication <br />NTLM <br />Http SPNEGO Negotiate <br />Kerberos <br />NTLM  <br /><br /><br />　　这里我们着重介绍 NTLM。<br /><br />　　NTLM 是 NT LAN Manager 的缩写。早期的 SMB 协议在网络上明文传输口令，这是很不安全的。微软随后提出了 WindowsNT 挑战/响应验证机制，即 NTLM。<br /><br />　　NTLM 协议是这样的： <br /><br />　　·客户端首先将用户的密码加密成为密码散列； <br /><br />　　·客户端向服务器发送自己的用户名，这个用户名是用明文直接传输的； <br /><br />　　·服务器产生一个 16 位的随机数字发送给客户端，作为一个 challenge（挑战） ； <br /><br />　　·客户端用步骤1得到的密码散列来加密这个 challenge ，然后把这个返回给服务器； <br /><br />　　·服务器把用户名、给客户端的 challenge 、客户端返回的 response 这三个东西，发送域控制器 ； <br /><br />　　·域控制器用这个用户名在 SAM 密码管理库中找到这个用户的密码散列，然后使用这个密码散列来加密 challenge； <br /><br />　　·域控制器比较两次加密的 challenge ，如果一样，那么认证成功； <br /><br />　　Java 6 以前的版本，是不支持 NTLM 认证的。用户若想使用 HttpConnection 连接到一个使用有 Windows 域保护的网站时，是无法通过 NTLM 认证的。另一种方法，是用户自己用 Socket 这样的底层单元实现整个协议过程，这无疑是十分复杂的。<br /><br />　　终于，Java 6 的 Authentication 类提供了对 NTLM 的支持。使用十分方便，就像其他的认证协议一样：<br /><br /><br />class DefaultAuthenticator extends Authenticator {<br />　private static String username = "username ";<br />　private static String domain = "domain ";<br />　private static String password = "password ";<br /><br />　public PasswordAuthentication getPasswordAuthentication() {<br />　　String usernamewithdomain = domain + "/ "+username;<br />　　return (new PasswordAuthentication(usernamewithdomain, password.toCharArray()));<br />　}<br />} <br /><br /><br />　　这里，根据 Windows 域账户的命名规范，账户名为域名+”/”+域用户名。如果不想每生成 PasswordAuthentication 时，每次添加域名，可以设定一个系统变量名“http.auth.ntlm.domain“。<br /><br />　　Java 6 中 Authentication 的另一个特性是认证协商。目前的服务器一般同时提供几种认证协议，根据客户端的不同能力，协商出一种认证方式。比如，IIS 服务器会同时提供 NTLM with kerberos 和 NTLM 两种认证方式，当客户端不支持 NTLM with kerberos 时，执行 NTLM 认证。<br /><br />　　目前，Authentication 的默认协商次序是：<br /><br />GSS/SPNEGO -> Digest -> NTLM -> Basic<br /><br />　　那么 kerberos 的位置究竟在哪里呢?<br /><br />　　事实上，GSS/SPNEGO 以 JAAS 为基石，而后者实际上就是使用 kerberos 的。<br /><br />　　轻量级 HTTP 服务器<br /><br />　　Java 6 还提供了一个轻量级的纯 Java Http 服务器的实现。下面是一个简单的例子：<br /><br /><br />public static void main(String[] args) throws Exception{<br />　HttpServerProvider httpServerProvider = HttpServerProvider.provider();<br />　InetSocketAddress addr = new InetSocketAddress(7778);<br />　HttpServer httpServer = httpServerProvider.createHttpServer(addr, 1);<br />　httpServer.createContext("/myapp/", new MyHttpHandler());<br />　httpServer.setExecutor(null);<br />　httpServer.start();<br />　System.out.println("started");<br />}<br /><br />static class MyHttpHandler implements HttpHandler{<br />　public void handle(HttpExchange httpExchange) throws IOException { <br />　　String response = "Hello world!";<br />　　httpExchange.sendResponseHeaders(200, response.length());<br />　　OutputStream out = httpExchange.getResponseBody();<br />　　out.write(response.getBytes());<br />　　out.close();<br />　} <br />} <br /><br /><br />　　然后，在浏览器中访问 http://localhost:7778/myapp/，我们得到：<br /><br /><br />图一 浏览器显示 <br /><br />　　首先，HttpServer 是从 HttpProvider 处得到的，这里我们使用了 JDK 6 提供的实现。用户也可以自行实现一个 HttpProvider 和相应的 HttpServer 实现。<br /><br />　　其次，HttpServer 是有上下文（context）的概念的。比如，http://localhost:7778/myapp/ 中“/myapp/”就是相对于 HttpServer Root 的上下文。对于每个上下文，都有一个 HttpHandler 来接收 http 请求并给出回答。<br /><br />　　最后，在 HttpHandler 给出具体回答之前，一般先要返回一个 Http head。这里使用 HttpExchange.sendResponseHeaders(int code, int length)。其中 code 是 Http 响应的返回值，比如那个著名的 404。length 指的是 response 的长度，以字节为单位。<br /><br />Cookie 管理特性<br /><br />　　Cookie 是 Web 应用当中非常常用的一种技术， 用于储存某些特定的用户信息。虽然，我们不能把一些特别敏感的信息存放在 Cookie 里面，但是，Cookie 依然可以帮助我们储存一些琐碎的信息，帮助 Web 用户在访问网页时获得更好的体验，例如个人的搜索参数，颜色偏好以及上次的访问时间等等。网络程序开发者可以利用 Cookie 来创建有状态的网络会话（Stateful Session）。 Cookie 的应用越来越普遍。在 Windows 里面，我们可以在“Documents And Settings”文件夹里面找到IE使用的 Cookie，假设用户名为 admin，那么在 admin 文件夹的 Cookies 文件夹里面，我们可以看到名为“admin@(domain)”的一些文件，其中的 domain 就是表示创建这些 Cookie 文件的网络域， 文件里面就储存着用户的一些信息。<br /><br />　　JavaScript 等脚本语言对 Cookie 有着很不错的支持。 .NET 里面也有相关的类来支持开发者对 Cookie 的管理。 不过，在 Java SE 6 之前， Java一直都没有提供 Cookie 管理的功能。在 Java SE 5 里面， java.net 包里面有一个 CookieHandler 抽象类，不过并没有提供其他具体的实现。到了 Java SE 6， Cookie 相关的管理类在 Java 类库里面才得到了实现。有了这些 Cookie 相关支持的类，Java 开发者可以在服务器端编程中很好的操作 Cookie， 更好的支持 HTTP 相关应用，创建有状态的 HTTP 会话。<br /><br />　　·用 HttpCookie 代表 Cookie <br /><br />　　java.net.HttpCookie 类是 Java SE 6 新增的一个表示 HTTP Cookie 的新类， 其对象可以表示 Cookie 的内容， 可以支持所有三种 Cookie 规范：<br /><br />　　Netscape 草案 <br />　　RFC 2109 - http://www.ietf.org/rfc/rfc2109.txt <br />　　RFC 2965 - http://www.ietf.org/rfc/rfc2965.txt <br />　　这个类储存了 Cookie 的名称，路径，值，协议版本号，是否过期，网络域，最大生命期等等信息。<br /><br />　　·用 CookiePolicy 规定 Cookie 接受策略 <br /><br />　　java.net.CookiePolicy 接口可以规定 Cookie 的接受策略。 其中唯一的方法用来判断某一特定的 Cookie 是否能被某一特定的地址所接受。 这个类内置了 3 个实现的子类。一个类接受所有的 Cookie，另一个则拒绝所有，还有一个类则接受所有来自原地址的 Cookie。<br /><br />　　·用CookieStore 储存 Cookie <br /><br />　　java.net.CookieStore 接口负责储存和取出 Cookie。 当有 HTTP 请求的时候，它便储存那些被接受的 Cookie； 当有 HTTP 回应的时候，它便取出相应的 Cookie。 另外，当一个 Cookie 过期的时候，它还负责自动删去这个 Cookie。<br /><br />　　·用 CookieManger/CookieHandler 管理 Cookie <br /><br />　　java.net.CookieManager 是整个 Cookie 管理机制的核心，它是 CookieHandler 的默认实现子类。下图显示了整个 HTTP Cookie 管理机制的结构：<br /><br /><br /><br />图 2. Cookie 管理类的关系 <br /><br />　　一个 CookieManager 里面有一个 CookieStore 和一个 CookiePolicy，分别负责储存 Cookie 和规定策略。用户可以指定两者，也可以使用系统默认的 CookieManger。<br /><br />　　例子 <br /><br />　　下面这个简单的例子说明了 Cookie 相关的管理功能：<br /><br /><br />// 创建一个默认的 CookieManager<br />CookieManager manager = new CookieManager();<br /><br />// 将规则改掉，接受所有的 Cookie<br />manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);<br /><br />// 保存这个定制的 CookieManager<br />CookieHandler.setDefault(manager);<br /><br />// 接受 HTTP 请求的时候，得到和保存新的 Cookie<br />HttpCookie cookie = new HttpCookie("...(name)...","...(value)...");<br />manager.getCookieStore().add(uri, cookie);<br /><br />// 使用 Cookie 的时候：<br />// 取出 CookieStore <br />CookieStore store = manager.getCookieStore();<br /><br />// 得到所有的 URI <br />List&lt;URI> uris = store.getURIs();<br />for (URI uri : uris) {<br />// 筛选需要的 URI<br />// 得到属于这个 URI 的所有 Cookie<br />List&lt;HttpCookie> cookies = store.get(uri);<br />for (HttpCookie cookie : cookies) {<br />　// 取出了 Cookie<br />}<br />}<br /><br />// 或者，取出这个 CookieStore 里面的全部 Cookie<br />// 过期的 Cookie 将会被自动删除<br />List&lt;HttpCookie> cookies = store.getCookies();<br />for (HttpCookie cookie : cookies) {<br />　// 取出了 Cookie<br />} <br /><br /><br />其他新特性<br /><br />　　·NetworkInterface 的增强<br /><br />　　从 Java SE 1.4 开始，JDK 当中出现了一个网络工具类 java.net.NetworkInterface，提供了一些网络的实用功能。 在 Java SE 6 当中，这个工具类得到了很大的加强，新增了很多实用的方法。例如：<br /><br />　　public boolean isUp() <br />　　用来判断网络接口是否启动并运行 <br /><br />　　public boolean isLoopback() <br />　　用来判断网络接口是否是环回接口（loopback） <br /><br />　　public boolean isPointToPoint() <br />　　用来判断网络接口是否是点对点（P2P）网络 <br /><br />　　public boolean supportsMulticast() <br />　　用来判断网络接口是否支持多播 <br /><br />　　public byte[] getHardwareAddress() <br />　　用来得到硬件地址（MAC） <br /><br />　　public int getMTU() <br />　　用来得到最大传输单位（MTU，Maximum Transmission Unit） <br /><br />　　public boolean isVirtual() <br />　　用来判断网络接口是否是虚饨涌?<br /><br />　　关于此工具类的具体信息，请参考 Java SE 6 相应文档（见 参考资源）。<br /><br />　　·域名的国际化<br /><br />　　在最近的一些 RFC 文档当中，规定 DNS 服务器可以解析除开 ASCII 以外的编码字符。有一个算法可以在这种情况下做 Unicode 与 ASCII 码之间的转换，实现域名的国际化。java.net.IDN 就是实现这个国际化域名转换的新类，IDN 是“国际化域名”的缩写（internationalized domain names）。这个类很简单，主要包括 4 个静态函数，做字符的转换。<br /><br />　　结束语<br /><br />　　Java SE 6 有着很多 HTTP 相关的新特性，使得 Java SE 平台本身对网络编程，尤其是基于 HTTP 协议的因特网编程，有了更加强大的支持。
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/151130#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Dec 2007 10:16:18 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/151130</link>
        <guid>http://liyong0527.javaeye.com/blog/151130</guid>
      </item>
      <item>
        <title>Apache CXF 2.0 基于spring的web service开发</title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/148317" style="color:red;">http://liyong0527.javaeye.com/blog/148317</a>&nbsp;
          发表时间: 2007年12月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Apache CXF Developing a Service using JAX-WS<br />two approaches:<br /> I.WSDL First Development<br />Generate starting point code. <br />Implement the service's operations. <br />Publish the implemented service. <br /> II.Java First Development <br /><br />Create a Service Endpoint Interface (SEI) that defines the methods you wish to expose as a service. <br />Add the required annotations to your code. <br />Generate the WSDL contract for your service. <br />Publish the service. <br />注意事项：<br />JAX-WS relies on the annotation feature of Java 5. 通过对Interface和implement class添加annotation来映射wsdl.<br />使用Java First Development，首先要创建SEI和实现类。<br />然后添加annotation<br />@WebService<br />name：用于Interface，属映射到wsdl:portType element的name属性。<br />targetNamespace：用于Interface和implement，如果不指定，缺省会使用包名做为wsdl名空间。<br />serviceName：用于implement，表示wsdl服务名。<br />portName：用于implement，表示wsdl:port 的name属性。<br />endpointInterface：用于implement，指定Interface全名，包括包名。<br />如果Service Endpoint Interface中包含用户自定义的复杂类型，如Address，Role etc.<br />@SOAPBinding如果用document style（缺省），parameterStyle要使用ParameterStyle.BARW（缺省是ParameterStyle.WRAPPED ），如果用RPC style,则只能使用ParameterStyle.WRAPPED。<br />@WebMethod(exclude=true)可以将不希望暴露的方法屏蔽。<br />对于简单的web service,其他annotation可以省略不用。 <br /><br />Property  Values  Description  <br />style  Style.DOCUMENT (default)<br />Style.RPC  Specifies the style of the SOAP message. If RPC style is specified, each message part within the SOAP body is a parameter or return value and will appear inside a wrapper element within the soap:body element. The message parts within the wrapper element correspond to operation parameters and must appear in the same order as the parameters in the operation. If DOCUMENT style is specified, the contents of the SOAP body must be a valid XML document, but its form is not as tightly constrained.  <br />use  Use.LITERAL (default)<br />Use.ENCODED  Specifies how the data of the SOAP message is streamed.  <br />parameterStyle  ParameterStyle.BARE<br />ParameterStyle.WRAPPED (default)  Specifies how the method parameters, which correspond to message parts in a WSDL contract, are placed into the SOAP message body. A parameter style of BARE means that each parameter is placed into the message body as a child element of the message root. A parameter style of WRAPPED means that all of the input parameters are wrapped into a single element on a request message and that all of the output parameters are wrapped into a single element in the response message. If you set the style to RPC you must use the WRAPPED parameter style.  <br /><br /><br />This example will lead you through creating your first service with Spring. You'll learn how to: <br /><br />Set up your build for CXF <br />Writing a simple JAX-WS service <br />Set up the HTTP transport <br />This example corresponds to the spring_http example in the CXF distribution. <br /><br />Setting up your build<br />Open up your favorite IDE and create a new project. The first thing we need to do is add the necessary CXF dependencies to the project. You can find these dependencies in the CXF distribution in the lib directory. <br /><br />commons-logging-1.1.jar<br />geronimo-activation_1.1_spec-1.0-M1.jar (or Sun's Activation jar)<br />geronimo-annotation_1.0_spec-1.1.jar (JSR 250)<br />geronimo-javamail_1.4_spec-1.0-M1.jar (or Sun's JavaMail jar)<br />geronimo-servlet_2.5_spec-1.1-M1.jar (or Sun's Servlet jar)<br />geronimo-ws-metadata_2.0_spec-1.1.1.jar (JSR 181)<br />jaxb-api-2.0.jar<br />jaxb-impl-2.0.5.jar<br />jaxws-api-2.0.jar<br />saaj-api-1.3.jar<br />saaj-impl-1.3.jar<br />stax-api-1.0.1.jar<br />wsdl4j-1.6.1.jar<br />wstx-asl-3.2.1.jar<br />XmlSchema-1.2.jarThe Spring jars: <br /><br />aopalliance-1.0.jar<br />spring-core-2.0.4.jar<br />sprint-beans-2.0.4.jar<br />spring-context-2.0.4.jar<br />spring-web-2.0.4.jarAnd the CXF jar: <br /><br />cxf-2.0-incubator.jarWriting your Service<br />First we'll write our service interface. It will have one operation called "sayHello" which says "Hello" to whoever submits their name. <br /><br />package demo.spring;<br /><br />import javax.jws.WebService;<br /><br />@WebService<br />public interface HelloWorld {<br />    String sayHi(String text);<br />}Our implementation will then look like this: <br /><br />package demo.spring;<br /><br />import javax.jws.WebService;<br /><br />@WebService(endpointInterface = "demo.spring.HelloWorld")<br />public class HelloWorldImpl implements HelloWorld {<br /><br />    public String sayHi(String text) {<br />        return "Hello " + text;<br />    }<br />}The @WebService annotation on the implementation class lets CXF know which interface we want to create our WSDL with. In this case its simply our HelloWorld interface. <br /><br />Declaring your server beans<br />CXF contains support for "nice XML" within Spring 2.0. For the JAX-WS side of things, we have a &lt;jaxws:endpoint> bean which sets up a server side endpoint. <br /><br />Lets create a "beans.xml" file in our WEB-INF directory which declares an endpoint bean: <br /><br />&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />	xmlns:jaxws="http://cxf.apache.org/jaxws"<br />	xsi:schemaLocation="<br />http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd<br />http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"><br /><br />	&lt;import resource="classpath:META-INF/cxf/cxf.xml" /><br />	&lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /><br />	&lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /><br /><br />	&lt;jaxws:endpoint <br />	  id="helloWorld" <br />	  implementor="demo.spring.HelloWorldImpl" <br />	  address="/HelloWorld" /><br />	  <br />&lt;/beans>The bean is pretty self explanatory. The id becomes the id of the bean in the Spring context. The serviceClass property is our implementation class. Finally, the address property specifies the location which we want to host our service at. This can be either a full address with host & port or just a path. <br /><br />To provide a bean name instead of a classname as an implementor, simply supply the bean-name prepended with "#", e.g. implementor="#myBean". <br /><br />Setting up the Servlet<br />We'll need to add two things to our web.xml. First, the Spring ContextLoaderLister. This starts Spring and loads our beans.xml file. We can specify where our file is via a &lt;context-param>. The second thing is the CXF Servlet. <br /><br />&lt;web-app><br />	&lt;context-param><br />		&lt;param-name>contextConfigLocation&lt;/param-name><br />		&lt;param-value>WEB-INF/beans.xml&lt;/param-value><br />	&lt;/context-param><br /><br />	&lt;listener><br />		&lt;listener-class><br />			org.springframework.web.context.ContextLoaderListener<br />		&lt;/listener-class><br />	&lt;/listener><br /><br />	&lt;servlet><br />		&lt;servlet-name>CXFServlet&lt;/servlet-name><br />		&lt;display-name>CXF Servlet&lt;/display-name><br />		&lt;servlet-class><br />			org.apache.cxf.transport.servlet.CXFServlet<br />		&lt;/servlet-class><br />		&lt;load-on-startup>1&lt;/load-on-startup><br />	&lt;/servlet><br /><br />	&lt;servlet-mapping><br />		&lt;servlet-name>CXFServlet&lt;/servlet-name><br />		&lt;url-pattern>/*&lt;/url-pattern><br />	&lt;/servlet-mapping><br />&lt;/web-app>It is important to note that the address that you chose for your endpoint bean must be one your servlet listens on. For instance, if my Servlet was register for "/some-services/*" but my address was "/more-services/HelloWorld", there is no way CXF could receive a request. <br /><br />Create a Client<br />CXF includes a JaxWsProxyFactory bean which create a client for you from your service interface. You simply need to tell it what your service class is (the HelloWorld interface in this case) and the URL of your service. You can then create a client bean via the JaxWsProxyFactory bean by calling it's create() method. <br /><br />Here's an example: <br /><br />&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />	xmlns:jaxws="http://cxf.apache.org/jaxws"<br />	xsi:schemaLocation="<br />http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd<br />http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd"><br /><br />    &lt;bean id="client" class="demo.spring.HelloWorld" <br />      factory-bean="clientFactory" factory-method="create"/><br />    <br />	&lt;bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"><br />	  &lt;property name="serviceClass" value="demo.spring.HelloWorld"/><br />	  &lt;property name="address" value="http://localhost:9002/HelloWorld"/><br />	&lt;/bean><br />	  <br />&lt;/beans>If you were going to access your client you could now simply pull it out of the Spring context (or better yet, inject it into your application using Spring!): <br /><br />ApplicationContext context = ...; // your Spring ApplicationContext<br />HellWorld client = (HelloWorld) context.getBean("client");
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/148317#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 14 Dec 2007 13:22:35 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/148317</link>
        <guid>http://liyong0527.javaeye.com/blog/148317</guid>
      </item>
      <item>
        <title>Java多线程编程技术</title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/147765" style="color:red;">http://liyong0527.javaeye.com/blog/147765</a>&nbsp;
          发表时间: 2007年12月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          线程是被个别创建的，但可以将它们归类到线程组中，以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中，使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。 <br /><br />线程间发信 <br /><br />当线程在继续执行前需要等待一个条件时，仅有 synchronized 关键字是不够的。虽然 synchronized 关键字阻止并发更新一个对象，但它没有实现线程间发信。Object 类为此提供了三个函数：wait()、notify() 和 notifyAll()。以全球气候预测程序为例。这些程序通过将地球分为许多单元，在每个循环中，每个单元的计算都是隔离进行的，直到这些值趋于稳定， 然后相邻单元之间就会交换一些数据。所以，从本质上讲，在每个循环中各个线程都必须等待所有线程完成各自的任务以后才能进入下一个循环。这个模型称为 屏蔽同步，下例说明了这个模型： <br /><br />屏蔽同步 <br /><br />public class BSync {　int totalThreads;　int currentThreads;　public BSync(int x) {　　totalThreads = x;　　currentThreads = 0;　}　public synchronized void waitForAll() {　　currentThreads++;　　if(currentThreads &lt; totalThreads) {　　　try {　　　　wait();　　　} catch (Exception e) {}　　}　　else {　　　currentThreads = 0;　　　notifyAll();　　}　}}<br /> <br /><br />当对一个线程调用 wait() 时，该线程就被有效阻塞，只到另一个线程对同一个对象调用 notify() 或 notifyAll() 为止。因此，在前一个示例中，不同的线程在完成它们的工作以后将调用 waitForAll() 函数，最后一个线程将触发 notifyAll() 函数，该函数将释放所有的线程。第三个函数 notify() 只通知一个正在等待的线程，当对每次只能由一个线程使用的资源进行访问限制时，这个函数很有用。但是，不可能预知哪个线程会获得这个通知，因为这取决于 Java 虚拟机 (JVM) 调度算法。 <br /><br />将 CPU 让给另一个线程 <br /><br />当线程放弃某个稀有的资源（如数据库连接或网络端口）时，它可能调用 yield() 函数临时降低自己的优先级，以便某个其他线程能够运行。 <br /><br />守护线程 <br /><br />有两类线程：用户线程和守护线程。用户线程是那些完成有用工作的线程。 守护线程是那些仅提供辅助功能的线程。Thread 类提供了 setDaemon() 函数。Java 程序将运行到所有用户线程终止，然后它将破坏所有的守护线程。在 Java 虚拟机 (JVM) 中，即使在 main 结束以后，如果另一个用户线程仍在运行，则程序仍然可以继续运行。 <br /><br />避免不提倡使用的方法 <br /><br />不提倡使用的方法是为支持向后兼容性而保留的那些方法，它们在以后的版本中可能出 现，也可能不出现。Java 多线程支持在版本 1.1 和版本 1.2 中做了重大修订，stop()、suspend() 和 resume() 函数已不提倡使用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听起来很诱人，但请抵制诱惑不要使用它们。 <br /><br />调试线程化的程序 <br /><br />在线程化的程序中，可能发生的某些常见而讨厌的情况是死锁、活锁、内存损坏和资源耗尽。 <br /><br />死锁 <br /><br />死锁可能是多线程程序最常见的问题。当一个线程需要一个资源而另一个线程持有该资源 的锁时，就会发生死锁。这种情况通常很难检测。但是，解决方案却相当好：在所有的线程中按相同的次序获取所有资源锁。例如，如果有四个资源 ?A、B、C 和 D ? 并且一个线程可能要获取四个资源中任何一个资源的锁，则请确保在获取对 B 的锁之前首先获取对 A 的锁，依此类推。如果“线程 1”希望获取对 B 和 C 的锁，而“线程 2”获取了 A、C 和 D 的锁，则这一技术可能导致阻塞，但它永远不会在这四个锁上造成死锁。 <br /><br />活锁 <br /><br />当一个线程忙于接受新任务以致它永远没有机会完成任何任务时，就会发生活锁。这个线程最终将超出缓冲区并导致程序崩溃。试想一个秘书需要录入一封信，但她一直在忙于接电话，所以这封信永远不会被录入。 内存损坏 <br /><br />如果明智地使用 synchronized 关键字，则完全可以避免内存错误这种气死人的问题。 <br /><br />资源耗尽 <br /><br />某些系统资源是有限的，如文件描述符。多线程程序可能耗尽资源，因为每个线程都可能 希望有一个这样的资源。如果线程数相当大，或者某个资源的侯选线程数远远超过了可用的资源数，则最好使用 资源池。一个最好的示例是数据库连接池。只要线程需要使用一个数据库连接，它就从池中取出一个，使用以后再将它返回池中。资源池也称为 资源库。 <br /><br />调试大量的线程 <br /><br />有时一个程序因为有大量的线程在运行而极难调试。在这种情况下，下面的这个类可能会派上用场： <br /><br />public class Probe extends Thread {　public Probe() {}　public void run() {　　while(true) {　　　Thread[] x = new Thread[100];　　　Thread.enumerate(x);　　　for(int i=0; i&lt;100; i++) {　　　　Thread t = x[i];　　　　if(t == null)　　　　　break;　　　　else　　　　　System.out.println(t.getName() + "\t" + t.getPriority()+ "\t" + t.isAlive() + "\t" +t.isDaemon());　　　}　　}　}}<br /> <br /><br />限制线程优先级和调度 <br /><br />Java 线程模型涉及可以动态更改的线程优先级。本质上，线程的优先级是从 1 到 10 之间的一个数字，数字越大表明任务越紧急。JVM 标准首先调用优先级较高的线程，然后才调用优先级较低的线程。但是，该标准对具有相同优先级的线程的处理是随机的。如何处理这些线程取决于基层的操作系统 策略。在某些情况下，优先级相同的线程分时运行；在另一些情况下，线程将一直运行到结束。请记住，Java 支持 10 个优先级，基层操作系统支持的优先级可能要少得多，这样会造成一些混乱。因此，只能将优先级作为一种很粗略的工具使用。最后的控制可以通过明智地使用 yield() 函数来完成。通常情况下，请不要依靠线程优先级来控制线程的状态。 <br /><br />小结 <br /><br />本文说明了在 Java 程序中如何使用线程。像是否应该使用线程这样的更重要的问题在很大程序上取决于手头的应用程序。决定是否在应用程序中使用多线程的一种方法是，估计可以并行运行的代码量。并记住以下几点： <br /><br />使用多线程不会增加 CPU 的能力。但是如果使用 JVM 的本地线程实现，则不同的线程可以在不同的处理器上同时运行（在多 CPU 的机器中），从而使多 CPU 机器得到充分利用。 <br /><br />如果应用程序是计算密集型的，并受 CPU 功能的制约，则只有多 CPU 机器能够从更多的线程中受益。 <br /><br />当应用程序必须等待缓慢的资源（如网络连接或数据库连接）时，或者当应用程序是非交互式的时，多线程通常是有利的。 <br /><br />基于 Internet 的软件有必要是多线程的；否则，用户将感觉应用程序反映迟钝。例如，当开发要支持大量客户机的服务器时，多线程可以使编程较为容易。在这种情况下，每个线 程可以为不同的客户或客户组服务，从而缩短了响应时间。 某些程序员可能在 C 和其他语言中使用过线程，在那些语言中对线程没有语言支持。这些程序员可能通常都被搞得对线程失去了信心。
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/147765#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Dec 2007 12:33:02 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/147765</link>
        <guid>http://liyong0527.javaeye.com/blog/147765</guid>
      </item>
      <item>
        <title>使用 Java 进行图像处理 - 图像翻转     </title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/146476" style="color:red;">http://liyong0527.javaeye.com/blog/146476</a>&nbsp;
          发表时间: 2007年12月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: 14pt"><span style="color: blue"> public static </span>BufferedImage flipHorizontalJ2D(BufferedImage bufferedImage) ...{<br />        int width = bufferedImage.getWidth();<br />        int height = bufferedImage.getHeight();<br /><br />        BufferedImage <span style="color: blue">dstImage</span> = new BufferedImage(width, height, bufferedImage.getType());<br />        <br />        AffineTransform <span style="color: blue">affineTransform</span> = new AffineTransform( -1, 0, 0, 1, width, 0);<br />        AffineTransformOp <span style="color: blue">affineTransformOp</span> = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);<br />        <br />        <span style="color: blue">return </span>affineTransformOp.filter(bufferedImage, dstImage);<br />    }<br /><br />    <span style="color: green">/** <br />     * 图像竖直翻转。<br />     * @param bufferedImage 原图像。<br />     * @return 返回竖直翻转后的图像。<br />     */</span><br />    <span style="color: blue">public static </span>BufferedImage flipVerticalJ2D(BufferedImage bufferedImage) ...{<br />        int width = bufferedImage.getWidth();<br />        int height = bufferedImage.getHeight();<br /><br />        BufferedImage <span style="color: darkblue">dstImage</span> = new BufferedImage(width, height, bufferedImage.getType());<br />        <br />        AffineTransform <span style="color: blue">affineTransform</span> = new AffineTransform(1, 0, 0, -1, 0, height);<br />        AffineTransformOp affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);<br />        <br />        <span style="color: blue">return</span> affineTransformOp.filter(bufferedImage, dstImage);<br />    }</span>
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/146476#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 06 Dec 2007 18:30:18 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/146476</link>
        <guid>http://liyong0527.javaeye.com/blog/146476</guid>
      </item>
      <item>
        <title>Java与.NET 的Web Services相互调用</title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/145951" style="color:red;">http://liyong0527.javaeye.com/blog/145951</a>&nbsp;
          发表时间: 2007年12月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一:简介<br /><br />　　本文介绍了Java与.NET开发的Web Services相互调用的技术。本文包括两个部分，第一部分介绍了如何用.NET做客户端调用Java写的Web Services,第二部分介绍了如何用Java做客户端调用.NET开发的Web Services。<br /><br />　　二:项目需要的工具<br /><br />　　Windows2000 Server(IIS)<br /><br />　　Jbuilder9.0( 含有Tomcat , axis)<br /><br />　　JDK1.4+Java Web Services Develop<br /><br />　　VS.Net 2003<br /><br />　　备注:如果没有JBuilder的话就需要自己下载安装Tomcat4.1 以及 Axis的开发包，并做相应配置。由于网上有很多这样的文章，这里就不一一说明了。<br /><br />　　三:用.NET做客户端调用Java写的Web Services<br /><br />　　1. 生成一个Java Web Services<br /><br />　　使用JBuilder 生成一个Web Services是非常简单的，我完全是按照它的帮助做的，只要一步步做下去就可以了。具体路径是Developing Web Services -> tutorials : Web Services(Axis) -> Creating a simple Web Services<br /><br />　　2. 发布这个Web Services并得到它的WSDL<br /><br />　　Web Services生成好之后，F9运行这个项目。然后，单击View浏览现有的Web 服务，单击Bean1的WSDL连接，我们可以在浏览器中察看它的WSDL描述。在浏览器地址栏复制WSDL地址，为下一步使用.NET开发客户端调用程序做准备。<br /><br />　　3. 用VS.NET生成一个.NET的客户端<br /><br />　　新建一个项目(WinForm,ASP.net都可以)，我在这里使用的是一个Asp.Net项目。在起始页面上放置一个文本输入框用来显示调用Web Services的结果，放置一个按钮，用来单击调用Web Services。然后，选择添加Web 引用，在WSDL一栏中把刚才得到的WSDL地址复制过来，Web 引用的名称输入JavaService，单击添加引用按钮就可以了。此时，我们可以在VS.net 的Solution Explore中看到这个Web 引用。<br /><br />　　在按钮的单击事件中输入下列代码:<br /><br />　　JavaService.Bean1 bean = new JavaService.Bean1();<br />　　TextBox1.Text = bean.getSample.ToString ();<br /><br />　　这样，一个.NET客户端就完成了，测试一下，工作正常，OK.<br /><br />四:用Java做客户端调用.NET写的 Web Services<br /><br />　　有了上面的成功，使我以为用Java做客户端调用也是一件十分容易的事情，可实际情况却耗费了我两天时间才得以实现。<br /><br />　　1. 用VS.NET新建一个Asp Web Services工程，添加一个web 服务，命名为SumService.asmx。新增一个web method，代码如下:<br /><br />　　[WebMethod]<br />　　public int IntAdd(int a,int b)<br />　　{<br />　　return a+b ;<br />　　}<br /><br />　　然后运行它，并利用IE进行测试成功。<br /><br />　　2. 打开jbuilder9.0,新建一个项目，添加一个java class ，命名为TestNetService，输入下列代码:<br /><br />package MyWebServiceJavaClient;<br />import java.util.Date;<br />import java.text.DateFormat;<br />import java.util.Date;<br />import java.text.DateFormat;<br />import org.apache.axis.client.Call;<br />import org.apache.axis.client.Service;<br />import javax.xml.namespace.QName;<br />import java.lang.Integer;<br />import javax.xml.rpc.ParameterMode;<br />/**<br />* Title: <br />* Description: <br />* Copyright: Copyright (c) 2004<br />* Company: <br />* @author not attributable<br />* @version 1.0<br />*/<br />public class TestNetService {<br />public TestNetService() {<br />}<br />public static void main(String[] args) {<br />try {<br />Integer i = new Integer(1);<br />Integer j = new Integer(2);<br />String endpoint="http://localhost/MyServices/WebServiceTest/SumService.asmx";<br />Service service = new Service();<br />Call call = (Call)service.createCall();<br />call.setTargetEndpointAddress(new java.net.URL(endpoint));<br />call.setOperationName(new QName("http://www.my.com/SU","IntAdd"));<br />call.addParameter("a",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);<br />call.addParameter("b",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);<br />call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);<br />call.setUseSOAPAction(true);<br />call.setSOAPActionURI("http://www.my.com/Rpc");<br />Integer k = (Integer)call.invoke(new Object[]{i,j});<br />System.out.println( "result is " + k.toString() + ".");<br />}<br />catch (Exception e) {System.err.println(e.toString());}<br />}<br />}<br /><br />　运行上面的java客户端程序，你会发现系统会抛出一个SoapAction异常。奇怪，怎么会错误呢?想到了我开发的asp web services没有指定SoapAction，于是在SumService.asmx中的 [web method] 的上一行添加下列代码:<br /><br />[SoapRpcMethod(Action="http://www.my.com/Rpc",RequestNamespace="http://www.my.com/SU",ResponseNamespace="http://www.my.com/SU")]<br /><br />　　重新编译运行asp web services后，在执行java程序，这时会发现输出了正确的结果3。<br /><br />　　这样，用java调用.net生成的web services也算初步完成了，好像也不是很复杂是吧。其实，在实际工作中，我一开始并没有在网上找到一个很好的代码例子，全部是依靠jbuilder 和 axis的帮助完成的, 可总是提示什么找不到相应的SoapAction。而实际上，我在运行了asp web services后是可以在IE浏览器中看到那个SoapAction的。我试验过将默认的SoapAction拷贝到java代码中，但是java客户端依然抛出同样的异常，这要我也很迷惑。<br /><br />　　五:总结<br /><br />　　经过两天的试验，终于从技术上明确了通过Web Services实现.net 与 java的互通是可能的。当然有几点是需要注意的:<br /><br />　　1. 在提供Web Services的时候，尽量使用xml schema中支持的变量类型做参数。如果使用.net 中的dataset这种类型，对于java来说解析起来将是一个灾难，当然，理论上是可以解析的。但是从效率角度来说，在Web Services与客户端交换信息的过程中，始终有一个序列化和反序列化的问题。如果使用dataset这种类型，系统还需要对它进行序列化操作，这将是一个很耗费资源的过程。而使用string类型将简单很多。<br /><br />　　2. 如果使用了soap header等扩展功能，例如使用了微软提供的WSE技术，它们之间的相互通信需要作特殊处理。<br /><br /><br /><br />一:简介<br /><br />　　本文介绍了Java与.NET开发的Web Services相互调用的技术。本文包括两个部分，第一部分介绍了如何用.NET做客户端调用Java写的Web Services,第二部分介绍了如何用Java做客户端调用.NET开发的Web Services。<br /><br />　　二:项目需要的工具<br /><br />　　Windows2000 Server(IIS)<br /><br />　　Jbuilder9.0( 含有Tomcat , axis)<br /><br />　　JDK1.4+Java Web Services Develop<br /><br />　　VS.Net 2003<br /><br />　　备注:如果没有JBuilder的话就需要自己下载安装Tomcat4.1 以及 Axis的开发包，并做相应配置。由于网上有很多这样的文章，这里就不一一说明了。<br /><br />　　三:用.NET做客户端调用Java写的Web Services<br /><br />　　1. 生成一个Java Web Services<br /><br />　　使用JBuilder 生成一个Web Services是非常简单的，我完全是按照它的帮助做的，只要一步步做下去就可以了。具体路径是Developing Web Services -> tutorials : Web Services(Axis) -> Creating a simple Web Services<br /><br />　　2. 发布这个Web Services并得到它的WSDL<br /><br />　　Web Services生成好之后，F9运行这个项目。然后，单击View浏览现有的Web 服务，单击Bean1的WSDL连接，我们可以在浏览器中察看它的WSDL描述。在浏览器地址栏复制WSDL地址，为下一步使用.NET开发客户端调用程序做准备。<br /><br />　　3. 用VS.NET生成一个.NET的客户端<br /><br />　　新建一个项目(WinForm,ASP.net都可以)，我在这里使用的是一个Asp.Net项目。在起始页面上放置一个文本输入框用来显示调用Web Services的结果，放置一个按钮，用来单击调用Web Services。然后，选择添加Web 引用，在WSDL一栏中把刚才得到的WSDL地址复制过来，Web 引用的名称输入JavaService，单击添加引用按钮就可以了。此时，我们可以在VS.net 的Solution Explore中看到这个Web 引用。<br /><br />　　在按钮的单击事件中输入下列代码:<br /><br />　　JavaService.Bean1 bean = new JavaService.Bean1();<br />　　TextBox1.Text = bean.getSample.ToString ();<br /><br />　　这样，一个.NET客户端就完成了，测试一下，工作正常，OK.<br /><br />四:用Java做客户端调用.NET写的 Web Services<br /><br />　　有了上面的成功，使我以为用Java做客户端调用也是一件十分容易的事情，可实际情况却耗费了我两天时间才得以实现。<br /><br />　　1. 用VS.NET新建一个Asp Web Services工程，添加一个web 服务，命名为SumService.asmx。新增一个web method，代码如下:<br /><br />　　[WebMethod]<br />　　public int IntAdd(int a,int b)<br />　　{<br />　　return a+b ;<br />　　}<br /><br />　　然后运行它，并利用IE进行测试成功。<br /><br />　　2. 打开jbuilder9.0,新建一个项目，添加一个java class ，命名为TestNetService，输入下列代码:<br /><br />package MyWebServiceJavaClient;<br />import java.util.Date;<br />import java.text.DateFormat;<br />import java.util.Date;<br />import java.text.DateFormat;<br />import org.apache.axis.client.Call;<br />import org.apache.axis.client.Service;<br />import javax.xml.namespace.QName;<br />import java.lang.Integer;<br />import javax.xml.rpc.ParameterMode;<br />/**<br />* Title: <br />* Description: <br />* Copyright: Copyright (c) 2004<br />* Company: <br />* @author not attributable<br />* @version 1.0<br />*/<br />public class TestNetService {<br />public TestNetService() {<br />}<br />public static void main(String[] args) {<br />try {<br />Integer i = new Integer(1);<br />Integer j = new Integer(2);<br />String endpoint="http://localhost/MyServices/WebServiceTest/SumService.asmx";<br />Service service = new Service();<br />Call call = (Call)service.createCall();<br />call.setTargetEndpointAddress(new java.net.URL(endpoint));<br />call.setOperationName(new QName("http://www.my.com/SU","IntAdd"));<br />call.addParameter("a",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);<br />call.addParameter("b",org.apache.axis.encoding.XMLType.XSD_DATE,javax.xml.rpc.ParameterMode.IN);<br />call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);<br />call.setUseSOAPAction(true);<br />call.setSOAPActionURI("http://www.my.com/Rpc");<br />Integer k = (Integer)call.invoke(new Object[]{i,j});<br />System.out.println( "result is " + k.toString() + ".");<br />}<br />catch (Exception e) {System.err.println(e.toString());}<br />}<br />}<br /><br />　运行上面的java客户端程序，你会发现系统会抛出一个SoapAction异常。奇怪，怎么会错误呢?想到了我开发的asp web services没有指定SoapAction，于是在SumService.asmx中的 [web method] 的上一行添加下列代码:<br /><br />[SoapRpcMethod(Action="http://www.my.com/Rpc",RequestNamespace="http://www.my.com/SU",ResponseNamespace="http://www.my.com/SU")]<br /><br />　　重新编译运行asp web services后，在执行java程序，这时会发现输出了正确的结果3。<br /><br />　　这样，用java调用.net生成的web services也算初步完成了，好像也不是很复杂是吧。其实，在实际工作中，我一开始并没有在网上找到一个很好的代码例子，全部是依靠jbuilder 和 axis的帮助完成的, 可总是提示什么找不到相应的SoapAction。而实际上，我在运行了asp web services后是可以在IE浏览器中看到那个SoapAction的。我试验过将默认的SoapAction拷贝到java代码中，但是java客户端依然抛出同样的异常，这要我也很迷惑。<br /><br />　　五:总结<br /><br />　　经过两天的试验，终于从技术上明确了通过Web Services实现.net 与 java的互通是可能的。当然有几点是需要注意的:<br /><br />　　1. 在提供Web Services的时候，尽量使用xml schema中支持的变量类型做参数。如果使用.net 中的dataset这种类型，对于java来说解析起来将是一个灾难，当然，理论上是可以解析的。但是从效率角度来说，在Web Services与客户端交换信息的过程中，始终有一个序列化和反序列化的问题。如果使用dataset这种类型，系统还需要对它进行序列化操作，这将是一个很耗费资源的过程。而使用string类型将简单很多。<br /><br />　　2. 如果使用了soap header等扩展功能，例如使用了微软提供的WSE技术，它们之间的相互通信需要作特殊处理。
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/145951#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Dec 2007 17:53:19 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/145951</link>
        <guid>http://liyong0527.javaeye.com/blog/145951</guid>
      </item>
      <item>
        <title>Maven 打包 jar 、war 文件时，不将 pom.xml 等打包进包中 </title>
        <author>liyong0527</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://liyong0527.javaeye.com">liyong0527</a>&nbsp;
          链接：<a href="http://liyong0527.javaeye.com/blog/145949" style="color:red;">http://liyong0527.javaeye.com/blog/145949</a>&nbsp;
          发表时间: 2007年12月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          如果是 jar 包，在 Plugin 中配置<br /><br />&lt;build><br />  &lt;plugins><br />    &lt;plugin><br />      &lt;groupId>org.apache.maven.plugins&lt;/groupId><br />      &lt;artifactId>maven-jar-plugin&lt;/artifactId><br />      &lt;configuration><br />        &lt;archive><br />          &lt;addMavenDescriptor>false&lt;/addMavenDescriptor><br />        &lt;/archive><br />      &lt;/configuration><br />    &lt;/plugin><br />  &lt;/plugins><br />&lt;/build><br /><br />如果是 war 包，在 Plugin 中配置<br /><br />&lt;build><br />  &lt;plugins><br />    &lt;plugin><br />      &lt;groupId>org.apache.maven.plugins&lt;/groupId><br />      &lt;artifactId>maven-war-plugin&lt;/artifactId><br />      &lt;configuration><br />        &lt;archive><br />          &lt;addMavenDescriptor>false&lt;/addMavenDescriptor><br />        &lt;/archive><br />      &lt;/configuration><br />    &lt;/plugin><br />  &lt;/plugins><br />&lt;/build><br /><br />这个是在 maven-archiver 中设置的，可以查看代码。
          <br/><br/>
          <span style="color:red;">
            <a href="http://liyong0527.javaeye.com/blog/145949#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Dec 2007 17:47:39 +0800</pubDate>
        <link>http://liyong0527.javaeye.com/blog/145949</link>
        <guid>http://liyong0527.javaeye.com/blog/145949</guid>
      </item>
  </channel>
</rss>