sulong 于 2009-11-14
没有评论 »
问题
JAXB是我用过的java处理XML的方法中做方便的一个,在jaxb中如何使用类的集成关系有一个小小的需要注意的地方。看下面的两端XML。
XML 示例1:
XML示例2:
这两段XML的唯一差别就在c元素与d元素。为了生成这两个XML,有几种方案。
方案一
不利用类的继承来重用代码,写两套Java代码, 如:
@XmlRootElement(name = a)
public class A {
B b;
C c:
}
@XmlRootElement(name = a)
public class A2 {
B b;
D d:
}
public class B {}
public class D {}
这一方案不是我们想要的,虽然可以解决问题,但是不能重用两个XML中共有的结构。
方案二
利用一个父类表示两个XML之间的共同的结构,用两个子类扩展这个父类,分别添加 C 和 D 元素。
代码如下:
@XmlRootElement(name = "a")
public class A {
B b;
}
public class B {}
public class C {}
public class D {}
public class E extends A {
C c;
}
public class F extends A {
D d;
}
这一方案看似很直观,但是实践中却发现 E 和 F 却都只能生成 父类的 部分,如下的XML:
即使把 @XmlRootElement(name = “a”) 移到 E 和 F类上也行不通。
方案三
用一个类代表共同的结构,用一个父类代表C和D元素,在用两个类代表具体化的C和D类,如:
@XmlRootEelemnt(name = "a")
public class A {
B b;
@XmlElements({
@XmlElement(name = "c", type=C.class),
@XmlElement(name = "d", type=D.class)
})
E e;
}
public class B {}
public class E {}
public class C extends E {}
public class D extends E {}
这样做才最终达到目的。关键点就是@XmlElements的使用。
sulong 于 2009-11-12
9 篇评论 »
在打印单据的时候,有两个汉字“玥”和“芃”,始终显示为“?”,这一问题困扰了业务人员一段时间了。以前没有空,就没有投入精力去查原因,上次得了空,终于把这个问题解决掉了。
这个乱码的汉字从哪里来的呢?首先是业务人员通过一个遗留的PHP应用,输入到一个mysql 4数据库中,然后我们的java程序从这个mysql 4中读取,再写入到新的mysql5的数据库中,最后通过java程序生成html在用户的浏览器里显示,结果就看到了这两个汉字乱码。那么这个问题如何解决呢?
只有两个汉字乱码,而不是所有的汉字都乱码,所以我们的程序一定使用了一种包含汉字较少的字符集,而这个出错的汉字恰好不在此字符集中,否则,就应当是大部分汉字乱码,而不仅仅是这两个了。很自然的就让人想到了 gb2312, gbk, gb18030, utf8等字符集之间的关系。其中gb2312中只有六千多个汉字,其它几个字符集支持的汉字数相差不多,我们程序一定是在该使用gbk, gb18030或utf8的地方使用了含有汉字较少的gb2312。
经查阅相关文档,果然发现那两个汉字都不在gb2312里,而在gbk, utf8字符集里。我们的mysql5使用的utf8字符集,生成的html也是utf8编码,如果mysql5中的汉字是正确的话,那么就应该能正常显示,因此,数据进入mysql5的时候就应该出错了。java程序在连接mysql5的时候,在jdbc连接中设置了utf8,所以如果从mysql4数据库中读取出来的是正确的,就不应该写入出问题,因此数据在mysql4中可能就错了,也可能是从mysql4中读取的时候出错了。php的兄弟们说mysql的数据库是gb2312字符集的,mysql的配置文件里也是这么配置的。如果果真如此,那么这个两个汉字在mysql4的数据库中就应该不正常了,所有的程序读出之后都应该是乱码,可是php的录入程序那边确实是能正常显示的。我断定这个数据库里放的实际上是gbk字符集的汉字。选用和mysql4相对应的mysql j connector 3.14,并在jdbc连接url里设置了characterEncoding=gbk,读出来的仍旧不正确!查阅了mysql j connector的文档,原来3 版本的mysql connector根本就不支持characterEncoding这个选项。看来只能修改mysql的配置文件了。修改之后,果然这两个汉字可以正常显示了。
如果计算机是中国人发明的,那么计算机也许一开始就得支持汉字,就再也没有乱码的问题。如果世界上只有一种汉字的编码方案,也不会有乱码的问题,可惜汉字偏偏有很多中编码方案。所以在我们的程序中,一定得搞清楚,我们的汉字数据来自于哪里,使用的哪种编码,每个环节都得配置得当,否则就会有乱码问题。
对于一般的web应用来说,需要关心编码的地方有:
1,数据库以什么编码存储数据
2,程序使用什么字符集连接数据库
3,程序内部运行时使用什么字符集
4,程序源码使用什么字符集
5,生成的html文件是什么字符集
6,程序告知浏览器的字符集
如果以上这些地方的字符集有配置不正确的地方,往往就会乱码。
如果可以的话,最好在所有的地方都使用一种编码,比如对于java应用来说,在所有的地方都使用utf8编码,就可以解决问题。需要注意的是,在windows环境下,默认的文件编码是gb18030的,而不是utf8。
另外,极端鄙视故意使用生僻字火星文的脑残族!!
sulong 于 2009-09-27
22 篇评论 »
我为公司内部交流而写的PPT,谈论PHP和JAVA相关的话题。在这里查看:
漫谈PHP和Java
sulong 于 2009-08-07
没有评论 »
原本希望groovy能以php那种方式工作,但是现在看来不太可能。Groovy发行包里自带的TemplateServlet太弱,GroovyServlet也有致命的缺陷。
GroovyServlet使用GroovyScriptEngine(后面简称GSE)解析groovy文件,解析过程中GSE会智能的自动的到类路径中寻找被引用到的groovy类文件。如果被用作groovyServlet的文件被更新了,GSE会重新解析它,不需要重启服务器,就可以看到效果。可惜的是,如果被引用到的类路径中的其它的文件被更新了,GSE还在使用原来的文件,必须重启服务器才能看到效果,这是在是太令人失望了。据说groovy 1.7 里GSE会这方面增强,很期待呀。TemplateServlet干脆就连GSE也没有用,所以自动引用其他的groovy文件也不可能了。无论是GroovyServlet还是TemplateServlet都不能够像php那样通过include别的php文件来获得别的文件里定义的类,方法和闭包。
看开,在目前,如果不用grails,是没有什么好办法直接用groovy文件写网络程序的,只好把它编译成class文件,就像java生成的class一样来使用。很可气的是,我试用了几个IDE,eclipse, netbeans和idea,其中只有idea支持得还可以,但都是不算很好。看来groovy还有一段路要走。