随笔-124  评论-194  文章-0  trackbacks-0
 

 

完整文章在这里

 

文章写得比较易懂清晰,最后倾向于用HTTP Invoker,是轻量级的易于安装而灵活的方案,但它只在通信两边都是SPRING时适用。

 

要点如下:

每一种远程技术都有其优点与不足,表格1对它们进行了简单的对比。

按框架 优点 缺点分述如下:

RMI

全面支持Java对象串行化。因此,你能够通过网络发送复杂数据类型。

RMI仅是一种Java到Java型远程方案。如果你拥有任何非Java客户端的话,那么你无法使用它。另外,你还无法通过HTTP协议存取对象,除非你有专门的“通道”实现RMI通讯。注意,它需要一个RMI编译器(为了生成代理和框架)和一个外部注册表(用于查询服务)。

Hessian/Burlap

跨防火墙工作良好

它们使用一种专利对象串行化机制。其中,Burlap仅支持Java客户端。它们能够串行化Hibernate对象,但是对集合对象执行“惰式”加载。

HTTP Invoker

基于HTTP的Java到Java Remoting;通过HTTP实现Java串行化;容易建立。

服务器和客户端应用程序都需要使用Spring。

仅是一种Java方案。

EJB

支持Remoting J2EE服务,应用程序安全以及事务处理

EJB是一种重量级技术。它要求使用一个J2EE容器。

Web服务

平台和语言独立

要付出SOAP操作所带来的开销,并且要求使用一个Web服务引擎。

表格1:各种Spring Remoting技术优缺点比较

如你所见,每一种Spring Remoting技术都有各自的优缺点,但是大多数实际的应用程序都会要求使用一种轻量级Remoting技术。当实现远程服务时,使用例如EJB这样的重量级远程组件模型需要其它额外的开销。通常情况下,使用一种支持对象串行化能力的HTTP服务就足够了。

posted @ 2007-06-08 18:53 我爱佳娃 阅读(837) | 评论 (0)编辑 收藏

被强制更新了ie7,英文字体非常不心惯,可以通过以下方法恢复:

 

关闭cleartype的效果:
工具-internat选项-高级-多媒体-总是将cleartype应用于html,把钩去掉。

posted @ 2007-06-05 17:27 我爱佳娃 阅读(568) | 评论 (0)编辑 收藏

最近通过搜索发现建立TreeV3时候,方便的加载图标方法:在这里

 

但是有个问题,想在程序里动态修改它却没有函数,经过研究代码发现可以用如下简单方法实现:

取得之前定义的TreeDocIconExtension的引用:

var treeicons = dojo.widget.manager.getWidgetById("phyTreedocIcons");

 

改变TreeNodeV3的TYPE值为CSS文件定义过的项目:

node.nodeDocType = 3;

 

最关键是要去刷新iconNode的innerHTML,调用如下:

treeicons.setnodeDocTypeClass (node);

 

已经实验通过。这样就可以方便的根据后台数据刷新节点状态,而不必重建树节点。

posted @ 2007-06-02 12:06 我爱佳娃 阅读(1300) | 评论 (0)编辑 收藏

转录自:这里

并实验通过。

 

TreeV3支持节点图标, 因为和老版本的使用方式大相径庭, 而且没有文档, 所以给升级到V3的developer造成一定的困扰. 我利用google, 并分析了源代码后找到了方法.
在TreeV3中加入图标的方法如下:

首先定义一个widget:
<div dojoType="TreeDocIconExtension" widgetId="docIcons"></div>

并给tree加入一个名为"docIcons"的listener:
<div dojoType="TreeV3" listeners="link;selector;docIcons;treeController;menu">

在定义节点时需要加入一个属性"nodeDocType", 如:
<div dojoType="TreeNodeV3" title="nodetitle" nodeDocType="nodetype1" ></div>

最后给每一个nodedoctype定义一个名为".TreeIconXXXX"的style, 这里的XXXX就是给节点定义的nodeDoctype的名字:
<style>
.TreeIconnodetype1{
background-image: url('icon.gif');
}
</style>

posted @ 2007-06-01 17:37 我爱佳娃 阅读(1717) | 评论 (1)编辑 收藏

$self->{net_server}就是Multiplex,为了能够实现多态调用(在父类中调用实现子类的方法,PERL中使用SUPER实现),又定义了:

Net::Server::Multiplex::MUX

每有一个新连接,会NEW一个这样的对象进行管理。

 

而封装的IO::Multiplex对象是存在:$self->{net_server}->{mux}中。

posted @ 2007-05-29 11:11 我爱佳娃 阅读(324) | 评论 (0)编辑 收藏

Jetty启动后,如果修改javascript文件,将不能保存,使调试很麻烦。这是因为使用了CACHE,JETTY说是WINDOWS下的一个限制。可以通过如下方法修正:

 

解压出jetty.jar中的org/mortbay/jetty/webapp/webdefault.xml文件,将这一选项由true改为false,另存到src/main/resources目录,或者其它自选目录。

<init-param> <param-name>useFileMappedBuffer</param-name> <param-value>true</param-value> <!-- change to false --> </init-param>

 

在pom.xml中加入对这个文件的指向:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<webDefaultXml>src/main/resources/webdefault.xml</webDefaultXml>
</configuration>
</plugin>

 

本人已经验证通过。

 

问题描述,点这里

posted @ 2007-05-27 16:50 我爱佳娃 阅读(5612) | 评论 (0)编辑 收藏
随着AJAX的普遍应用,客户端的开发也要走向面向对象,面向模式的开发范畴。
看到一篇文章(附文链接见后),着重归纳一种开发模式:

一页就是一个“应用程序”,一个系统可能有好几个这样的应用程序;
用JSF或者STRUTS形成各“应用程序”的第一页;
其中,每一页含有:
controller.js负责:(这是CONTROLLER)
      接来自页面的调用,通过AJAX封装包(如JSON-RPC或者DWR)调用系统服务;
      因为要异步响应,需要安排CALLBACK;
      在CALLBACK中,调用VIEW及MODEL的维护

datacopy.js负责:(这是MODEL)
      保存数据模型,并由CONTROLLER来更新

render.js负责:(这是VIEW)
      听从CONTROLLER调用,通过取MODEL的数据,建立widgets,刷新页面

原文来自,这里
      
另外,有关JS的面向对象编程<<javascript权威指南>>一书讲的相当不错,我简单的与C++比较了一下,请点这里。
posted @ 2007-05-26 10:56 我爱佳娃 阅读(1352) | 评论 (0)编辑 收藏

多行注释:
perl没有多行注释,可以用下面代替:
=pod
代码行;
.
.
.
代码行;
=cut


关于ref函数:
 ref EXPR
 ref     Returns a non-empty string if EXPR is a reference, the empty
         string otherwise. If EXPR is not specified, $_ will be used. The
         value returned depends on the type of thing the reference is a
         reference to. Builtin types include:

             SCALAR
             ARRAY
             HASH
             CODE
             REF
             GLOB
             LVALUE

         If the referenced object has been blessed into a package, then
         that package name is returned instead. You can think of "ref" as
         a "typeof" operator.



讲类的段落,比较明了:
Object Construction
All objects are references, but not all references are objects. A reference won't work as an object unless its referent is specially marked to tell Perl what package it belongs to. The act of marking a referent with a package name--and therefore, its class, since a class is just a package--is known as blessing. You can think of the blessing as turning a reference into an object, although it's more accurate to say that it turns the reference into an object reference.

The bless function takes either one or two arguments. The first argument is a reference and the second is the package to bless the referent into. If the second argument is omitted, the current package is used.

$obj = { };                 # Get reference to anonymous hash.
bless($obj);                # Bless hash into current package.
bless($obj, "Critter");     # Bless hash into class Critter.
Here we've used a reference to an anonymous hash, which is what people usually use as the data structure for their objects. Hashes are extremely flexible, after all. But allow us to emphasize that you can bless a reference to anything you can make a reference to in Perl, including scalars, arrays, subroutines, and typeglobs. You can even bless a reference to a package's symbol table hash if you can think of a good reason to. (Or even if you can't.) Object orientation in Perl is completely orthogonal to data structure.

Once the referent has been blessed, calling the built-in ref function on its reference returns the name of the blessed class instead of the built-in type, such as HASH. If you want the built-in type, use the reftype function from the attributes module. See use attributes in Chapter 31, "Pragmatic Modules".

And that's how to make an object. Just take a reference to something, give it a class by blessing it into a package, and you're done. That's all there is to it if you're designing a minimal class. If you're using a class, there's even less to it, because the author of a class will have hidden the bless inside a method called a constructor, which creates and returns instances of the class. Because bless returns its first argument, a typical constructor can be as simple as this:

package Critter;
sub spawn { bless {}; }
Or, spelled out slightly more explicitly:
package Critter;
sub spawn {
    my     $self = {};       # Reference to an empty anonymous hash
    bless  $self, "Critter"; # Make that hash a Critter object
    return $self;            # Return the freshly generated Critter
}
With that definition in hand, here's how one might create a Critter object:
$pet = Critter->spawn;

12.4.1. Inheritable Constructors
Like all methods, a constructor is just a subroutine, but we don't call it as a subroutine. We always invoke it as a method--a class method, in this particular case, because the invocant is a package name. Method invocations differ from regular subroutine calls in two ways. First, they get the extra argument we discussed earlier. Second, they obey inheritance, allowing one class to use another's methods.

We'll describe the underlying mechanics of inheritance more rigorously in the next section, but for now, some simple examples of its effects should help you design your constructors. For instance, suppose we have a Spider class that inherits methods from the Critter class. In particular, suppose the Spider class doesn't have its own spawn method. The following correspondences apply:

Method Call Resulting Subroutine Call
Critter->spawn() Critter::spawn("Critter")
Spider->spawn() Critter::spawn("Spider")

The subroutine called is the same in both cases, but the argument differs. Note that our spawn constructor above completely ignored its argument, which means our Spider object was incorrectly blessed into class Critter. A better constructor would provide the package name (passed in as the first argument) to bless:

sub spawn {
    my $class =  shift;       # Store the package name
    my $self  =  { };
    bless($self, $class);     # Bless the reference into that package
    return $self;
}
Now you could use the same subroutine for both these cases:
$vermin = Critter->spawn;
$shelob = Spider->spawn;
And each object would be of the proper class. This even works indirectly, as in:
$type  = "Spider";
$shelob = $type->spawn;         # same as "Spider"->spawn
That's still a class method, not an instance method, because its invocant holds a string and not a reference.

If $type were an object instead of a class name, the previous constructor definition wouldn't have worked, because bless needs a class name. But for many classes, it makes sense to use an existing object as the template from which to create another. In these cases, you can design your constructors so that they work with either objects or class names:

sub spawn {
    my $invocant = shift;
    my $class    = ref($invocant) || $invocant;  # Object or class name
    my $self     = { };
    bless($self, $class);
    return $self;
}

12.4.2. Initializers
Most objects maintain internal information that is indirectly manipulated by the object's methods. All our constructors so far have created empty hashes, but there's no reason to leave them empty. For instance, we could have the constructor accept extra arguments to store into the hash as key/value pairs. The OO literature often refers to such data as properties, attributes, accessors, member data, instance data, or instance variables. The section "Instance Variables" later in this chapter discusses attributes in more detail.

Imagine a Horse class with instance attributes like "name" and "color":

$steed = Horse->new(name => "Shadowfax", color => "white");
If the object is implemented as a hash reference, the key/value pairs can be interpolated directly into the hash once the invocant is removed from the argument list:
sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ };          # Remaining args become attributes
    bless($self, $class);       # Bestow objecthood
    return $self;
}
This time we used a method named new for the class's constructor, which just might lull C++ programmers into thinking they know what's going on. But Perl doesn't consider "new" to be anything special; you may name your constructors whatever you like. Any method that happens to create and return an object is a de facto constructor. In general, we recommend that you name your constructors whatever makes sense in the context of the problem you're solving. For example, constructors in the Tk module are named after the widgets they create. In the DBI module, a constructor named connect returns a database handle object, and another constructor named prepare is invoked as an instance method and returns a statement handle object. But if there is no suitable context-specific constructor name, new is perhaps not a terrible choice. Then again, maybe it's not such a bad thing to pick a random name to force people to read the interface contract (meaning the class documentation) before they use its constructors.

Elaborating further, you can set up your constructor with default key/value pairs, which the user could later override by supplying them as arguments:

sub new {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant;
    my $self = {
        color  => "bay",
        legs   => 4,
        owner  => undef,
        @_,                 # Override previous attributes
    };
    return bless $self, $class;
}

$ed       = Horse->new;                    # A 4-legged bay horse
$stallion = Horse->new(color => "black");  # A 4-legged black horse
This Horse constructor ignores its invocant's existing attributes when used as an instance method. You could create a second constructor designed to be called as an instance method, and if designed properly, you could use the values from the invoking object as defaults for the new one:
$steed  = Horse->new(color => "dun");
$foal   = $steed->clone(owner => "EquuGen Guild, Ltd.");

sub clone {
    my $model = shift;
    my $self  = $model->new(%$model, @_);
    return $self;     # Previously blessed by ->new
}

posted @ 2007-05-24 15:31 我爱佳娃 阅读(8289) | 评论 (2)编辑 收藏

Maven2代比1代改进很多,其中主要强调的是--它不仅仅是个依赖包管理器!
开始先要推荐一个专讲Maven2的电子书给大家,对MAVEN学习相当有助益:Better Builds with Maven  


下面就专门介绍下Maven2对WEBAPP在管理和调试方面的支持。

1.创建项目

mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp

也可参看这里

创建要注意遵循MAVEN的目录结构,尤其要注意源文件要放在main/java下:



2. POM文件的配置

这里要特别注意对resource一节的配置,因为我的SPRING以及WEB相关的XML是放在WEB-INF目录,为了在unit test的时候也能用,加入了对这些配置文件的引用。相当于加了一个classpath。

这里还有个插曲:不知为何MAVEN2里没有JTA的包,自动下载时会有提示教你如何手工通过命令加入,非常简单。

JETTY的plugin是为后面用它来调试做准备。

DWR也是目前WEB开发一个热选。

另外,为使用JAVA5代来编译,加入了maven-compiler-plugin一节。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation
="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  
<modelVersion>4.0.0</modelVersion>
  
<groupId>com.exchangebit.nms</groupId>
  
<artifactId>ebnms</artifactId>
  
<packaging>war</packaging>
  
<version>1.0-SNAPSHOT</version>
  
<name>ebnms Maven Webapp</name>
  
<url>http://maven.apache.org</url>
      
  
<build>
    
<finalName>ebnms</finalName>
    
      
<resources>
        
<resource>
          
<directory>src/main/java</directory>
          
<includes>
            
<include>**/*.xml</include>
          
</includes>
        
</resource>
        
<resource>
          
<directory>src/main/webapp/WEB-INF</directory>
          
<includes>
            
<include>**/*.xml</include>
            
<include>**/log4j.properties</include>
          
</includes>
        
</resource>
      
</resources>
      
      
<plugins>
        
<plugin>
          
<groupId>org.apache.maven.plugins</groupId>
          
<artifactId>maven-compiler-plugin</artifactId>
          
<configuration>
            
<source>1.5</source>
            
<target>1.5</target>
          
</configuration>
        
</plugin>
        
      
<plugin>
        
<groupId>org.mortbay.jetty</groupId>
        
<artifactId>maven-jetty-plugin</artifactId>
      
</plugin>        
  
      
</plugins>
    
</build>    
      
  
<dependencies>
    
<dependency>
      
<groupId>junit</groupId>
      
<artifactId>junit</artifactId>
      
<version>3.8.1</version>
      
<scope>test</scope>
    
</dependency>
        
    
<dependency>
      
<groupId>org.hibernate</groupId>
      
<artifactId>hibernate</artifactId>
      
<version>3.1</version>
    
</dependency>
    
    
<dependency>
      
<groupId>log4j</groupId>
      
<artifactId>log4j</artifactId>
      
<version>1.2.11</version>
    
</dependency>
    
<dependency>
      
<groupId>mysql</groupId>
      
<artifactId>mysql-connector-java</artifactId>
      
<version>3.1.11</version>
      
<scope>runtime</scope>
    
</dependency>
    
<dependency>
      
<groupId>javax.servlet</groupId>
      
<artifactId>servlet-api</artifactId>
      
<version>2.4</version>
      
<scope>provided</scope>
    
</dependency>
    
<dependency>
      
<groupId>javax.servlet</groupId>
      
<artifactId>jstl</artifactId>
      
<version>1.1.2</version>
      
<scope>runtime</scope>
    
</dependency>
    
<dependency>
      
<groupId>taglibs</groupId>
      
<artifactId>standard</artifactId>
      
<version>1.1.2</version>
      
<scope>runtime</scope>
    
</dependency>
    
<dependency>
      
<groupId>org.springframework</groupId>
      
<artifactId>spring</artifactId>
      
<version>1.2.6</version>
    
</dependency>
        
    
<dependency>
      
<groupId>dwr</groupId>
      
<artifactId>dwr</artifactId>
      
<version>1.1.3</version>
    
</dependency>        
  
</dependencies>
  
</project>


代码放入/main/java后,可以在项目目录下执行:
mvn compile来做编译尝试,
也可以用mvn war直接生成打包文件,
当然最后可以用 mvn jetty:run来运行你的WEBAPP!


3.  在Eclipse中配置jetty进行调试
要把之前的项目导入Eclipse首先让maven为我们生成Eclipse工程文件,执行:
mvn eclipse:eclipse
再把M2_REPO加入到Eclipse的classpath中,有两种方法,其中的b)方法是有效的:
a) mvn -Declipse.workspace=<path-to-eclipse-workspace> eclipse:add-maven-repo
b) Window > Preferences. Select the Java > Build Path > Classpath Variables page


之后,就可以通过Eclipse的File->Import功能将工程导入。


有人为了使用WEBAPP开发功能,而装象MYECLIPSE这样的巨物。有了JETTY,通过轻松配置就可以实现比TOMCAT更快更便捷的容器,所以在调试时强力推荐这个东东。下面就来看下如何配置。

先下配置一个外部工具,来运行JETTY:
选择菜单Run->External Tools->External Tools ...在左边选择Program,再点New:
配置Location为mvn完整命令行。

选择Working Directory为本项目。

Arguments填写:jetty:run

再点选Enviroment页:加入MAVEN_OPTS变量,值为:
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y
其中,如果suspend=n 表示不调试,直接运行。

然后,点APPLY,再关闭本对话框。
另外注意一点,好像external tool菜单项在java browering的perspective下才会出现。如果在java下看不见,可以切换下试试。



下面新建运行配置:
点选run->debug...
选中左树中的Remote Java Application,再点New。
选择你的项目,关键是要填和之前设置外部工具时相同的端口号。





配置就完成了,正面开始调试运行:
首先要把JETTY运行起来(有点象TOMCAT里的运行APPSERVER),从Run->External Tools中选择之前配置的外部工具运行,这时LOG里会显示:
listening at port 4000字样,
再选择Run->Debug选择我们刚建的运行配置,这时程序就RUN起来了,可以通过WEB进行访问,设置断点调试了。



后记:
在ECLIPSE中,有更方便高效的调试方式,点这里
posted @ 2007-05-19 23:08 我爱佳娃 阅读(25786) | 评论 (4)编辑 收藏

STEP 3:配置
打开/conf/目录,打开svnserve.conf找到一下两句:


# [general]
# password-db = passwd

去之每行开头的#,其中第二行是指定身份验证的文件名,即passwd文件
同样打开passwd文件,将

# [users]
# harry = harryssecret
# sally = sallyssecret

这几行的开头#字符去掉,这是设置用户,一行一个,存储格式为“用户名 = 密码”,如可插入一行:admin = admin888,即为系统添加一个用户名为admin,密码为admin888的用户

 

create it:
sc create svnservice binpath= "\"c:\program files\Subversion\bin\svnserve.exe\" --service -r D:\svn" displayname= "SVNService" depend= Tcpip

delete it:
sc delete svnservice



mysql:
 C:\> mysqld-nt --install
   C:\> NET START MySql

  C:\> NET STOP MySql
   C:\> mysqld-nt --remove


posted @ 2007-05-16 22:38 我爱佳娃 阅读(608) | 评论 (0)编辑 收藏
仅列出标题
共13页: First 上一页 5 6 7 8 9 10 11 12 13 下一页