JiveJdon Community Forums
在线100人   首页   主题表   培训咨询   标签   查搜   注册    登陆 RSS
符合查询结果共有181 2 Go
Re: B/S展现层的选型探讨 2004年07月14日 09:54 到本帖网址


http://www.jdon.com/jive/thread.jsp?forum=62&thread=15041

http://buaawhl.blogdriver.com/diary/buaawhl/index.html

Re: 如何读取并显示服务器上不在webapp目录上的图片? 2004年07月13日 11:07 到本帖网址

iter.i tried to send a mail to you. but failed.
if u like, please contact my msn whlhuzhao@hotmail.com.

Re: Web页面技术综述(包括fastm) 2004年07月12日 22:55 到本帖网址

多谢Banq的回答。我们的思路经历有些相同。
我甚至想到了要使用SiteMesh。
http://www.opensymphony.com/sitemesh/
SiteMesh是一个基于Servlet Filter规范的一个页面布局工具。
属于opensymphony组织。OSWorkflow,WebWork就属于这个组织。

但后来发现,这样会令问题更加复杂化。
比较探索了各种框架许久。直到了解了PHP,才豁然开朗,找到了思路。

fastm的核心思想是,
(Static Readonly)Template DOM + (Dynamic) ValueSet DOM = Dynamic Template.

其中的Tempate DOM从PHP模板思路而来。
而ValueSet DOM是我为了支持多线程、节省空间和时间,而产生的概念。

我正在做把Struts Tile TagLib的Sample移植到fastm的例子。
还有一些Portal的例子。完成之后,请Bang多指教。

另:
我也在关注JDonJive。
并也有未来把一些Forum移植到fastm的想法。
对于fastm来说,移植PHP Forum更容易一些。因为fastm几乎可以直接使用PHP模板。


Re: 如何读取并显示服务器上不在webapp目录上的图片? 2004年07月12日 12:24 到本帖网址

iter.
没错。我是在xmu的ehi。:-) and u?

多谢解答。
你是说,这是两个Web Context之间的互访问?
和"crossContex"属性有关吗?



Re: Web页面技术综述(包括fastm) 2004年07月12日 12:16 到本帖网址

多谢banq的鼓励和关注。

我也一直在关注JSF。并希望JSF能与Visual Studio(ASP.net)一争。

另外,在JDon论坛中看到banq与道友讨论Portal框架和Portlet规范的贴子。受益非浅。多谢。(当然,JDon中还有各种其它的规范和实现讨论,比如Web Service,一并谢过)。

我正是比较了多个框架,多种实现方式,多种开发方式。才产生了实现fastm的想法,以提高开发速度、运行速度,降低学习成本和维护成本。
并且,fastm在实现Layout,Tile,Portal方面,具有先天的优势。


Re: 关于多线程编程的讨论,请高手们展开来讨论一下 2004年07月09日 19:16 到本帖网址

同意mep.

synchronized instance_method = synchronized(this);

synchronized static_method = synchronized(the Class itself);

http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#30531

Re: 语法问题 2004年07月09日 19:12 到本帖网址
首先,我们要知道,"aaaaaaaaaa"这个字符常量是在Class结构的Constant Pool里面分配的。
参考这个link.
http://jakarta.apache.org/bcel/manual.html
里面有类加载到内存中的结构。


字符串常量和一般字符串还是有一些区别:
字符串常量的声明方法,和一般字符串的声明方法之间的区别。下面举例说明这个区别。

String a = “ABC”; // 字符串常量
String b = “ABC”; // 字符串常量
String c = new String(“ABC”); // 不是字符串常量

这里我们有a == b,a和b 这两个字符串的reference相等,都指向字符串常量”ABC”。
尽管c.equals(a)并且c.equals(b),但是c != a,c != b。c有自己的reference,指向new String(“ABC”)。

可以运行这段代码,看看结果。
这可能是JVM为了做优化所导致的结果。


Re: 关于线程的问题,清高手指点 2004年07月09日 18:56 到本帖网址
线程安全的标准只有一个:
代码中是否用到具有可以改变的(writable)的成员变量(不管是静态还是实例变量)。

如果有writable的成员变量,那么不是线程安全。这样的类或对象 称为 stateful。

如果只有Read-Only成员变量,没有writable成员变量,那么是线程安全。
这样的类或对象 称为 stateless。

Re: 急,盼各位高手回复,多谢! 2004年07月09日 18:44 到本帖网址
如果这些XML文件都具有同样的XML Schema或者DTD。
那么,一个解析器就够了。

有多少种XML Schema或者DTD,就需要多少个解析器。

Re: 这么多设计模式,我的看法和理解 2004年07月09日 18:37 到本帖网址
3.多列排序问题

3.1排序条件的数量

我们知道,SQL语句能够实现强大的排序功能,能够按照不同字段的排列进行排序,也能够按照升序,降序排序。比如下面的语句。
order by field1 asc, field2 asc, field3 desc。

这个排序条件按照field1的升序,field2的升序,field3的降序排序。
注意,排在前面的字段具有较高的优先级。
比如,两条纪录A和B,满足如下条件:
(1)A.field1 > B.field1,(2)A.field2 < B.field2。
这时如果按照order by field1, field2语句排序,那么 A > B。
如果上述条件中的(1)A.field1 > B.field1变化为A.field1 == B.field1。这时,条件(2)就会起作用。这时,A < B。

我们来看看在Java中如何实现这种灵活而强大的排序。
我们还是以上一节的Record类为例。Record类有3个字段,我们来看一看,有多少种可能的排序条件。
(1)按field1排序。(2)按field2排序。(3)按field3排序。(4)按field1,field2排序。(5)按field1升序,按field2降序排序…...

各种排序条件的排列组合,大概共有30种。而且,随着字段个数的增长,排序条件的个数呈幂级数的增长。
按照上一节的sort和Comparator方法,如果我们需要达到按照任意条件进行排序的目的,那么我们需要为每一个排序条件提供一个Comparator,我们需要30个Comparator类。:-)

当然,我们不会这么做,我们能够进一步提取这个问题中的相同重复部分,优化我们的解决方案。

3.2 问题分析
我们来分析这个问题中变化的部分和不变的部分。
上面所有的排序条件中,不变的部分有3部分:
(1)A.field1和B.field1的比较,
(2)A.field2和B.field2的比较,
(3)A.field3和B.field3的比较;

变化的部分有两部分,
(1)这三种比较条件的任意组合排列,
(2)升序和降序。

根据这段分析,我们引入两个类,ReverseComparator类和CompositeComparator类。
CompositeComparator类用来解决字段的组合排列问题。
ReverseComparator类用来解决字段的升序、降序问题。

3.3 ReverseComparator类的代码

import java.util.Comparator;

public class ReverseComparator implements Comparator{
/** the original comparator*/
private Comparator originalComparator = null;

/** constructor takes a comparator as parameter */
public ReverseComparator(Comparator comparator){
originalComparator = comparator;
}

/** reverse the result of the original comparator */
public int compare(Object o1, Object o2){
return - originalComparator.compare(o1, o2);
}
}


3.4 CompositeComparator类的代码

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;

public class CompositeComparator implements Comparator{
/** in the condition list, comparators' priority decrease from head to tail */
private List comparators = new LinkedList();

/** get the comparators, you can manipulate it as need.*/
public List getComparators(){
return comparators;
}

/** add a batch of comparators to the condition list */
public void addComparators(Comparator[] comparatorArray){
if(comparatorArray == null){
return;
}

for(int i = 0; i < comparatorArray.length; i++){
comparators.add(comparatorArray[i]);
}
}

/** compare by the priority */
public int compare(Object o1, Object o2){
for(Iterator iterator = comparators.iterator(); iterator.hasNext();){
Comparator comparator = (Comparator)iterator.next();

int result = comparator.compare(o1, o2);

if(result != 0){
return result;
}
}

return 0;
}
}


3.5 Comparator的组合应用
这一节讲述上面两个类的用法。
对应前面的排序问题,我们只需要3个Comparator类:
(1)Field1Comaprator;
(2)Field2Comaprator;
(3)Field3Comaprator。

下面举例说明,如何组合这些Comparator实现不同的排序条件。
(1)order by field1, field2


CompoiComparator myComparator = new CompoiComparator();
myComparator. addComparators(
new Comparator[]{
new Field1Comaprator (), new Field2Comaprator ()};
);

// records is a list of Record
Collections.sort(records, myComparator);

(1)order by field1 desc, field2

CompoiComparator myComparator = new CompoiComparator();
myComparator. addComparators(
new Comparator[]{
new ReverseComparator(new Field1Comaprator ()),
new Field2Comaprator ()};
);

// records is a list of Record
Collections.sort(records, myComparator);



这里提供的ReverseComparator类和CompositeComparator类都采用了Decorator Pattern。
CompositeComparator类同时也是Composite Pattern。

4.过滤条件的排列组合
过滤条件问题也属于条件组合问题的范畴。比如JDK提供的java.io.File类提供了一个文件过滤方法listFile(FileFilter),用户可以定制不同的FileFilter,实现不同的过滤条件,比如文件时间在某个范围内;文件后缀名,文件名符合某种模式;是目录,还是文件,等等。
同样,我们可以应用上述的解决方法,实现灵活的过滤条件组合――用一个CompositeFilter类任意组合过滤条件,用一个ReverseFilter类作为排除条件。

4.1 CompositeFilter类的代码

import java.io.FileFilter;
import java.io.File;

import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;

public class CompositeFilter implements FileFilter {

/** in the filter list, every condition should be met. */
private List filters = new LinkedList();

/** get the filters, you can manipulate it as need.*/
public List getFilters(){
return filters;
}

/** add a batch of filters to the condition list */
public void addComparators(FileFilter[] filterArray){
if(filterArray == null){
return;
}

for(int i = 0; i < filterArray.length; i++){
filters.add(filterArray[i]);
}
}

/** must meet all the filter condition */
public boolean accept(File pathname) {
for(Iterator iterator = filters.iterator(); iterator.hasNext();){
FileFilter filter = (FileFilter)iterator.next();

boolean result = filter.accept(pathname);

// if any condition can not be met, return false.
if(result == false){
return false;
}
}

// all conditions are met, return true.
return true;
}
}


4.2 ReverseFilter类的代码


import java.util.Comparator;

public class ReverseComparator implements Comparator{
/** the original comparator*/
private Comparator originalComparator = null;

/** constructor takes a comparator as parameter */
public ReverseComparator(Comparator comparator){
originalComparator = comparator;
}

/** reverse the result of the original comparator */
public int compare(Object o1, Object o2){
return - originalComparator.compare(o1, o2);
}
}

Re: 这么多设计模式,我的看法和理解 2004年07月09日 18:36 到本帖网址
Design Pattern Practice

1.序
本文从一个简单的多列排序的例子入手,由浅入深地讲解Design Pattern(设计模式)的目的、分析和实践。
文中的例子用到Compositor Pattern和Decorator Pattern。
同时,文中的例子也提供了一类问题(条件组合问题)的解决方案。

2.问题的引入
Design Pattern(设计模式)的目标是,把共通问题中的不变部分和变化部分分离出来。不变的部分,就构成了Design Pattern(设计模式)。这一点和Framework(框架)有些象。
下面举个排序的例子,说明如何抽取问题中的不变部分。
假设一个Java类Record有field1,field2,field3等字段。


public class Record{
public int field1;
public long field2;
public double filed3;
};


我们还有一个Record对象的数组Record[] records。我们需要对这个数组按照不同的条件排序。
首先,按照field1的大小从小到大进行升序排序。
排序函数如下:


void sort(Record[] records){
for(int i =…){
for(int j=…){
if(records[ i ].field1 > records[ j ].field1)
// swap records[ i ] and records[ j ]
}
}
}


其次,按照field2的大小从小到大进行升序排序。

void sort(Record[] records){
for(int i =…){
for(int j=…){
if(records[ i ].field2 > records[ j ].field2)
// swap records[ i ] and records[ j ]
}
}
}


再次,按照field3的大小从小到大进行升序排序。
...
这种要求太多了,我们写了太多的重复代码。我们可以看到,问题的变化部分,只有判断条件部分(黑体的if条件判断语句)。
我们可以引入一个Comparator接口,把这个变化的部分抽取出来。

public interface Comparator(){
public boolean greaterThan(Record a, Record b);
};


sort函数就可以这样写(把判断条件作为参数):


void sort(Record[] records, Comparator compare){
for(int i =….){
for(int j=….){
if(compare.greaterThen(records[ i ], records[ j ]))
// swap records[ i ] and records[ j ]
}
}
}


这样,对应第一个要求――对records数组按照field1的大小排序。
我们可以做一个实现Comparator接口的CompareByField1类。


public class CompareByField1 implements Comparator{
public boolean greaterThan(Record a, Record b){
if(a.filed1 > b.filed1){
return ture;
}
return false;
}
}


sort函数的调用为:

sort(records, new CompareByField1());


这样,对应第一个要求――对records数组按照field2的大小排序。
我们可以做一个实现Comparator接口的CompareByField2类。

public class CompareByField2 implements Comparator{
public boolean greaterThan(Record a, Record b){
if(a.filed2 > b.filed2){
return ture;
}
return false;
}
}
[code]

sort函数的调用为:
[code]
sort(records, new CompareByField2());


按照C++ STL的叫法,这里的sort称为算法(Algorithm),records称为容器(集合),Comparator称为函数对象(Function Object)。

JDK的java.util.Collections类的sort方法和java.util.Comparator接口就是按照这样的思路设计的。下面我们来看看如何应用sort和Comparator解决多列排序问题。


Re: 高手能否能给初学者讲讲动态代理? 2004年07月09日 18:14 到本帖网址
动态代理的基本机制:在运行期间,(Byte Code Instrument)动态生成Byte Code,动态生成Java类。

我所知道的Class Byte Code操作工具实现有2种:

BCEL 按照DOM结构方式操作Byte Code。
http://jakarta.apache.org/bcel/index.html

ASM 按照SAX方式(Visitor模式)操作Byte Code。
http://asm.objectweb.org/

有了Byte Code操作工具,就可以在运行期间动态生成代理类了。
cglib就是这样一个动态代理类的生成工具。
http://cglib.sourceforge.net/

cglib能够生成多种丰富的动态代理类。

JDK1.4引入了动态代理类的简单实现(只提供一种代理类)。
包括java.lang.reflect包的Proxy类和InvocationHandler类这两个标准的API。操作Byte Code的具体类是sun.misc.ProxyGenerator类。

Sun JDK 源代码下载:
http://wwws.sun.com/software/communitysource/
先注册并登录到“Sun Community Source Licensing”,然后下载J2SE(几十兆)或者J2EE(几百兆)。

动态代理是实现AOP的一种流行的方法。
关于JDK1.4 Proxy的具体用法。这里不再赘述。下面有些中文文章。

Banq的文章。
http://www.jdon.com/AOPdesign/spring.htm

还有:
http://www-900.ibm.com/developerWorks/cn/java/l-connpoolproxy/index.shtml


Re: 如何读取并显示服务器上不在webapp目录上的图片? 2004年07月09日 16:27 到本帖网址
(我上面发的贴子不能正确显示,请删除。这里再发一遍)

我知道一种在Tomcat中的一种方法。

server.xml里面有如下行。


<Context path="/myweb" docBase="/webapp" crossContext="true"/>
<Context path=
"" docBase="/wwwroot" crossContext="true" />


其中,/webapp是动态内容(Web应用程序)目录。
/wwwroot是静态图片和文件的目录。
假设有/wwwroot/images/Logo.gif文件。

在/webapp/home.html文件中,包括如下代码。

<img src="/images/Logo.gif"/>

用户访问/webapp/home.html的时候,浏览器可以正确显示出/wwwroot/images/Logo.gif.

做项目的时候,大家都这么用。
我们的开发环境是Tomcat,发布环境是WebLogic。
显然,WebLogic也支持这种配置方式。应该是Web Server的一种普遍支持。

但具体原理我还不是很清楚。
也没有找到Tomcat文档中相应的部分。敬请指点。

Re: 如何读取并显示服务器上不在webapp目录上的图片? 2004年07月09日 16:20 到本帖网址
我知道一种在Tomcat中的一种方法。

server.xml里面有如下行。

<Context path="/myweb" docBase="/home/webapp" crossContext="true" />
<Context path="" docBase="/wwwroot" crossContext="true"/>

其中,/home/webapp是动态内容(Web应用程序)目录。
/wwwroot是静态图片和文件的目录。

在/wwwroot/images目录下,有很多图片文件,比如Logo.gif。

在/home/webapp/下有一个home.html.
<img src="/images/Logo.gif"/>

就可以显示出/wwwroot/images/Logo.gif.

但是做项目的时候,大家都这么用。
我们的开发环境是Tomcat,发布环境是WebLogic。
显然,WebLogic也支持这种配置方式。应该是Web Server的一种普遍支持。

具体原理我还不是很清楚。
也没有找到Tomcat文档中相应的部分。敬请指点。

Re: 有谁可以给我一个解析html包 最好负例子 2004年07月09日 16:03 到本帖网址
NekoHTML(http://www.apache.org/~andyc/neko/doc/html/)是一个HTML文档解析工具。
NekoHTML使用Apache Xerces(http://xml.apache.org/xerces2-j/index.html)的Xerces Native Interface对HTML文档进行解析,能够自动补足并修正不符合XML文法的HTML元素,并生成HTML DOM文档树。
Apache Xcerse的XPathAPI,可以用XPath方便地定位DOM结构的结点。
DOM + XPath的详细用法请参见NekoHTML的使用文档。

还有一种方法是SAX+Filter比较难以理解,不易上手。
使用SAX+Filter的步骤:
1.建立自己的Filter,实现org.apache.xerces.xni.parser.XMLDocumentFilter接口。
参见org.cyberneko.html.filters包。
2.创建org.cyberneko.html.parsers.SAXParser。调用
parser.setFeature("http://cyberneko.org/html/features/balance-tags", false); // optional
XMLDocumentFilter[] filters = new XMLDocumentFilter[]{myFilter, writer}; // create filters
parser.setProperty("http://cyberneko.org/html/properties/filters", filters); // set filters
parser.parse(…);


符合查询结果共有18Go 1 2