2006年5月13日

原文来自: HttpClient POST 的 UTF-8 编码问题

Apache HttpClient ( http://jakarta.apache.org/commons/httpclient/ ) 是一个纯 Java 的HTTP 协议的客户端编程工具包, 对 HTTP 协议的支持相当全面, 更多细节也可以参考IBM 网站上的这篇文章 HttpClient入门 ( http://www-128.ibm.com/developerworks/cn/opensource/os-httpclient/ ).

问题分析

不过在实际使用中, 还是发现按照最基本的方式调用 HttpClient 时, 并不支持 UTF-8 编码, 在网络上找过一些文章, 也不得要领, 于是查看了 commons-httpclient-3.0.1 的一些代码, 首先在 PostMethod 中找到了 generateRequestEntity() 方法:
    /**
     * Generates a request entity from the post parameters, if present.  Calls
     {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set.
     
     @since 3.0
     */
    protected RequestEntity generateRequestEntity() {
        if (!this.params.isEmpty()) {
            // Use a ByteArrayRequestEntity instead of a StringRequestEntity.
            // This is to avoid potential encoding issues.  Form url encoded strings
            // are ASCII by definition but the content type may not be.  Treating the content
            // as bytes allows us to keep the current charset without worrying about how
            // this charset will effect the encoding of the form url encoded string.
            String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet());
            ByteArrayRequestEntity entity = new ByteArrayRequestEntity(
                EncodingUtil.getAsciiBytes(content),
                FORM_URL_ENCODED_CONTENT_TYPE
            );
            return entity;
        else {
            return super.generateRequestEntity();
        }
    }

原来使用 NameValuePair 加入的 HTTP 请求的参数最终都会转化为 RequestEntity 提交到 HTTP 服务器, 接着在 PostMethod 的父类 EntityEnclosingMethod 中找到了如下的代码:
    /**
     * Returns the request's charset.  The charset is parsed from the request entity's 
     * content type, unless the content type header has been set manually. 
     
     @see RequestEntity#getContentType()
     
     @since 3.0
     */
    public String getRequestCharSet() {
        if (getRequestHeader("Content-Type"== null) {
            // check the content type from request entity
            // We can't call getRequestEntity() since it will probably call
            // this method.
            if (this.requestEntity != null) {
                return getContentCharSet(
                    new Header("Content-Type", requestEntity.getContentType()));
            else {
                return super.getRequestCharSet();
            }
        else {
            return super.getRequestCharSet();
        }
    }


解决方案

从上面两段代码可以看出是 HttpClient 是如何依据 "Content-Type" 获得请求的编码(字符集), 而这个编码又是如何应用到提交内容的编码过程中去的. 按照这个原来, 其实我们只需要重载 getRequestCharSet() 方法, 返回我们需要的编码(字符集)名称, 就可以解决 UTF-8 或者其它非默认编码提交 POST 请求时的乱码问题了.

测试

首先在 Tomcat 的 ROOT WebApp 下部署一个页面 test.jsp, 作为测试页面, 主要代码片段如下:
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page session="false" %>
<%
request.setCharacterEncoding("UTF-8");
String val = request.getParameter("TEXT");
System.out.println(">>>> The result is " + val);
%>


接着写一个测试类, 主要代码如下:
    public static void main(String[] argsthrows Exception, IOException {
        String url = "http://localhost:8080/test.jsp";
        PostMethod postMethod = new UTF8PostMethod(url);
        //填入各个表单域的值
        NameValuePair[] data = {
                new NameValuePair("TEXT""中文"),
        };
        //将表单的值放入postMethod中
        postMethod.setRequestBody(data);
        //执行postMethod
        HttpClient httpClient = new HttpClient();
        httpClient.executeMethod(postMethod);
    }
    
    //Inner class for UTF-8 support
    public static class UTF8PostMethod extends PostMethod{
        public UTF8PostMethod(String url){
            super(url);
        }
        @Override
        public String getRequestCharSet() {
            //return super.getRequestCharSet();
            return "UTF-8";
        }
    }


运行这个测试程序, 在 Tomcat 的后台输出中可以正确打印出 ">>>> The result is 中文" .

代码下载

本文所提到的所有代码, 以及测试程序(可直接导入 eclipse)提供打包下载: att:HttpClient POST 的 UTF-8 编码问题.httpClientUTF8.tar.bz2

END


posted @ 2006-10-31 23:00 thinkbase.net 阅读(7683) | 评论 (8)编辑 收藏
 
原文来自:  使用 Apache 反向代理实现负载均衡及热备


初步设想

  • 早些时候在 JavaEye 上看到过一些使用 lighttpd 或者 apache 作前端, 通过负载均衡, 实现高性能的 Web 系统的讨论, 于是留意了一下这方面的技术;
  • 考虑到对不同的 App Server 而言, 实现 Session 复制的配置各不相同(通常是需要配置集群), 因此从通用的角度, 觉得使用 session sticky 方式实现的负载均衡比较方便;
  • 由于没有看到有资料说 lighttpd 能够实现 session sticky, 所以决定先使用 Apache 试试.
参考资料:

环境准备

  • 下载安装 Apache, 测试时使用的是 XAMPP ( http://www.apachefriends.org/en/xampp.html ) 的 Linux 版本 (xampp-linux-1.5.4.tar.gz), 按照安装说明, 解压到 /opt/lampp 目录下就可以使用了;
    • 启动 Apache: sudo /opt/lampp/lampp startapache
    • 重新加载 Apache: sudo /opt/lampp/lampp reloadapache (在 httpd.conf 文件被修改后可以不重启, 而是直接 reload 就可以了)
    • 停止服务: sudo /opt/lampp/lampp stop
  • 准备两个运行同样程序的 Web 服务器, 这里使用的是 Tomcat 5.5, 并使用一个 jsp 文件作为测试文件(相关源代码参见文章最后的附件);
    • 这两个 Tomcat 服务器需要将 HTTP 服务配置在不同的端口上, 同时由于测试时运行在同一台机器上, 其它端口也需要避免冲突;
  • 下载安装 JMeter ( jakarta-jmeter-2.2), 用于压力测试, 验证负载均衡的效果;

测试 jsp 文件的说明

测试用的 jsp 文件 (test.jsp) 具有如下功能:
  • 显示当前运行的服务器的 IP 地址及端口号, 这样从返回的页面就能够知道是运行在哪一个 Web 服务器上的了;
  • 统计每个客户端(不同的 session)向同一台服务器发出请求的次数, 通过这个计数可以验证是否实现了 session sticky;
  • 通过 clear 请求参数(即 .../test.jsp?clear=1)清除请求次数的计数结果, 以便进行下一次测试;
  • 模拟 JSESSIONID +jvmRoute 的机制, 自行实现了一个 STICK_PORT_TOKEN 的 Cookie, 直接使用不同服务器的 HTTP 端口号作为 route;
    • 说明1: 考虑到方案的通用性, 这里没有直接使用 JSESSIONID +jvmRoute 的机制;
    • 说明2: 虽然作为一个例子, 相关代码是写死在 jsp 文件中的, 但是这个机制可以很方便的用一个 Filter 统一实现;

Apache 的配置

编辑 Apache 的 httpd.conf 文件(如果使用 xampp-linux 的话, 应该在 /opt/lampp/etc 目录下), 在文件的最后加上如下内容:
###############################################################################
# Reverse Proxy and Load Balance ##############################################
###############################################################################
# 1)简单的反向代理
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /1 http://localhost:8080/test
#ProxyPassReverse /1 http://localhost:8080/test
ProxyPass /2 http://localhost:18080/test
#ProxyPassReverse /2 http://localhost:18080/test
# 2)非 stickysession 的 balance
ProxyPass /3 balancer://non-sticky-cluster nofailover=On
<Proxy balancer://non-sticky-cluster>
BalancerMember http://localhost:8080/test
BalancerMember http://localhost:18080/test smax=10
</Proxy>
# 3)stickysession 的 balance
ProxyPass /4 balancer://sticky-cluster stickysession=STICK_PORT_TOKEN nofailover=On
<Proxy balancer://sticky-cluster>
BalancerMember http://localhost:8080/test route=8080
BalancerMember http://localhost:18080/test route=18080 loadfactor=2
</Proxy>
这个配置分为3个部分, 包括了 1)简单的反向代理, 2)非 session sticky 的 load balance, 以及 3)session sticky 的 load balance 三种方式的配置(这里假设两个 Tomcat 服务器的 HTTP 服务被配置在 8080 和 18080 端口), 其中第 2) 和 3) 的配置中 "nofailover=On" 适合于没有 session 复制的情况下, 这种情况下, 如果其中一台 HTTP 服务器出错, 那么原来分配在这个出错机器上的浏览器客户端不会被自动转移到另外的服务器上, 必须重新启动浏览器才能将请求分配到另外一台服务器上去.

使用 JMeter 测试结果

使用 JMeter 对 "3)session sticky 的 load balance" 的效果进行测试, 通过压力测试的方式, 检查两台 Tomcat 服务器被分配到的请求数量, 相关的测试脚本参见文章最后的附件.

注意如果重复测试, 在下一次测试开始之前请对每个 Tomcat 服务器执行 .../test.jsp?clear=1 的请求, 清除上一次的计数结果.

从下图的测试结果可见: 50个线程中有21个被分配在 8080 端口的服务器上, 29个则被分配到 18080 端口的服务器; 另外, 所有的 session 请求次数都是 20 次, 说明 session sticky 达到了预期的效果.

附件


后记

如何禁用 XAMPP 自带的内容, 使之成为一个单纯的转发服务器:
  • 1)注释掉 /opt/lampp/etc/httpd.conf 中 "Include etc/extra/httpd-xampp.conf" 这一行;
  • 2)删除或者移走 /opt/lampp/htdocs 目录下的内容(但是此目录需要保留).
posted @ 2006-10-10 13:12 thinkbase.net 阅读(7035) | 评论 (7)编辑 收藏
 

(原文来自: 2006-07-28 介绍一个 RSA 加密小工具 bmrsa)

因为要做一个不对称加密/解密相关的应用(其实是想用在软件的注册控制方面), 本来的想法是去找找有没有 RSA 加密/解密的源代码的例子, 结果在 sourceforge 找到来 bmrsa(RSA Cryptographic Text Processor), 可以从 http://sourceforge.net/projects/bmrsa 访问.

项目 README 里的描述:

 This program is an exercise in prime number generation,
RSA key generation, RSA encryption and conversion between
decimal, hexadecimal, base64 and text. Take note that RSA
is generally not used to encrypt entire messages because it
is too slow. It is normally used to encrypt keys used in
other encryption algorithms or other relatively small
values. For more detailed documentation, execute bmrsa
from a command line without passing any arguments. You will
probably want to pipe the output through more like this

试用了一下, 总结该软件有如下特点:
  • 开源, GPL 协议;
  • 跨平台, 而且完全使用 C++ 编写, 下载包里包含了 Windows 和 Linux 下的可执行文件;
  • 命令行程序, 运行时使用 stdin 和 stdout, 应该说被其它程序调用还算方便;
  • 只能处理文本, 不支持中文, 因此对于中文文本或者二进制文件可能需要先 base64 一下.

我用的是 2003-03-16 16:00 的 bmrsa10.zip 这个包, 可以从项目主页找到下载, 也可以从下面的链接下载:
下面简单说明产生 公钥/私钥 和 加密/解密 的整个过程:
  • 首先将下载后的 bmrsa10.zip 解压缩到一个目录, 进入这个目录;
  • 如果是 linux 环境下, 为了后面输入命令方便, 可以执行 export PATH=.:$PATH , 将当前目录加入 PATH;
  • 首先生成一个 768 位的密钥文件 _keys.768-bit.txt:
bmrsa -mkh -g 48 -f _keys.768-bit.txt
  • 接走我们建立另外两个文本文件 _private-key.768-bit.txt_public-key.768-bit.txt, 分别对应私钥和公钥. 这两个文件都是对 _keys.768-bit.txt 中内容的裁减, 基本上类似这个样子:
    • _private-key.768-bit.txt
public mod=7ECF58B12DAB4557B9B39589D26CA444BDF96...
private key=3C4B0676352943057A3B6B0D54A8B0E56265B...
private p=ED66018402DEED19082ED5EA500B778DAFA7A0...
private q=88BF09780DC8C15C429AE72AC6F91B0795C4E68...
  • 和:
    • _public-key.768-bit.txt
public mod=7ECF58B12DAB4557B9B39589D26CA444BDF96...
public key=BA562B6FEF44681C8937C54FCB985B205DAF0A...
  • 在实际使用中, 我们可以把公钥公布出来, 而用私钥加密传递的信息, 接收到信息的人可以使用公钥对信息进行解密(另外也可以反过来使用公钥加密, 接收方使用私钥解密);
    • 具体到这个例子中, 也就是说我们可以把 _public-key.768-bit.txt 公开给需要接收我们的信息的人, 而 _private-key.768-bit.txt 必需妥善保管, 因为一旦别人拿到这个私钥, 那就意味着他可以冒充你发送消息了;
  • 下面我们建立一个文本文件 _demo.txt 作为加密的原文:
NAME=thinkbase
URL =http://www.thinkbase.net
IP =218.81.120.31
  • 我们使用密钥 _private-key.768-bit.txt_demo.txt 进行加密, 加密后的文件是 _demo.enc.txt
bmrsa -mkh -mit -moh -pr -f _private-key.768-bit.txt <_demo.txt >_demo.enc.txt
  • 接收方拿到加密后的文件 _demo.enc.txt 后, 可以使用公钥 _public-key.768-bit.txt 对信息进行解密:
bmrsa -mkh -mih -mot -pu -f _public-key.768-bit.txt <_demo.enc.txt

具体的运行界面参见下图:




在实验过程中使用的一些文件也可以下载, 供参考:
posted @ 2006-07-29 00:18 thinkbase.net 阅读(2032) | 评论 (0)编辑 收藏
 

(原文来自: 2006-06-18 尝试了一下用 swig 编写 JNI 程序)

总是觉得编写 JNI (Java Native Interface) 程序是件复杂的事情, 于是开始漫无目的地搜索是否有简单一点的方法, 倒是有些商业软件提供这样的功能, 比如 http://www.jniwrapper.com 就提供了通过 Java 直接调用 DLL 的功能(可惜是商业软件, 哈哈).

搜索中无意到了 swig 的网站( http://www.swig.org ), 看到一个用 swig 产生 Java 模块的例子(原来知道 swig 是因为 python 的缘故), 于是就照着例子自己尝试了一下(比例子稍微复杂一点, 另外我是用 mingw 上的 gcc 进行编译的).

源代码包括 3 个文件, Example.c, Example.i, net/thinkbase/test/Test.java:

/** Example.c ****************************************************************/
#include <time.h>

/**A variable*/
double  PI =  3.1415927 ;

/**Return n!*/
int  fact ( int  n ) {
     if  ( n <=  1 )
         return  1 ;
     else
         return  n*fact ( n- 1 ) ;
}

/**mod function*/
int  mod ( int  x,  int  y ) {
     return  ( x%y ) ;
}

/**Get time as String*/
char  * getTime (){
     time_t ltime;
     time ( &ltime ) ;
     return  ctime ( &ltime ) ;
}

/**to upper case*/
char  * toUpperCase ( char  * result ){
     char  * p = result;
     while ( '\0' !=*p ){
         char  c = *p;
         if  ( ( c >  'a' ) && ( c <  'x' ) ){
         *p = c- 32 ;
         }
         p++;
     }
     return  result;
}


/** Example.i ****************************************************************/
%module Example
% {
     /* Put header files here or function declarations like below */
     extern  double  PI;
     extern  int  fact ( int  n ) ;
     extern  int  mod ( int  x,  int  y ) ;
     extern  char  * getTime () ;
     extern  char  * toUpperCase ( char  * str ) ;
% }

extern  double  PI;
extern  int  fact ( int  n ) ;
extern  int  mod ( int  x,  int  y ) ;
extern  char  * getTime () ;
extern  char  * toUpperCase ( char  * str ) ;


/** net/thinkbase/test/Test.java *********************************************/
package  net.thinkbase.test;

import  net.thinkbase.test.swig.Example;

public class  Test  {
     public static  void  main ( String argv []) {
         System.loadLibrary ( "Example" ) ;
         System.out.println (
             "    Example.getPI()      = "  + Example.getPI ()) ;
         System.out.println (
             "    Example.fact(6)      = "  + Example.fact ( 6 )) ;

         System.loadLibrary ( "Example" ) ;
         System.out.println (
             "    Example.mod(100, 30) = "  + Example.mod ( 100 30 )) ;
         System.out.println (
             "    Example.getTime()    = "  + Example.getTime ()) ;
         System.out.println (
             "    Example.toUpperCase(\"Hello, world!\") = "  +
             Example.toUpperCase ( "Hello, world!" )) ;
     }
}



试验步骤

建立必要的目录:
  • mkdir "net/thinkbase/test/swig"
  • mkdir ".out"
使用 swig 建立相关接口:
  • swig -java -package net.thinkbase.test.swig -outdir net/thinkbase/test/swig Example.i
编译 c 文件得到 dll:
  • gcc -c Example.c -o .out/Example.o -I%JAVA_HOME%/include -I%JAVA_HOME%/include/win32
  • gcc -c Example_wrap.c -o .out/Example_wrap.o -I%JAVA_HOME%/include -I%JAVA_HOME%/include/win32
  • gcc -shared .out/Example.o .out/Example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o .out/Example.dll
编译测试用的 Java 程序:
  • javac -sourcepath . net/thinkbase/test/Test.java -d .out
运行测试:
  • java -cp .out -Djava.library.path=.out net.thinkbase.test.Test
运行及测试结果:
源代码可以从这里下载:
posted @ 2006-07-29 00:16 thinkbase.net 阅读(4137) | 评论 (0)编辑 收藏
 
一个方便的SSL证书配置工具的介绍, 以及Tomcat上配置双向SSL(就是必须要客户端数字证书才能访问)的具体例子; 文章的主要内容完成于一年半以前, 现在发表基本上算是炒冷饭了, 不过最近加上了 Tomcat 5 和 Tomcat 4 上的实际配置例子, 所以整理了一下重新发出来.

配置适用于正式使用环境下的Tomcat Web服务器双向SSL认证

在 Tomcat 5.5 上的配置实例
在 Tomcat 4.1.31 上的配置实例
posted @ 2006-06-15 00:16 thinkbase.net 阅读(5454) | 评论 (14)编辑 收藏
 
(如果看不到图请点击标题进入)
类别: ubuntu
将 Java 开发环境迁移到 Ubuntu 基本完成了, 现在初步有了一个稳定的开发环境:
  • Eclipse, 这个不用说了;
  • Firefox, 这个也不用说了;
  • JFileSync, 很好用的文件同步工具, 我主要用来和 Windows 机器上的某些目录进行文件同步;
    http://jfilesync.sourceforge.net/
  • Meld, 文件比较工具, 大概和 Windows 下的 WinMerge 功能差不多, 不过这个东东是用 Python 写的, 也许在 Windows 下面也能运行;
    http://meld.sourceforge.net/
  • NetBeans, 和 Eclipse 齐名的开源 Java IDE, 偶尔用用;
  • SVN Client, 其实就是另外一个 Eclipse(只是 Platform, 不含 JDT), 安装了 subclipse 插件, 换了个图标;
  • vmplayer, 可以认为是著名的 VMWare 的简化版, 只能运行, 不能创建虚拟机; 这是唯一一个非开源的软件.

posted @ 2006-06-05 00:41 thinkbase.net 阅读(2543) | 评论 (1)编辑 收藏
 

类别:  java | javamail | mail

Aspirin(阿司匹林, https://aspirin.dev.java.net/ ), 按照网站上的介绍, "Aspirin is an embeddable send-only SMTP server.".

为什么叫阿司匹林呢? 因为它就是用来解决令人头痛的发送邮件问题的.

Aspirin 项目中使用了部分来自 Apache James (Apache 著名的邮件服务器项目, http://james.apache.org/ )的代码, 通过建立一个小型的 SMTP 服务器, 实现了一个不需要外部 SMTP 服务器的, 简单的 mail 发送工具;

不依赖于外部 SMTP 服务器, 意味着我们在通过 Java 程序发送邮件时, 可以不再需要安装和配置 postfix, sendmail 等 email 服务器, 使应用程序配置更简单, 更方便做到跨平台.

使用 Aspirin 发送邮件的代码很简单, 代码片断如下:

...
import  javax.mail.Message.RecipientType;
import  javax.mail.internet.InternetAddress;
import  javax.mail.internet.MimeMessage;

import  org.masukomi.aspirin.core.MailQue;
import  org.masukomi.aspirin.core.SimpleMimeMessageGenerator;

...

         MimeMessage msg = SimpleMimeMessageGenerator.getNewMimeMessage () ;
         msg.setSubject ( subject ) ;
         msg.setText ( mailText ) ;
         msg.setFrom ( new  InternetAddress ( fromAddress )) ;
         msg.setRecipient ( RecipientType.TO,  new  InternetAddress ( toAddress )) ;
         MailQue.addWatcher ( new  DefaultWatch ()) ;
         MailQue.queMail ( msg ) ;

...


另外需要注意的是,邮件其实是首先存放在一个队列里面,然后再发送的,所以如果第一次发送失败(比如 DNS 解析失败),程序还是会进行重试的,所以邮件可能会比实际发送时间晚几分钟(甚至更长)发出;具体重试几次,怎么样算失败,我还没有仔细去研究.
posted @ 2006-06-05 00:32 thinkbase.net 阅读(2545) | 评论 (3)编辑 收藏
 

(如果看不到图请点击标题进入)

类别标签: NTLM | subclipse | subversion | ubuntu

一开始使用 subclipse (Eclipse 的 Subversion 插件)不能通过 NTLM 认证访问 SVN 服务器, 始终报告如下图所示的错误(svn: HTTP authorization method 'NTLM' is not supported):

今天再看了一下, 在 Eclipse Perferences 中的 SVN 设置中发现不能选择使用 "JavaHL" 作为 SVN 接口(报告的错误是在 java.library.path 中找不到 libsvnjavahl-1.so), 心想不知道使用 JavaHL 是否可以解决 NTLM 认证的这个问题, 应该尝试一下, 上网查了查, 从 http://packages.ubuntulinux.org/dapper/devel/libsvn-javahl 找到了 libsvn-javahl 的下载 deb 包 libsvn-javahl_1.3.1-3ubuntu1_i386.deb, 下载完毕后使用
  sudo dpkg -i libsvn-javahl_1.3.1-3ubuntu1_i386.deb
进行安装, 却被告知依赖的 libsvn0 还没有被安装, 直接用 apt-get install libsvn0 安装后再次使用 dpkg -i 安装下载的 libsvn-javahl_1.3.1-3ubuntu1_i386.deb, 却被告知 libsvn0 版本不对:
xxx@xxxlinux:~/Desktop$ sudo dpkg -i libsvn-javahl_1.3.1-3ubuntu1_i386.deb
选中了曾被取消选择的软件包 libsvn-javahl。
(正在读取数据库 ... 系统当前总共安装有 60192 个文件和目录。)
正在解压缩 libsvn-javahl (从 libsvn-javahl_1.3.1-3ubuntu1_i386.deb) ...
dpkg:依赖关系问题使得 libsvn-javahl 的配置工作不能继续:
libsvn-javahl 依赖于 libsvn0 (= 1.3.1-3ubuntu1);然而:
系统里的 libsvn0 的版本是 1.2.0-1ubuntu1.
dpkg:处理 libsvn-javahl (--install)时出错:
依赖关系问题 - 仍未被配置
在处理时有错误发生:
libsvn-javahl
于是又从 http://packages.ubuntulinux.org/dapper/devel/libsvn-javahl 页面上找到 libsvn-javahl 的依赖库 libsvn0 (= 1.3.1-3ubuntu1) 的 deb 文件, 然后安装时又被告知依赖于其它的模块(未安装或者版本不对), 于是继续使用 apt-get install 安装这些模块, 或者继续在 http://packages.ubuntulinux.org/dapper/devel/ 下面各个依赖模块的页面上找到这些下一层的依赖模块的 deb 安装包, 如此循环往复, 花了不少时间, 总算把 JavaHL 安装好了.

然后进入 $JAVA_HOME/jre/lib/i386/client/ 目录, 执行:
  sudo ln -s /usr/lib/jni/libsvnjavahl-1.so libsvnjavahl-1.so
然后再启动 Eclipse, 进入 SVN 的设置页面, 果然现在可以选择 "JavaHL (JNI)" 方式了:
连接到 SVN 服务器测试, 果然现在能够正确弹出输入用户名和密码的对话框了:


终于解决了这个问题, 现在可以将大部分工作都转移到 Ubuntu 上面来啦 :)
posted @ 2006-05-13 15:01 thinkbase.net 阅读(1640) | 评论 (1)编辑 收藏
 
(如果看不到图,或者格式混乱,请点击标题进入)
类别标签: font | ubuntu

首先说一下, 这篇文章主要是针对 Java 开发者的, 如果是做 Windows 开发, 那么基本上没有办法把工作环境移植到 Ubuntu 上的(当然也不能说死, 也许以后可以使用 WINE 试试, 呵呵).

1.系统默认编码


我们知道在中文 Windows 下一般来说系统的默认编码是 GBK, 从 Java 开发的角度来说, 就是在进行诸如 Java 源代码编译, 文件读写等操作时, 默认使用的编码是 GBK; 而我们参照一般的 Ubuntu 中文安装文档, 可能会建议将默认的语言设置为 zh_CN.UTF-8, 这样会带来一些问题, 比如我在 Windows 使用 Eclipse 时的编辑器的默认编码是 GBK, 但是在 Ubuntu 下面就是 UTF-8, 同样是使用 Eclipse, 在 Windows 下的中文文档到了 Ubuntu 中会产生乱码, 必须手工逐个文档设置属性中的编码为 GBK 才可以正常; 一些测试代码也是以默认编码读取文件的, 这些代码读取出来的文件内容也会包含乱码.

所以, 最好是将系统的默认编码设置为 GBK, 这样和 Windows 下面的开发环境最接近. 设置的方法应该不止一种, 我采用的是编辑 /etc/environment, 改成这个样子:
  LANGUAGE="zh_CN:zh:en_US:en"
GST_ID3_TAG_ENCODING=GBK
LANG=zh_CN.GBK
LC_CTYLE=zh_CN.GBK

2.中文字体


Ubuntu 5.10 默认安装后的中文字体不是点阵字体, 因此在小字显示的时候模模糊糊比较难看, 而且, 在浏览网页时, 无法显示中文粗体. 关于字体美化的文章网上太多了, 有些是采用 Windows 字体来进行的; 最近 "文泉驿"( http://wqy.sourceforge.net/ ) 的开源点阵字体受到很多好评, 而且点阵字体正好合适用于小字的显示, 我用的是最新的 0.7 beta 版(0.6.9 pcf update 3), 按照 文泉驿点阵宋体安装指南 上的步骤安装, 修改了 xorg.conf, 也执行了 fc-cache -f -v , 安装过程还算顺利, 就是有一点需要注意, 那就是字体一定要放在 /usr/share/fonts/ 的子目录下面, 不然执行 fc-cache 不会起作用的. 安装完毕后需要配置一下系统的默认字体, Firefox 也需要配置一下字体, 效果还是不错的(见下面截图).


3.Java(Swing)程序的字体


这个我主要参考了 最简单的对JDK1.5的中文乱码处理方法 , 按照其中更简单的那个方法, 在 $JAVA_HOME/jre/lib/fonts/ 目录下创建 fallback 目录, 并把一个中文的 TTF 字体链接或者安装到 fallback 目录下就可以了.

和参考文章说的稍有差别, 我是下载了文泉驿 0.6.9 ttf update 3 的 TTF 字体, 直接解压后复制到 fallback 目录下, 接着执行 mkfontdir 和 mkfontscale, 果然问题得以解决; 现在 NetBeans 或者 JMeter 的 "打开" 文件对话框中的按钮和标签就正确显示出中文了.

安装在 Ubuntu 上面的 NetBeans 5.0:
存在中文问题的"打开项目"对话框:
经过处理后可以正确显示中文的对话框:

参考:
posted @ 2006-05-13 14:53 thinkbase.net 阅读(2631) | 评论 (2)编辑 收藏
 
.
Ubuntu,源于非洲祖鲁人和科萨人的语言,发作“oo-boon-too”的音。学会这个发音还是
有价值的,你不是第一个人问这个问题了。
大多数的美国人读"ubuntu"时,将"u"作为元音发音,类似单词 "who" 或者 "boo",重
音在第二个音节即u'buntu,oo-boon-too。如果你喜欢添加一些非洲撒哈拉的味道,你可以在
第一个"u",后面带些嗡嗡声:oom-boon-too。
.
(摘自 Ubuntu中文 的 FAQ: http://www.ubuntu.org.cn/support/documentation/faq/faqsection_view?section=Ubuntu )

关于 Ubuntu 的详细信息, 可以去看看这两个网站:
Qemu 是一个开源的 CPU 仿真器, 一般介绍都认为它比 Bochs 快(当然比不上 VMWare 啦), 试用一段时间后, 觉得速度还是慢, 不过倒是比较方便, Qemu 的所有配置都是在命令行上输入的, 因此也就没有什么配置文件了, 也不需要安装过程, 解压缩后就可以使用了.

关于 Qemu, 可以看看如下链接:
言归正传, 说说在 Qemu 上安装 Ubuntu 5.10 的经历, 原先安装了两次都没有成功, 报告磁盘是只读的什么, 后来想想安装时候都是指定在一个 2GB 的 Qemu 模拟硬盘上的, 估计是磁盘空间还是不够, 所以这次用了一个 4GB 的模拟硬盘, 大概花了一个下午安装才完成, 果然需要大于 2G 的空间. 闲话少说, 给几张图片 :)




posted @ 2006-05-13 14:38 thinkbase.net 阅读(2084) | 评论 (0)编辑 收藏