梧桐轩工作室
自我介绍
切换风格
订阅我的Blog
博客日历
文章归档...
最新发表...
博客统计...
网站链接...
资源
===========================================================
list.toArray出现java.lang.ClassCastException
===========================================================
转载自http://www.roboticfan.com/blog/user_2005/104/archives/2007/20071127213533.shtml

List list = new ArrayList();
list.add(new Person());
list.add(new Person());
list.add(new Person());
Person[] person = (Person[]) list.toArray();

运行程序会抛出异常:java.lang.ClassCastException

但运行如下代码:

List list = new ArrayList();
list.add(new Person());
list.add(new Person());
list.add(new Person());
Person[] person = (Person[]) list.toArray(new Person[0]);

程序正确执行,

原因,先看ArrayList的两个toArray()方法的源代码:

public Object[] toArray() {
Object[] result = new Object[size];
System.arraycopy(elementData, 0, result, 0, size);
return result;
}



public Object[] toArray(Object a[]) {
if (a.length < size)
a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}

可以看出,不带参数的toArray方法,是构造的一个Object数组,然后进行数据拷贝,此时进行转型就会产生ClassCastException而带参数的toArray方法,则是根据参数数组的类型,构造了一个对应类型的,长度跟ArrayList的size一致的空数组,虽然方法本身还是以Object数组的形式返回结果,不过由于构造数组使用的ComponentType跟需要转型的ComponentType一致,就不会产生转型异常。

那么,对于不带参数的toArray方法,它有什么特殊意义呢?还是用代码说话:
ArrayList list = new ArrayList();
list.add(new Person());
list.add(new Person());
list.add(new Person());
//这里不需要转型,也不能使用转型
Object[] ss = list.toArray();
//这里可以进行转型,取出原ArrayList里面存放的对象
for (int i = 0; i < ss.length; i++)
{Person person= (Person) ss[i];
System.out.println(person);
}

就是说,如果用toArray,需要自己“手工”“逐个”进行类型转换。


RobinOuyang 发表于:2011.03.08 10:35 ::分类: ( Java Programming ) ::阅读:(164次) :: 评论 (0) :: 引用 (0)
===========================================================
Portlet中生成或下载PDF文件
===========================================================

在portlet中动态生成PDF或者其他文件,不能正常下载,而会显示成页面,这个现象的主要原因是因为访问生成PDF文件的Action是通过<netui:anchor action/>,此时Portal容器的ContentType强制是text/html,不管你在Action中对response设置了contentType。因此需要访问不是放在Portal容器中的Action,可以直接通过<a href/>标签访问Action即可。
RobinOuyang 发表于:2011.02.25 15:55 ::分类: ( Java Programming ) ::阅读:(161次) :: 评论 (0) :: 引用 (0)
===========================================================
WebLogic通过JS异步请求直接读取XML文件的问题
===========================================================
在weblogic中通过JS异步请求直接读取XML文件,发现在IE中无法通过request.responseXML获取,因为它不认为是XML,主要是因为没有设置contentType="text/xml",因此需要在web.xml中添加MIME映射,如
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
 查看全文
RobinOuyang 发表于:2011.02.23 13:14 ::分类: ( Web技术 ) ::阅读:(218次) :: 评论 (0) :: 引用 (0)
===========================================================
HTML5之表单详解
===========================================================

阅读本文前建议在Opera最新版中打开样例演示页查看样例演示

一、表单结构更自由

XHTML中需要放在form之中的诸如inpu/button/select/textarea等标签元素,在HTML5中完全可以放在页面任何位置,然后通过新增的form属性指向元素所属表单的ID值,即可关联起来。

比如:





<FORM id=iform>
<INPUT>
...
</FORM>
<INPUT
value=我在id为iform的表单外 form="foo">

二、多样的输入类型(大部分新类型目前并不为所有标准浏览器支持,请参见样例演示中的提示)

email输入类型





<INPUT type=email name=email>

此类型要求输入格式正确的email地址,否则浏览器是不允许提交的,并会有一个错误信息提示.此类型必须指定name值,否则无效果.

url输入类型





<INPUT type=url>

上面代码展示的文本域要求输入格式正确的URL地址,Opera中会自动在开始处添加http://.

日期时间相关输入类型(这些个很牛X的)





<INPUT type=date>
<INPUT type=time>
<INPUT
type=month>
<INPUT type=week>

这一系列是很酷的一个类型,完全解决了烦琐的JS日历控件问题.但目前MS只有Opera/Chrome新版本支持,且展示效果也不一样.

number输入类型(这些个很牛X的)





<INPUT type=number>

这个不用多解释了,要求输入一个数字字符,若未输入则会抛出一个错误.

range输入类型





<INPUT type=range>

此类型将显示一个可拖动的滑块条,并可通过设定max/min/step值限定拖动范围.拖动时会反馈给value一个值.

search输入类型





<INPUT type=search>

此类型表示输入的将是一个搜索关键字,通过results=s可显示一个搜索小图标.

tel输入类型





<INPUT type=tel>

此类型要求输入一个电话号码,但实际上它并没有特殊的验证,与text类型没什么区别.

color输入类型





<INPUT type=color>

此类型表单,可让用户通过颜色选择器选择一个颜色值,并反馈到value中.

三、新增的表单属性

placeholder属性





<INPUT id=placeholder
placeholder="点击我会以清除">

这是一个很实用的属性,免去了用JS去实现点击清除表单初始值.浏览器支持也还不错,MS除了Firefox,其他标准浏览器都能很好的支持.

require/pattern属性





<INPUT id=placeholder name=require required>
<INPUT
id=placeholder name=require1 required="required">
<INPUT name=require2
pattern="^[1-9]d{5}$">

表单验证属性,require类型时,若输入值为空,则拒绝提交,并会有一个提示。上面两种写法都对,这个很有用。并且可以用于textarea以及hidden/image/submit类型.pattern类型为正则验证,可以完成各种复杂的验证。这两种类型必须指定name值,否则无效果。

autofocus属性





<INPUT autofocus="true">

默认聚焦属性,可在页面加载时聚焦到一个表单控件,类似于JS的focus().

list属性





<INPUT id=list list="ilist">
<DATALIST
id=ilist>
<OPTION value="a" label="a">
<OPTION value="b"
label="b">
<OPTION value="c"
label="c">
</DATALIST>

该属性需要与datalist属性共用,datalist是对选择框的记忆,而list属性可以为选择框自定义记忆的内容。

max/min/step属性





<INPUT type=range step="20" min="1"
max="100">

限制值的输入范围,以及值的输入渐进程度,比如可在number设定输入最大值最小值,或者在range中设定拖动阶梯。

autocomplete属性





<INPUT id=autocomplete
autocomplete="on">

此属性是为表单提供自动完成功能。如果该属性为打开状态可很好地自动完成。一般来说,此属性必须启动浏览器的自动完成功能。

路漫漫其修远兮,吾将上下而求索。前端之路,学无止尽。痛并快乐着。

转载自http://www.chinaz.com/Design/Rules/02211600112011.html


RobinOuyang 发表于:2011.02.22 13:47 ::分类: ( Web技术 ) ::阅读:(140次) :: 评论 (0) :: 引用 (0)
===========================================================
Windows 7 中删除文件类型关联
===========================================================

在控制面板中只能给某文件类型添加默认程序关联,但是如果加错了只能修改,不能删除。

据说只能采用修改注册表的方式修改,不过据传还有另外一个办法,就是用管理与打开CMD,然后在命令行中执行如下命令:

assoc .[后缀名]=

未测试,具体效果待查。


RobinOuyang 发表于:2011.01.10 15:36 ::分类: ( Others ) ::阅读:(321次) :: 评论 (0) :: 引用 (0)
===========================================================
IE下显示带Flash页面的问题
===========================================================

昨日,发现一个问题,就是在ExtJS创建页面中显示统计图表时,页面的Title在IE下会改变。

多方打听之后才发现是因为如果一个页面(页面的URL带#号)中显示Flash时,会修改页面的Title。果然,修改之后,打开页面如果不带#就OK。

Bingle。



RobinOuyang 发表于:2011.01.05 13:12 ::分类: ( Web技术 ) ::阅读:(177次) :: 评论 (0) :: 引用 (0)
===========================================================
WebLogic 10.3部署EAR提示DDBeanRoot may not be null.
===========================================================
在WebLogic Server 10.3上部署EAR,提示DDBeanRoot may not be null. 之后Active Changes之后提示异常,执行操作失败。提示weblogic-application.xml中的wls-commonslogging-bridge的reference为空。查找之后发现Domain的Config中的确没有wls-commonslogging-bridge的Library。因此将weblogic-application.xml中的相应部分注释,重新部署,仍然提示DDBeanRoot may not be null.但是可以Active Changes。
RobinOuyang 发表于:2009.12.31 10:02 ::分类: ( Java Programming ) ::阅读:(411次) :: 评论 (0) :: 引用 (0)
===========================================================
WebLogic Beehive应用部署到Tomcat上
===========================================================

在运行目录中添加Weblogic/server/lib下面的api.jar,以及所有有关BeehiveJar包,在weblogicbeehive目录下

有关配置使用JdbcControl的配置可以参考如下:

目的:实现在一个JSP中通过数据库链接池访问DB

步骤:

1)在server.xml中加入如下代码:

[code] <GlobalNamingResources>

<Resource driverClassName="com.sybase.jdbc3.jdbc.SybDriver"

maxActive="5" maxIdle="2" maxWait="5000" name="jdbc/sybase"

password="password" type="javax.sql.DataSource"

url="jdbc:sybase:Tds:192.168.0.1:4100/voo" username="admin"

validationQuery="select ititle from home" />

</GlobalNamingResources>[/code]

2)在该web application中的web.xml里加入:

[code] <resource-ref>

<description>sybase db</description>

<res-ref-name>jdbc/sybase</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>[/code]

3)在该web application中META-INF目录下新增context.xml,内容如下: [code]<?xml version="1.0" encoding="UTF-8"?>

<Context>

<resourcelink name="jdbc/sybase" global="jdbc/sybase"

type="javax.sql.datasourcer" />

</Context>[/code]

4)新建一JSP页面,JSP代码部分如下:

[code]<%

Context initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

DataSource ds = (DataSource)envCtx.lookup("jdbc/sybase");

Connection con=ds.getConnection();

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery("select ititle from home");

while(rs.next())

{

out.print("rs.get(1)--->"+rs.getString(1));

}

out.print("success");

%>[/code]

源文档 <http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=103&threadID=37290&messageID=253966>

JDBC控件是Beehive1.0中提供的访问JDBC数据源的Java控件。通过继承JDBC控件,我们根本无须关注访问数据库资源的通讯细节,只需要定义自己的业务方法,增加相应的注释来描述该继承子类,我们就可以非常轻松的实现企业应用中JDBC数据源的访问。

   JDBC控件的所有注释在org.apache.beehive.controls.system.jdbc.JdbcControl接口中定义,Beehive编译器在编译时将检查这些注释是否使用正确。

  本节中首先将通过一个简单的例子来演示如何通过继承JDBC控件来访问JDBC数据源,完成一个数据表的增加、删除、修改、查询等业务逻辑,随后将介绍如何使用JDBC控件访问JDBC数据源的更多技巧。

   本章中所有例子的源代码可以通过下载资源区的链接下载。

  

本节中所有演示例子对应的JDBC数据源均为MySQL数据库。

第一个JDBC控件的例子

  接下来的这段例子将演示如何通过继承JDBC控件来完成JDBC数据源的访问,实现JDBC数据源中一个数据表中记录增加、删除、修改和查询的业务逻辑。

   在演示例子中,为了保证演示的简洁,我们使用JDBC直接连接到数据库,而没有使用通常访问数据库所采用的DataSource技术。

  1. 建立数据表

  在本地MySQL数据库的Demo数据库实例中按照如下DDL建立相应的数据表。

  

create table demo(
id int(5) primary key auto_increment,
name varchar(20) not null default '',
value varchar(20) not null default ''
);

  1. 建立表征Demo对象的JavaBean

  创建新的应用目录,然后创建表征Demo对象的JavaBean

   清单1 srcorgvivianjbeehivecontrolsexamplescontrolsbeans

   Demo.java

1. package org.vivianj.beehive.controls.examples.beans;
2. 3. 4. /**
5. * Demo 用于表征Beehive JDBC控件例子中的Demo对象
6. */
7. public class Demo implements java.io.Serializable{
8. private int id;
9. 10. private String name;
11. 12. private String value;
13. 14. public int getId() {
15. return id;
16. }
17. 18. public void setId(int id) {
19. this.id = id;
20. }
21. 22. public String getName() {
23. return name;
24. }
25. 26. public void setName(String name) {
27. this.name = name;
28. }
29. 30. public String getValue() {
31. return value;
32. }
33. 34. public void setValue(String value) {
35. this.value = value;
36. }
37. 38. }

  1. 继承JDBC控件,增加自己的业务方法

  清单2 srcorgvivianjbeehivecontrolsexamplescontrols

   DemoMySQLControl.java

1. package org.vivianj.beehive.controls.examples.controls;
2. 3. import org.apache.beehive.controls.api.bean.ControlExtension;
4. import org.apache.beehive.controls.system.jdbc.JdbcControl;
5. import org.vivianj.beehive.controls.examples.beans.Demo;
6. 7. /**
8. * DemoMySQLControl 用于封装访问MySQL数据库中的Demo数据
9. 表的所有业务逻辑

10. * 包括新增、删除、修改、根据id查找对应的记录、查找所有Demo
11. 数据表中的记录、根据条件查找所有数据表中的记录

12. * 数据库访问时根据参数从DriverManager中获取数据库连接
13. */
14. 15. @ControlExtension
16. @JdbcControl.ConnectionDriver(
17. databaseDriverClass = "org.gjt.mm.mysql.Driver", 18. databaseURL = "jdbc:mysql://localhost/estore ",
19. userName = “root”, password = “root”)
20. public interface DemoMySQLControl extends JdbcControl {
21. /**
22. * 向数据表demo中增加新的记录
23. * 24. * @param demo
25. * 新增加的Demo对象
26. */
27. @SQL(statement = "insert into demo(name,value) 28. values({demo.name},{demo.value})")
29. public void createDemo(Demo demo);
30. 31. /**
32. * 修改数据表demo中demo.id对应记录的name和value信息
33. * 34. * @param demo
35. * 被修改的Demo对象
36. */
37. @SQL(statement = "update demo set name={demo.name},
38. value={demo.value} where id={demo.id}")
39. public void updateDemo(Demo demo);
40. 41. /**
42. * 删除数据表demo中demoId对应的记录
43. * 44. * @param demoId
45. * 被删除的Demo对象的id属性
46. */
47. @SQL(statement = "delete from demo where id={demoId}")
48. public void deleteDemo(int demoId);
49. 50. /**
51. * 根据demoId查找Demo数据库中对应的记录,返回对应的
52. Demo对象
53. * 54. * @param demoId
55. * 查找Demo对象的id属性
56. * @return id属性为demoId的记录
57. */
58. @SQL(statement = "select id,name,value from demo 59. where id={demoId}")
60. public Demo getDemoById(int demoId);
61. 62. /**
63. * 返回Demo数据表中所有记录集合
64. * 65. * @return Demo数据表中所有记录集合
66. */
67. @SQL(statement = "select id,name,value from demo")
68. public Demo[] getDemos();
69. 70. /**
71. * 72. * @param name
73. * @return
74. */
75. @SQL(statement = "select id,name,value from demo
76. where name like {sql: name}")
77. public Demo[] getDemosFilterByName(String name);
78. }

  1. 控件调用

  我们可以编写DemoMySQLControl控件的测试类,然后通过如下方式来完成控件中业务方法的调用。

  • 在测试类中采用声明式控件实例化方式来实例化DemoMySQLControl控件。

@Control
DemoMySQLControl _control;

  • 调用控件的相关业务方法来实现业务逻辑。

  下面的代码段可以完成Demo对象的新增功能。

Demo demo = new Demo();
demo.setName(“name”);
demo.setValue(“value”);
_control.createDemo(demo);

实例分析

  从上面的例子中我们可以看到,通过继承JDBC控件来完成JDBC数据源的访问是一件非常简单的事情,开发者需要完成的工作被简化为两项:编写表征访问对象的JavaBean和使用声明完成业务方法和逻辑的实现,这样的开发过程大大的简化了开发者的工作,极大地减少了开发者的代码编写量。

   下面我们详细的分析一下继承JDBC控件的子类DemoMySQLControl:

15. @ControlExtension

   在程序的第15行,我们使用@ControlExtension来注释将要创建的这个接口继承了另外的控件接口

16.@JdbcControl.ConnectionDriver(
17.databaseDriverClass = “org.gjt.mm.mysql.Driver”,
18.databaseURL = "jdbc:mysql://localhost/estore ",
19.userName = “root”, password = “king”)

  在程序的第16~19行我们使用@JdbcControl.ConnectionDriver注释来为将要创建的接口指定一些需要传递的参数,这里主要是一些数据库访问时所需要的JDBC驱动类、JDBC访问URL、数据库访问用户名和密码等必要信息。

   20.public interface DemoMySQLControl extends JdbcControl { 在程序的第20行使用extends关键字表示将要创建的接口DemoMySQLControl和JdbcControl接口之间的继承关系 27.@SQL(statement = "insert into demo(name,value) 28.values({demo.name},{demo.value})")

  在程序的第27~28行使用@SQL关键字注释接下来定义的这个业务方法所需要执行的业务逻辑,其中的{}表示对传入参数的调用,{}包含的内容表示了需要处理的参数,这些参数的表示方法遵循面向对象的属性调用方式,JDBC控件的解析器会将这些代码转化为对应的getter方法调用。

29.public void createDemo(Demo demo);

   在程序的第29行,采用常用的接口方法声明了该控件的一个访问接口。

  后面的代码采用和27~29行相应的原理定义了其它需要实现的业务方法。需要注意的是,定义查询类方法时,如果只需要返回一条记录,目前通常的做法是返回一个Demo对象。如果返回的记录有超过一条的可能性,返回的是符合查询条件的Demo对象数组、List对象等,请参考《JDBC控件返回类型》部分的内容。

  前面的内容中,我们已经通过继承JDBC控件完成了访问数据库资源的全部内容,现在你可以编写单元测试代码来测试控件是否符合要求了。请大家参考《控件入门》中的步骤完成JDBC控件的编译和单元测试工作。

  到现在为止,我们已经知道了如何使用JDBC控件和注释来访问数据库资源的基本步骤和方法,但是还没有学习如何使用注释来让JDBC控件和业务内容的结合起来。这部分的内容分作两部分进行介绍:一是如何通过注释定制JDBC控件,提供访问数据库的信息(比如数据库访问方式、URL、用户名和密码等),一是如何确定每次业务方法执行的返回对象。

使用注释订制JDBC控件

  本节中的内容将给大家介绍如何使用JDBC控件提供的注释根据不同的环境和要求来订制JDBC控件,完成JDBC数据源的访问和业务逻辑的封装。

   JDBC控件支持的四个注释:ConnectionDataSource、ConnectionDriver、ConnectionOptions、SQL。四个注释中ConnectionDataSource、ConnectionDriver、ConnectionOptions是用于类级别的注释,用于描述JDBC控件继承类,SQL注释是方法级别的注释,用于描述JDBC继承类中的业务方法。

  使用ConnectionDataSource注释可以指定JDBC控件访问数据库时根据采用DataSource方式获取数据库连接。使用ConnectionDriver注释可以指定JDBC控件访问数据库时使用指定的参数通过DriverManager获取数据库连接。ConnectionOptions注释描述了数据库访问时的一些扩展特性,比如数据库访问时是否使用READONLY优化(仍然可以进行UPDATE操作)等。

   下面开始详细的介绍这些注释,并且通过提供简单的代码段来说明如何使用这些注释来配置JDBC控件的继承类。

CONNECTIONDRIVER注释

  ConnectionDriver用于注释JDBC控件的继承类,控制JDBC控件在访问数据库的时候通过DriverManager获取数据库连接。ConnectionDriver注释支持5个参数:databaseDriverClass、databaseURL、userName、password、properties。

  • databaseDriverClass

  String类型,用于设定数据库驱动类的全名。使用ConnectionDriver注释时必须设置的参数。

   比如访问MySQL数据库,可以使用databaseDriverClass= “org.gjt.mm.mysql.Driver”,访问Oracle数据库的时候可以使用databaseDriverClass= “oracle.jdbc.driver.OracleDriver”

  • databaseURL

  String类型,用于设定数据库访问的JDBC URL,使用ConnectionDriver注释时必须设置的参数。

   比如访问MySQL可以使用databaseURL=“ jdbc:mysql://localhost/estore”,访问Oracle数据库时可以使用databaseURL=“ jdbc:oracle:thin:@localhost:1521:www”

  • userName

  String类型,设置访问数据库时使用的用户名,可选参数。

  • password

  String类型,设置访问数据库时使用的密码,可选参数。

  • properties

  String类型,设置访问数据库时的一些其它参数,可以一次性传递多个参数,两个参数之间用逗号隔开。

  在《第一个JDBC控件的例子》中,我们提供的代码已经演示了如何使用ConnectionDriver注释JDBC控件,请参见清单2 。

  

ConnectionDriver注释的JDBC控件运行时,必须保证databaseDriverClass中指定的数据库驱动类位于classpath中,否则控件运行时将抛出违例。

CONNECTIONDATASOURCE注释

  ConnectionDataSource注释用于指定JDBC控件在访问数据库时通过DataSource获取数据库连接,它有两个属性:jndiName和jndiContextFactory。

  • jndiName

  String类型,用于设置DataSource在目标容器内的jndiName属性

  • jndiContextFactory

  Class类型,用于设置数据库访问时可以获取jndi上下文环境的类,被传入的参数类必须继承org.apache.beehive.controls.system.jdbc.JdbcControl. JndiContextFactory类,并且覆盖JndiContextFactory类的getContext()方法,getContext()将获取访问目标容器的上下文环境(Context)。

  下面的章节中我们将看到如何通过JDBC控件和ConnectionDataSource注释访问Tomcat服务器,获取jndiName为jndi/samplesDataSource的DataSource资源,该DataSource连接到MySQL数据库的Demo实例,Web应用部署在Tomcat环境中。

  1. 修改Tomct配置文件,创建DataSource资源

  如何创建Tomcat环境下的DataSource资源请参考Tomcat的帮助文档。

  1. 修改Web应用的配置文件web.xml,增加如下内容,增加对资源的引用

  <resource-ref>

   <description>Datasource example</description>

   <res-ref-name>jndi/samplesDataSource</res-ref-name>

   <res-type>javax.sql.DataSource</res-type>

   <res-auth>Container</res-auth>

   </resource-ref>

  1. 创建访问Tomcat服务器Jndi上下文的类JndiContextFactory

  JndiContextFactory类继承自JdbcControl.JndiContextFactory父类,覆盖父类中的抽象方法----getContext(),清单3 中显示了JndiContextFactory类定义和实现的完整代码。

  清单3 src orgvivianjbeehivecontrolsexamplescontrols

   jndicontextJndiContextFactory.java

1. package org.vivianj.beehive.controls.examples.controls.jndicontext;
2. 3. import java.util.Hashtable;
4. 5. import javax.naming.Context;
6. import javax.naming.InitialContext;
7. 8. import org.apache.beehive.controls.system.jdbc.JdbcControl;
9. 10. /**
11. * JndiContextFactory 用于从Tomcat服务器中获取访问JNDI内容的上下文环境
12. */
13. public class JndiContextFactory extends JdbcControl.JndiContextFactory {
14. /**
15. * 获得本地Tomcat服务器中访问JNDI内容的上下文环境
16. * 17. */
18. public Context getContext() {
19. 20. Context ctx = null;
21. 22. try {
23. ctx = (Context)(new InitialContext().lookup("java:/comp/env"));
24. } catch (Exception e) {
25. 26. }
27. 28. return ctx;
29. }
30. }

  1. 我们可以使用ConnectionDataSource注释和新创建的JndiContextFactory类来注释JDBC控件了。

  下面的代码片断就是一个简单的例子,使用这段代码注释的JDBC控件,调用任何业务方法时,将通过本地Tomcat服务器上、JNDI名为“jndi/ samplesDataSource”的DataSource资源获取数据库连接。

   @JdbcControl.ConnectionDataSource(

   jndiName = "jndi/samplesDataSource",

   jndiContextFactory=JndiContextFactory.class)

CONNECTIONOPTIONS注释

  ConnectionOptions可以用于定义访问数据库时的一些扩展特性,可以选择性的和ConnectionDataSource或者ConnectionDriver一起使用。ConnectionOptions支持三个参数:readOnly、resultSetHoldability、typeMappers。

  • readOnly

  boolean类型,如果设置为true,数据库连接将优化为ReadOnly的访问方式,但是仍然可以进行更新和删除操作。默认为false。

  • resultSetHoldability

  org.apache.beehive.controls.system.jdbc.JdbcControl.HoldabilityType类型,可以选择为HOLD_CURSORS_OVER_COMMIT或者CLOSE_CURSORS_AT_COMMIT,用于设置ResultSet指针的关闭策略,默认值是CLOSE_CURSORS_AT_COMMIT,表示在每次commit之后关闭ResulSet对象指针。

  • typeMappers

  org.apache.beehive.controls.system.jdbc.JdbcControl.TypeMapper数组类型。设置SQL自定义类型和Java类型之间的映射。TypeMappers类中指定的Java类型必须实现java.sql.SQLData接口

SQL注释

   SQL注释用于描述JDBC控件继承类中定义的方法,主要设置被注释方法调用时需要执行的SQL语句和其它功能。我们可以回头看一看清单2,里面的每一个业务方法之前均有@SQL注释。

   SQL注释支持很多属性设置,包括statement、arrayMaxLength等,其中最重要的就是statemet,本节中我们讨论statement属性的设置,其他属性的设置方法请大家参考Beehive的帮助文档,在大多数的情况下最好不要设置这些属性,因为里面可能用到JDBC3.0规范中的新特性,而现在很多数据库驱动并不支持这些特性。

   statement内容描述了我们需要完成的业务逻辑,在statement中我们可以使用变量的方式访问被注释方法中传递进来的参数,JDBC控件的解析器在运行时保证这些参数的正确传递。

statement编写规则

  SQL注释的statement属性提供了被注释方法调用时执行的SQL语句的内容,SQL语言中可以使用JdbcControl提供的特殊语法直接访问Java对象或者它的属性。编写statement必须满足以下条件。

  1. statement中的sql语句编写方式和要求参考目标数据库的sql语句编写方式和要求。
  2. statement中使用{…}声明变量来获取业务方法调用时所传递参数或者它的属性。
  3. statement中变量声明的第一个字符和最后一个字符不能是空格,也就是说不能出现{ a}或者{a }这样的情况,否则可能执行结果和您期望的会有很大的出入
  4. {}中间的内容是大小写敏感的。如果传入的参数名为a,而{}中引用为A,他们之间将无法匹配。
  5. {}中间的内容可以是参数名(传入的参数是Java基本数据类型时适用),或者是参数对象的某个成员变量(传入的参数是Java类对象时)。
  6. {}中引用Java对象的字段时,必须保证该字段符合以下条件之一,否则Java控件调用时将会返回一个违例:
  7. 该字段被public关键字声明为公共字段,可以使用 对象名.字段名 直接访问
  8. 该字段被private关键字声明为私有字段,但是提供了公共的getter方法,可以通过对象名.get属性名方式访问。
  9. 该Java对象继承了java.util.Map接口,可以通过对象名.get(“属性名”)方式访问
  10. statement中引用业务方法中传递的参数时必须保证这些参数和对应的数据表的字段类型保持一致,不能出现数据表的字段是NUMBER类型,而对应的参数却是String类型。
  11. 当业务方法传递的日期或者时间类型的参数需要在statement中被引用时,请保证这些传递的日期和时间使用的是java.sql包中的对应类,比如我们应该使用java.sql.Date而不要使用java.util.Date来传递日期类型的变量给statement
  12. statement中不能出现单引号。如果确实需要使用单引号,必须采用特别的方法解决。

statement创建实例

  • 不从业务方法获取参数

  下面的业务方法声明可以从demo表中取出所有所有记录,返回一个Demo对象的数组。

   @SQL(statement=“select * from demo” )

   Public Demo[] getDemos();

  • 从业务方法中获取基本类型参数

  下面的statement中,我们使用{demoId}变量从getDemoById()方法调用中获取传入的参数demoId。

   @SQL(statement=“select * from demo where id={demoId}” )

   Public Demo[] getDemoById(int demoId);

  • 从业务方法中获取Java对象类型参数

  下面的statement中,我们使用{demo.name}变量表示从createDemo ()方法调用中获取传入的Java类对象demo的name属性的内容。

   @SQL(statement = “insert into demo(name,value)

   values({demo.name},{demo.value})”)

   public void createDemo(Demo demo);

  • 从业务方法中获取完整SQL语句

  有些时候,SQL语句可能需要动态生成,这时候statement默认的方式无法帮开发者完成这个过程,而是需要在Java代码中完成SQL语句的组装后传递给业务方法,这种情况下我们可以使用{sql: …}的方式向statement中传递一个完整的sql语句。

@SQL(statement=“{sql: totalsql}” )
Public Demo[] getDemos(String totalsql);

  • 从业务方法中获取SQL语句片断

  statement还支持某一段SQL语句从业务方法的参数中获取,比如下面的这个例子中,只有最后的{sql: name}来源于业务方法中的参数。

@SQL(statement = “select id,name,value from demo
where name like {sql: name}”)
public Demo[] getDemosFilterByName(String name);

  这种方式可以解决SQL语句中包含引号等特殊字符的问题,解决方法是你可以在业务方法调用之前使用Java代码创建包含这些特殊字符串的内容,然后通过sql片断的方式发送给statement。

  这种方式另外一种用途是可以解决SQL语句部分片断需要动态生成的问题,举个例子,我们的多条件查询的条件下,用户可以选择按照一个或者多个条件进行查询,所以where语句后面的条件是动态的,这种情况下,我们就可以把判断和SQL语句中where语句的生成这部分功能实现分离到Java语句中,然后作为业务方法调用参数传递到statement中来。

  • 调用存储过程

  JDBC控件支持对存储过程的调用,只需要在statement中配置里面采用{call …}这样的方式表示当前执行的是一个存储过程就可以了,下面的例子演示了如何调用存储过程以及如何向调用过程传递参数。

@SQL(statement=“call sp_updateData({keyVal}, {intVal})”
void call_sp_updateCust(short keyVal, int intVal);

控件返回类型

  继承JDBC控件后声明业务方法时,查询类业务方法需要返回数据,在业务逻辑中,需要返回的业务数据通常可以分为三种:

  • 简单字段。

  比如要查询今天有多少人访问了我们的系统、编号Id为1000的用户他的真实姓名是什么?。

  • 单条记录。

  比如查询结果需要返回编号为1000的用户。

  • 多条记录。

  比如查询结果需要返回所有系统用户。

   本节中将按照这三种不同的情况给大家介绍JDBC控件所支持的返回类型以及内部处理机制。

使用控件返回简单字段

  JDBC控件支持所有Java基本类型及其对应对象类型的返回,比如int、Integer、String等,在继承JDBC控件后声明业务方法时,只需要声明所需要的返回类型,JDBC控件会自动将SQL操作结果造型为所需要的返回类型。

   比如我们声明一个业务方法:

@SQL(statement = “select count(*) from demo”)
public int getDemosCount();]

  控件调用后的结果将返回一个int数值,而如果你声明的业务方法如下:

@SQL(statement = “select count(*) from demo”)
public Integer getDemosCount();

  控件调用后的结果将返回一个Integer对象。

  返回结果为简单字段时,如果SQL语句执行后没有符合要求的结果,控件将根据声明的返回类型返回不同的值,如果声明返回结果为数值型,那么返回结果为0;如果声明返回结果为boolean,那么将返回false,而如果声明的返回结果为类类型,那么控件调用返回结果为null。

使用控件返回单条记录

  当SQL查询语句需要返回单条记录时,控件支持两种不同的返回类型:JavaBean对象或者Map(或者HashMap)对象。如果能够确定返回对象的属性,通常采用返回JavaBean对象,比如要查找id为1000的系统访问者的详细信息,通常我们知道系统访问者的所有细节,所以使用JavaBean对象作为访问信息。如果无法确定返回对象的详细属性或者时返回对象的属性经常发生变化,比如我们的业务方法中可能返回一个系统访问者的信息,也可能返回的是一个管理员的信息,那么我们可以选择使用Map(或者HashMap)对象声明为业务方法的返回对象。

  • 返回JavaBean对象

  这种情况下,控件将在SQL语句执行结束后,自动构造一个返回结果声明类型的对象,调用它的相关setter方法初始化这个对象,然后返回这个对象。如果初始化过程中没有找到合适的setter方法,系统将抛出违例信息。

   我们可以通过如下的声明,控制控件在调用后返回一个Demo对象:

@SQL(statement = “select id,name,value from demo
where id={demoId}”)
public Demo getDemoById(int demoId) ;

  可声明为返回JavaBean类型的Java类必须符合以下条件:

  • Java类必须提供和statement中声明的返回字段对应的getter和setter方法。这些getter和setter方法必须支持大小写敏感。Java类中必须包含但不仅限于这些getter和setter方法。
  • Java类中每个getter和setter方法定义的数据类型必须和数据库表中的数据类型保持一致。
  • 如果该Java类是某个类的内部类,那么这个类必须使用public static关键字定义类声明。
  • 返回Map(或者HashMap)对象

  在不确定返回对象详细信息的情况下,我们可以声明返回对象类型为Map(或者HashMap),这种情况下,控件在SQL调用完成以后,将调用Map(或者HashMap)的put方法,将返回结果映射为Map(或者HashMap)对象,返回Map(或者HashMap)对象对象中键--值对的键就是数据表字段名称,键是大小写敏感的,返回Map(或者HashMap)对象中的所有键都被变成了大写字母,值就是数据表字段包含的值,值的类型和数据库中对应字段的类型有关。

   我们可以通过如下的声明,控制控件在调用后返回一个Map(或者HashMap)对象:

@SQL(statement = “select id,name,value from demo
where id={demoId}”)
public HashMap getDemoById(int demoId) ;

  在业务方法声明为返回单条记录时,如果该记录的对应字段为空,那么返回结果的对应字段将根据对应属性的类型被初始化null、0或者false,如果SQL语句实际执行时没有找到符合条件的记录,控件的默认返回结果为null,如果SQL语句实际执行时返回了多条记录,那么控件将默认将符合条件的第一条记录作为返回结果。

使用控件返回多条记录

  SQL查询语句的返回结果通常是一个以上的记录,JDBC控件支持使用数组、Iterator对象、ResultSet对象和XMLBeans对象来返回可能的多条记录。控件开发者需要根据不同的情况选择合适的返回对象,既要考虑让控件使用者操作简单,也要考虑可能引起的其他问题。

  使用数组返回多条记录对控件使用者而言是最好的方式,因为数组的遍历不需要更多的JavaAPI知识。然而数组只能在数据库操作完成以后一次性生成,因此整个ResultSet对象将被缓存,所以如果查询结果是一个非常大的ResultSet的时候,可能会造成系统内存耗尽的情况,这种情况下,使用数组返回多条记录的控件开发者必须考虑数据的分批提取策略。

  使用Iterator对象返回多条记录对控件的使用者提出了更高的要求,这种情况下,Iterator对象封装了ResulSet的数据获取行为,控件使用者在调用Iterator对象的next方法时,容器会调用ResultSet的对应方法从数据库中获取对应的记录,这种方式不存在ResultSet集大或者小的问题。当时这种方式不适合在PageFlow中使用,因为PageFlow的Action调用完成后跳转到显示页面使用Iterator对象时,数据库连接通常已经被关闭了,ResultSet已经无法获取相应的数据了,所以Iterator对象中的数据也无法得到。

   JDBC控件也支持直接返回ResulSet对象,以便控件使用者能够自由的控制SQL语句操作结果。

  • 如何使用数组返回多条记录

  这种情况下你可以有两种选择:返回JavaBean对象数组或者Map(或者HashMap)数组。这两种情况的区别请参考章节<<如何返回单条记录>>中的相关内容。

   我们可以使用下面这段代码声明业务方法返回JavaBean对象数组:

@SQL(statement = “select id,name,value from demo”)
public Demo[] getDemos() ;

  如果需要声明业务方法返回的结果被封装成Map(或者HashMap)数组,请参考使用下面的这段代码:

@SQL(statement = “select id,name,value from demo”)
public Map[] getDemos() ;

  如果SQL语句执行后没有符合条件的记录返回,上面的这两种情况下将返回一个长度为0的数组。

  • 如何使用Iterator对象返回多条记录

  和上面的情况一样,你可以选择Iterator中包含的对象是JavaBean对象或者是Map(或者HashMap)对象。

   我们可以使用下面这段代码声明业务方法返回Iterator中包含的是JavaBean对象:

@SQL(statement = “select id,name,value from demo”,
iteratorElementType=Demo.class)
public java.util.Iterator getDemos() ;

  如果需要声明业务方法返回的Iterator中使用Map(或者HashMap)封装单条记录的所有属性,请参考使用下面的这段代码,其中的iteratorElementType声明返回Iterator结果中包含的是HashMap对象:

@SQL(statement = “select id,name,value from demo”,
iteratorElementType=java.util.HashMap.class)
public java.util.Iterator getDemos() ;

  

后面这种情况下,返回结果中的HashMap对象的所有键(Key)都已经被变成了大写,控件使用者在访问时请注意这一点,不然可能引起程序的不正常运行。

  • 如何使用ResultSet对象返回多条记录

  这种方式的声明代码如下:

@SQL(statement=“SELECT * FROM customer”)
public java.sql.ResultSet findAllCustomersResultSet();

  基于大家熟知的性能方面的考虑,不推荐控件开发者使用这种方式来返回多条记录。

结束语

  数据库资源是企业应用中的主要资源形式之一,所以如何访问数据库资源是企业应用中的重要内容。控件架构中的JDBC控件大大的简化了数据库访问资源的复杂性、难度,开发者只需要通过简单的继承org.apache.beehive.controls.system.jdbc.JdbcControl,然后通过提供相应的注释就可以完成数据库资源的访问和操作结果的返回。

  本文中,作者首先通过简单的例子介绍了JDBC控件使用的基本步骤,然后详细的介绍了JDBC控件提供的主要注释和使用方法,最后介绍了如何通过JDBC控件返回操作结果的方式方法。

源文档 <http://dev2dev.bea.com.cn/techdoc/20060927886.html>

 查看全文
RobinOuyang 发表于:2008.05.12 13:38 ::分类: ( Java Programming ) ::阅读:(9936次) :: 评论 (0) :: 引用 (0)
===========================================================
JSP使页面过期
===========================================================
response.setHeader( "Cache-Control" , "no-cache" ); //Forces caches to obtain a new copy of the page from the origin server response.setHeader( "Cache-Control" , "no-store" ); //Directs caches not to store the page under any circumstance response.setDateHeader( "Expires" , 0); //Causes the proxy cache to see the page as "stale" response.setHeader( "Pragma" , "no-cache" ); 尤其要注意那个no-store的,这个才可以保证对firefox同样生效。
RobinOuyang 发表于:2008.03.06 14:40 ::分类: ( Java Programming ) ::阅读:(493次) :: 评论 (0) :: 引用 (0)
===========================================================
Portlet中getParameter的问题
===========================================================
如果页面中的一个form中有好些属性,而在action中是通过request.getParameter()获得,在一般的PageFlow中是可行的,但是,如果将这个PageFlow做成了Portlet就无法获得了,必须先通过ScopedServletUtils获得外层的request,这样子才能继续获得参数。
当然了,如果不是通过Form中的属性参数提交,而只是在URL上通过netui:parameter追加参数,还是没有问题的。
RobinOuyang 发表于:2008.02.18 11:12 ::分类: ( Java Programming ) ::阅读:(363次) :: 评论 (0) :: 引用 (0)
===========================================================
RSS链接超时检测问题
===========================================================

门户中很多地方采用了RSS,尤其是首页部分,如果其中一个RSS服务器链接超时了,必然导致整个首页要等待很长时间才出来,给用户的感觉就是出不来了,因此我们在获取RSS之前,需要检测一下链接是否存在,是否超时。
方法如下:

System.setProperty("sun.net.client.defaultConnectTimeout", "3000");
System.setProperty("sun.net.client.defaultReadTimeout", "3000");
URL rssURL = new URL(urlstr);
HttpURLConnection urlConn = (HttpURLConnection)rssURL.openConnection();
urlConn.connect();

如果超时,执行上诉代码就会出现异常。

其中urlstr就是RSS种子的URL,前面两个是设置超时检测属性,这个是在JDK1.4以前采用,1.5以后URL对象已经有专门的方法设置。另外最后一句urlConn.connect()需要引起注意,我们在SunJDK上检测的结果是不需要这一句就可以检测链接超时了,但是在JRockit上却还是不行,一次不经意的修改发现加上这一句可以使得检测超时在JRockit上有效。
Bingle!


RobinOuyang 发表于:2007.04.25 13:15 ::分类: ( Java Programming ) ::阅读:(471次) :: 评论 (0) :: 引用 (0)
===========================================================
页面流的继承
===========================================================
额地妈耶,试了老长时间了,终于成功了。 早就听说BEA workshop 9.2支持页面流的继承,但是主要是有两个问题,一是在将程序升级到9.2之后,IDE会提示原来的FormData类型不推荐使用了,建议改成implements Serializable。可是当我改了之后发现页面上无法识别actionForm.property。第二个问题就是即使是恢复成extends FormData,还是无法实现继承。 最后实验所得经验如下: 首先是在将8.1 Application升级到9.2时候,要选择JSP netui标签完全替换为 beehive标签。它默认是替换为netui-compat标签,在这种情况下,我试了新建一个简单的BaseFlow,然后里面用Form implements Serializable,是不行,即使这个pageflow的JSP用的是beehive标签也不行。之后我重新做了一遍升级,选择了完全替换成beehive标签,就发现可以采用Form implements Serializable了,而且新建一个BaseFlow和DerivedFlow实现了继承。 在修改原来的页面流实现继承时,需要将9.2应用下的build文件夹下的classes和netui目录给删了,否则它自己build时候不清这两个目录,导致程序上的一些修改不起作用。我是在改一个Form名字之后发现运行的时候老是提示原来的那个Form找不着,之后全局查找之后在发现在那两个目录下的xml文件中存的还是原来的form,清了之后就OK了,可以实现继承了。
RobinOuyang 发表于:2007.04.18 09:08 ::分类: ( Java Programming ) ::阅读:(57065次) :: 评论 (0) :: 引用 (0)
===========================================================
数据权限设计思考
===========================================================
目前有关用户权限采用的比较多的都是基于RBAC模型,即通过对角色权限的定义完成对用户权限的限制。有关功能权限部分想必都比较清楚,就是将系统的功能模块划分清楚,并赋予不同角色的访问权限,这样在用户访问某个功能模块之前进行权限校验即可。但是有关数据权限部分却一直比较模糊。

在如下这篇文章中给出一个权限模型,里面提到了数据权限的建模。
http://blog.csdn.net/fly_cloud/archive/2006/08/09/1041807.aspx
这个模型中有关数据权限也是对角色进行权限限定。模型中定义了几个概念:
资源:用户将要访问的数据对象(如用户)
数据对象类型:对用户将要访问的数据对象的限定类型(如部门)
资源数据对象类型:上面两个概念关联产生的,即用户要访问什么类型的数据对象(如××部门的用户,但是此时的××是通用的,只有将数据对象类型具体化之后××才会出现)。

将上面的资源数据对象类型实例化(即××具体化)之后就形成了一条数据对象访问规则,将这条规则附加给某个角色就完成了对角色数据访问权限的限定。这个模型定义是很清楚的,但是如何具体实现,其实是一个比较复杂的问题。

一个比较直观的想法就是在业务层之上加一个数据权限校验层。

上面定义的数据对象类型其实就是用户访问的数据对象的属性,因此在校验的时候确定相关数据对象的属性是否满足用户数据权限规则即可,对于增删改就是操作之前校验,对于查询就需要对查询结果过滤。当然为了整个实现的简单需要确保系统中的所有数据对象Class都是从一个Class中继承而来限制是。这一想法实现起来比较简单,但是有一个限制和一个性能忧虑。限制就是为了保证规则校验的进行,必须使得所有数据对象都应当具有权限规则定义的相应属性,如果规则定义的属性发生变化,势必需要所有数据对象的生成方法发生变化。性能忧虑就是对查询结果的过滤,其实在一般的MIS系统中多数情况是进行查询,但是如果依照这种方法进行结果过滤的话,可能会存在性能的问题。

因此,这一想法具有紧耦合和性能问题。

另外一个想法依然无法避免紧耦合,但是可以避免性能问题。然而在逻辑上就没有上面那个直观了。这一想法就是将数据权限规则转成SQL语句,嵌入到数据访问层中去。

因为资源必定会对应到某一个数据表,而数据对象类型也会对应的到某个数据表的某个属性列,因此完全可以依据数据权限规则动态生成SQL语句。数据权限规则可以如下定义:【资源数据对象类型 关系符 右值】,右值可以分为静态和动态两种:静态就是一个具体的值;动态就是用户的某个属性,这只有在与用户关联上之后才能确定。但是由于一个角色可以有多条数据权限规则,那么他们之后可以是与和或的关系,多个规则之间可能存在冲突,必须进行避免,如:当规则之间是与关系时,如果资源数据对象类型和关系符都相同时,就有可能冲突。具体的说就是要限制角色R只能访问A部门的用户且只能访问B部门的用户,这样子势必是相互冲突的。

在数据访问层调用一个统一的SQL生成方法,传入两个参数:不加限定是要访问的数据表名和角色数据权限规则集(此时的规则集中应当已经具有准确的右值,即如果是动态的也已经根据用户属性赋值了)。方法是:依次判断规则集中的规则是否有要访问的数据表名,如果有就生成SQL语句的FROM子句和WHERE子句,最终语句规则集关系符(AND | OR)生成FROM子句和WHERE子句返回。
数据访问层获得权限校验产生的FROM子句和WHERE子句嵌入到数据访问方法中去,这样就将数据访问和权限校验结合在一起了。明显是紧耦合,但是规避了性能问题。

因此,上面两个想法各有个的优势,但是同样都有一定的问题,是不是有更好的办法?继续思考中……

RobinOuyang 发表于:2007.04.01 11:08 ::分类: ( Java Programming ) ::阅读:(441次) :: 评论 (1) :: 引用 (0)
===========================================================
WSRP探秘
===========================================================
这周除了继续思考数据权限模型的建模和实现以外,主要还研究了一下WSRP(Web Service for Remote Portlet)。这个技术主要是采用WebService方法整合其他应用中的远程portlet到自己的Portal应用中去。
首先需要有一个Producer,即提供服务的出处,它分为两种:Simple Producer和Complex Producer,一般的采用Workshop创建Portal项目都是Complex的,而一般的Web Project即只采用Struts或者PageFlow的都是Simple的,其实生成Producer的过程很简单,如果是采用Workshop,则有很简单的菜单,当然即使不是采用Workshop,也就是拷贝几个Jar和生成几个XML文件。但是不管怎么样,都有一个问题就是这个Producer一定要运行在Portal Domain上,否则无法发现这个Producer中的服务(后面会提如何发现)。
接着就是应用Remote Portlet的Consumer。这一步操作也很简单,就是在创建portlet的时候选择类型remote portlet,然后输入producer的WSDL,一般是“[WEB_ERL]/producer?WSDL”,然后点击Retrive就可以发现Producer中的portlet了,之后选择一个portlet就可以创建成功了。
运行门户测试之后发现有两个问题:
1.URL问题,就是原来producer中的URL如果没有采用portal的URL tag或者应用生成URL的话,那么这个URL在consumer中应用就会出现连接错误,比较明显的就是一些图片无法显示。
2.用户身份问题,如果producer中需要用户身份,如果不设置CA和SSO,那么producer无法获取consumer中已经登录的用户。

这两个问题是致命性问题,涉及到对原来应用的修改和需要部署SSO,除此之外,加上需要producer部署在Portal Domain这一限制,当然还有producer和Consumer的风格差异问题,使得WSRP这一技术在当前工作中的应用,看来目前尚存在较大的困难。
RobinOuyang 发表于:2007.04.01 11:06 ::分类: ( Java Programming ) ::阅读:(371次) :: 评论 (0) :: 引用 (0)
===========================================================
BEA WebLogic问题解决方案总结
===========================================================

问题1:当采用ant 工具编译,尤其是当ant脚本中采用了ejbc这样的编译程序时,经常会出现BEA自动生成的代码部分少字符现象,解决的方法是在ant build脚本的相应位置加上jvmarg,如下:

<target name="execute_ejbc" depends="init, package_jar" >
<java classname="weblogic.ejbc" fork="true" failonerror="true">
<jvmarg value="-Dfile.encoding=GBK"/>
<arg file="${work}/build/ejb.jar" />
<arg file="${work}/build/ejb-container.jar" />
</java>
</target>

这个问题出现的原因可能是由于WEBLogic 在中文系统中采用的编码是gb18030,而它的内部编译器生成代码采用的却是GBK的缘故。

同样的问题当不是采用ant脚本编译,而是直接采用BEA的 Workshop编译是会出现同样的问题,就是代码少字符,解决的方法是:在Windows的“控制面板”-》“区域与语言选项”-》“高级”-》代码页转换表中不要勾选“GB18030”,然后退出程序,重启机器即可。

问题2:在BEA Portal中如果自己开发简单的Authentication Provider,这个Provider中只是实现了必要的MBean,没有实现其他的Optional的Mbean,而且这个Provider中认证用的用户数据库不是Weblogic默认的数据库(不仅仅是类型,还有物理和逻辑位置),这样子以来,在程序中获得Profile的方式如果采用ProfileFactory.getProfile会报错,提示Profile找不着,解决的方法是:可以采用UserProfileControl获得,可以采用profile:getProfile标签获得,但是在一般的Java文件中无法采用上述两种形式,此时可以采用ProfileFactory.getPhantomProfile获得。


RobinOuyang 发表于:2006.06.28 08:10 ::分类: ( Java Programming ) ::阅读:(733次) :: 评论 (3) :: 引用 (0)