by agate - Published: 2008-11-07 [3:02 下午] - Category: 开发环境
奇怪... Ubuntu8.04 下我都没碰到这类问题, 倒是升级到 Ubuntu8.10 的时候 java 就出现乱码了~ 不说为什么, 因为我也不知道. 这里记录一下简单的解决方案:
1.
在 ${JRE_HOME}/lib/fonts/ 下建立个目录 fallback
比如我这儿就是
$cd /usr/lib/jvm/java-6-sun/jre/lib/fonts/
$mkdir fallback
2.
在 fallback 里弄个中文字体(拷贝或链接都可以)
比如我这就是
$ln -s /usr/share/fonts/truetype/arphic/uming.ttf /usr/lib/jvm/java-6-sun/jre/lib/fonts/fallback/
3.
进入 ${JRE_HOME}/lib/fonts/fallback/ 执行 mkfontscale, 再把 jre/lib/fonts/fallback/fonts.scale 的内容加到 ${JRE_HOME}/lib/fonts/fonts.dir
我这儿就是
$cd /usr/lib/jvm/java-6-sun/jre/lib/fonts/fallback/
$mkfontscale
$cd ..
$cat fallback/fonts.scale >> fonts.dir
DONE!
by agate - Published: 2008-10-08 [7:45 下午] - Category: 程序编码
今天帮朋友做课程设计, 要用 RMI 远端操控数据库. 于是乎便看了一下 RMI 应用的用法规则. 发现十分简单. 在这里写下一个 HelloWorld 例子, 以便未来参考.
引言: 白痴的我明明知道 RMI 底层是 Socket 实现的, 传递的对象固然要序列化. 但是今天我竟然傻逼地把 Connection 传导客户端操作... 小朋友不要学我变成白痴哦!
一. 结构(我叫他规则):
一个接口, 一个实现类. 一个服务器端, 一个客户端. 总共三类一接口.
二. 代码:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Product extends Remote {
public String getName() throws RemoteException;
}
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ProductImpl extends UnicastRemoteObject implements Product {
private String name;
public ProductImpl(String name) throws RemoteException {
this.name = name;
}
public String getName() throws RemoteException {
System.out.println("方法 getName 被调用!");
return name;
}
}
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) {
try {
Registry r = LocateRegistry.createRegistry(1099);
Product p = new ProductImpl("乐事薯片"); //我的最爱
r.bind("p", p);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) {
try {
String host = ""; //这里替换成你的服务器地址, 空的就代表本机
Registry r = LocateRegistry.getRegistry(host);
Product p = (Product)r.lookup("p");
System.out.println("此产品的名字为:" + p.getName());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
三. 执行:
1. 放置
将上述 4 个类放置在统一文件夹下.
2. 编译
javac -cp . *.java
3. 启动服务器端
启动一个终端, 进入该文件夹, 执行:
java -cp . Server
4. 启动客户端
启动一个终端, 进入该文件夹, 执行:
java -cp . Client
四. 注意
编码问题一直存在, java 编译也不例外! 在 Linux 这些 UTF-8 的世界里请大家把上面四个文件都保存成 UTF-8 格式. Windows 的世界里, 保存成 ANSI 即可!
by agate - Published: 2008-10-08 [5:30 下午] - Category: 程序编码
不多说, 上代码:
jdbc:mysql://host:port/db?user=root&password=root&useUnicode=true&characterEncoding=UTF8
这段代码可以用在 "DriverManager.getConnection()" 中, 当然, 在 hibernate 的 xml 配置文件中也是可以使用的. 但是要注意的是在 xml 中记得把 '&' 替换成 '&'
by agate - Published: 2008-05-01 [9:42 下午] - Category: 程序编码
不知道各位使用 Struts1.x 的朋友们晓得不晓得,Struts1.x 的 org.apache.struts.action.Action 中有两个 execute 方法,在我们使用 eclipse 的自动完成 override 功能的时候要是不小心给弄错了你就等着迎接一个不报错的空白页面吧!让我们看看代码:
// one execute
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
//code...
}
// another execute
public ActionForward execute(ActionMapping mapping, ActionForm form,
ServletRequest request, ServletResponse response) {
//code...
}
好,公布结果!只有 override 上面这个 execute 才能起作用。如果你 override 的是下面这个 execute 的话,很不幸,您调用这个 action 的时候响应给你的是一个空白的页面,你也别想得到任何 exception 的提示!
在 eclipse 中我导入了 struts1.x 的 src 路径,并通过 Open Call Hierarchy 查找调用上面第二个 execute 的类时发现竟然没有调用者!换句话说当我们实现第二个 execute 的时候(没有实现第一个 execute ),是根本没用的!程序根本不会调用到我们 override 的那个 execute 只会傻傻地调用第一个 execute 的默认实现,返回一个 null
那第二个 execute 有什么用呢?我觉得他不是用来给我们重写的,看看它的内容:
public ActionForward execute(ActionMapping mapping, ActionForm form,
ServletRequest request, ServletResponse response)
throws Exception {
try {
return execute(mapping, form,
(HttpServletRequest) request,
(HttpServletResponse) response);
} catch (ClassCastException e) {
return null;
}
}
在我看来,其实它是为了当一个请求是一个非 http 请求的时候,作为一个前端转换器,重新包装请求和响应,然后才交给真正的,也就是我们的第一个 execute 方法来实现。这个从 src 的注释中我们也可以比较清晰的了解:
Process the specified non-HTTP request, and create the corresponding non-HTTP response (or forward to another web component that will create it), with provision for handling exceptions thrown by the business logic. Return an ActionForward instance describing where and how control should be forwarded, or null if the response has already been completed.
所以……当你重写这个 action 的 execute 方法时,注意咯!是重写那个参数是 http-request/response 的 execute哦!!!
这里严重鄙视一下 struts1.x 的编码态度!
by agate - Published: 2008-04-07 [10:03 下午] - Category: 感想, 程序编码
其实也没有什么,内行的人觉得这个是小Case吧。呵呵,这里我不是想说具体的方法,主要是一个感想:
<map
name="propertyName"
table="table_name"
lazy="true|false"
inverse="true|false"
cascade="all|none|save-update|delete|all-delete-orphan"
sort="unsorted|natural|comparatorClass"
order-by="column_name asc|desc"
... 其他属性
>
<key ... />
<map-key ... />
<element ... />
</map>
很多人首先想到的是sort,而且sort已经给出了排序的实现,我们只管天上属性方可。可是我们大多程序员是从学 SQL 转到 Hibernate 这个 ORM 的持久层框架上来的,旧有的观念还是喜欢“order by xxxx desc”。不是说自己怀旧,我发现很多朋友都有这个习惯。所以,一般来说还是建议使用 order-by="column_name asc|desc" 这个属性进行对应表字段的排序配置。在一些特殊时候,我也不建议使用 sort 所自带的属性,建议根据需要来具体实现 java.util.Comparator 这个接口来具体实现自定义排序。
by agate - Published: 2008-04-06 [4:38 下午] - Category: 程序编码
今天郁闷了2个小时,不停地试验,就是没成功……(试验什么呢?)就是这个,用HQL来查出一个List,条件是某个字段为空。
两个领域类:
public class User {
private String username;
private Group group;
// ------------- setter
// ------------- getter
}
public class Group {
private String groupName;
private List<user> users;
// ------------- setter
// ------------- getter
}
让你查数据库中所有group为空的(即加入组的)所有用户。
Read more...
by agate - Published: 2008-04-03 [11:01 上午] - Category: 程序编码
原来还是自己的问题……首先自我检讨一下,常常总是自以为是用自己的思维方式想问题。呵呵,这个真的是打开眼界啊!原来 OGNL 这个玩意有如此大的魔力,难怪 Struts2 使用他哈!厉害……
说道上回写的那个中文问题,本来是以为是转换成什么 Unicode 编码方式了,其实不然,只不过 Struts2 的 OGNL 有点低智商,只认 '' 符号里的西欧字符为字符串,其他的字符出现就会抛个 FormatException 异常……比较罕见,但是这个也使我研究了一小下 OGNL 的“真才实学”。
发现 Struts2 中
<s:if test="#user.sex == 'male' "> ... </s:if>
是可以的
<s:if test="#user.sex == '男' "> ... </s:if>
是不行的,必须改成
<s:if test="#user.sex == '男'.toString() "> ... </s:if>
发现牛逼在何处了吧…… OGNL 竟然除了属性的调用,还可以调用方法。像上面这样使用的话,中文的 OGNL 比较就基本没有问题了。
by agate - Published: 2008-04-02 [9:48 下午] - Category: 历程, 程序编码
最近一直使用struts2进行项目开发,因为之前就是用的webwork进行学习的,可是一直没有使用到页面逻辑的 if 标签。谁知今天用来比较一个String是否等于一个String的时候出现了问题。
这里先对自己不扎实的OGNL知识表示惭愧,我现学现卖地使用了包括EL格式的${},以及参见的${}和#{}以及直接输入属性的方式都无法识别,可是在我使用输出型标签<s:property/>时竟是完好显示的……
百思不得其解。忽然想到Struts2的Ajax是使用Dojo的,这个框架对于除西欧字符以外的所有字符都是使用Unicode的方式进行编码的(所有的字符都要编程类似 'ऩ' 的格式)。莫非……我马上在action端把属性的值进行了url转换,并写了一个测试用的jsp模板页面,里头也对应的把对比的字符串使用url格式的字符串代替了,结果真的通过了……我的妈呀!不会这么弱吧,这个框架的标签功能岂能这样啊!
没法,只好正规点使用其他标签来替代这种页面标签逻辑的方法。打算努力学几天OGNL和“白痴”的Struts2的标签,知道了结果陆续文章跟进……
补充后续探讨:
《续:Struts2的OGNL的中文识别》
by agate - Published: 2008-04-02 [5:45 下午] - Category: 程序编码
虽然如今的ws标准都已经很智能了,大多的数据类型都可以识别。但是在GlassFish中,发布的ws方法中参数和返回值不可以为hashmap的,但是如果非要要使用键值对该如何使用呢?
最简单的方法就是再次包装:
public class MapBean {
private HashMap<String,String> hm;
public HashMap<String, String> getHm() {
return hm;
}
public void setHm(HashMap<String, String> hm) {
this.hm = hm;
}
}
@WebService()
public class HelloWorld {
public HelloWorld() {
}
@WebMethod
public MapBean getMapBean(HashMap<String,String> hm) {
MapBean mb = new MapBean();
hm.put("server", "serverHashMap");
mb.setHm(hm);
System.out.println("Hello HashMap...");
return mb;
}
}
这样,加一层包装之后,就可以间接地使用Map了。
by agate - Published: 2008-04-01 [7:44 下午] - Category: 历程, 程序编码
IOC(DI)即依赖注入,参见的就是Spring的IOC容器,实现就是实现符合java bean的规范的带有无参构造函数的带有对应set和get方法的一个java类(pojo)。前面都是废话,我们都知道注入一般就是使用set方法,对需要的成员变量进行动态的赋值指向。一般get没有什么用,所以我们用spring管理的时候一般只需写入需要注入对象的set方法即可。
但是今天开发展现层的时候……我用struts的表单自动注入的特性写了一个CRUD模块,当然我还是使用原先的逻辑:只写set方法。结果值没有正确被赋值(有的时候只有部分值被获取)。而且发现如果是简单的数值类型的参数在只设置set方法的情况下是可以被赋值的,但是要是参数是一个ValueObject这样的一个实体对象:
public class User {
private String userName;
private String userPwd;
// --------other private property
// --------setter
// --------getter
}
那么,如果我们在action中只对user属性写了set方法
public class UserAction {
private User user;
// --------setter
public String execute() {
// --------code...
}
}
那么经过我不下10次的不同试验,保证是无法正确赋值的!因为……还缺了个get方法。也不知道具体原因是什么(猜想在struts2的IOC中,对于复杂对象的注入可能同时用到了set和get方法),但是经验告诉的是set和get方法最好都写!