随笔-31  评论-257  文章-0  trackbacks-0
 
Smarty 的配置文件

      开发人员一直使用配置文件来存储确定应用程序行为和操作的数据。例如,php.ini 文件负责确定PHP的大量行为。对于Smarty ,模板设计人员也可以利用配置文件的强大作用。例如,设计人员可以使用配置文件存储页面标题、用户消息以及有必要集中存储的任何信息。
      以下是一个示例配置文件 (名为 app.config):

#Global Variables
appName = "PMNP News Service"
copyright = "Copyright 2005 PMNP News Service, Inc."

[Aggregation]
title = "Recent News"
warning = "Copyright warning.Use of this information is for personal use only."

[Detail]
title = "A Closer Look..."

      中括号中包围的项称为节(section)。节之外的项都认为是全局的。这此项应当在定义任何节之前定义。
     
    下面将展示如何使用config_load 函数来加载配置文件,还会解释如何在模板中引用配置变量。
    配置文件存储在 configs 目录中,并使用Smarty函数 config_load 加载。下面是加载配置文件 app.config 的示例:
    {config_load file="app.config"}
但是要记住,此调用只能加载配置文件的全局变量。如果要加载特定的节,需要使用 section 属性指定。所以,可以使用以下语法加载 app.config 的节 Aggregation:
      {config_load file="app.config" section="Aggregation"}
      另外两个可选参数介绍如下:
    scope:确定所加载的配置变量的作用域。默认情况下设置为local,表示变量只能用于本地模板。其它可能的设置包括 parent 和 global 。作用域设置为 parent 时,变量可用于本地模板和调用模板。作用域设为global 时,变量则可以用于所有模板。
    section:指定加载配置文件的特定节。因此,如果只对某个特定节感兴趣,可以只加载该节,而非整个文件。

引用配置变量

      配置文件中变量的引用方式与其它变量的引用方式有所不同。实际上,这些配置变量使用几种不同的语法来引用,下面将介绍这个内容。
    1、#
      在 Smarty 模板中,可以在变量前面加上#号来引用配置变量。例如:
      {#title}
      2、Smarty的$smarty.config变量
    引用配置变量时,如果喜欢更为正式的语法,可以使用 Smarty 的 $smarty.config 变量。例如:
      {$smarty.config.title}
      3、get_config_vars() 方法
    array get_config_vars([string variablename])
      get_config_vars() 方法返回一个数组,包含加载的所有配置变量值。如果只对某个变量值感兴趣,可以通过 variablename 传入该变量。例如,如果只对以上 app.config  配置文件中 Aggregation 节的 title 感兴趣,可以首先使用 config_load 函数加载该节:
      {config_load file="app.config" section="Aggregation"}
然后,在模板中启用PHP的节中调用 get_config_vars( ),如下:
      $title = smarty->get_config_vars("title");
当然,无论选择哪一种获取配置参数的语法,都不要忘记首先使用 config_load 函数加载配置文件。
posted @ 2008-07-29 13:51 姜大叔 阅读(319) | 评论 (0)编辑 收藏
Smarty 的表现逻辑

      第一编文章中,只简单的讲述了Smarty里的基本原理,也就传几个变量的值而已,而本节中,将会讲述Smarty的逻辑表示结构,比如它的分支,修饰符,迭代等结构的表达。

     (1) 注释:

      中Smarty中,也可以使用注释,设计人员可以用注释在模板页面中传递一些说明信息等。在Smarty中的注释为:{* Hello Jiang! *},大家可以看到,Smarty中的注释是用{**}来包围的,可以单行,也可以多行,比如可以这样写:
      {* Hello
           Jiang! *}

     (2)变量修饰符:

      在Smarty中,可以为变量添加修饰符,用于对变量进行一些Smarty已定义好的操作,变量修饰符的写法是:
      {$var|modifier}
其中,$var 是变量,modifier 是修饰符的单词,意为对指定变量进行某种修饰操作。

      1、capitalize 修饰符
      capitalize 修饰符用于对变量内的值中所有单词的首字母变为大写,可看示例:
      $smarty = new Smarty;
      $smarty->assign("$title","hello jiang zone");
      $smarty->display("index.tpl");

index.tpl 内容为:
      {$title|capitalize}

      2、count_words
      count_words 函数统计变量中的单词总数

      3、date_format
      date_format 函数是PHP strftime() 函数的包装器,它能将可以被strftime()解析的任何日期/时间格式字符串转换为某种特殊格式。

      4、default
      default 函数当应用层没有返回值时,default为指示特定变量的默认值提供了一种简单的方式。

      5、strip_tags
      strip_tags 函数删除变量字符串中的标签符号。如:
      $smarty->assign("name","<b>Jiang</b>");
      模板里这样写:{$name|strip_tags}
      会输入如下name的值:"Jiang",它将<b></b>删除了。所以,没有输出粗体

      6、truncate
      truncate 函数将变量字符串截取为指定数量的字符。]


      (3)控制结构

      1、if-elseif-else
      Smarty 的if语句与PHP语言中的if语句相同,与PHP一样,可以使用一些条件限定符如下:
      eq            gt            gte            ge
      lt              lte            le              ne
      neq          is even     is not even   is odd
      is not odd  div by     event by    not
      mod         odd by      ==            !=
      >              <              <=            >=
示例:
      {if $var > 5}
          <p>Hello JiangZone</p>
      {/if}

      2、foreach
      foreach 标记的作用与PHP语句中的命令相同。但如下所示,其语法大不相同。它有4个参数,其中两个是必要的:
      form : 这个必要参数指定目标数组的名。
      item : 这个必要参数指定当前元素的名。
      key : 这个可选参数指定当前键的名。
      name : 这个可选参数指定节的名。这个名是任意的,应当设置为一个描述性的名字。
看看如下例子:
require("Smarty.class.php");
$smarty = new Smarty;
$daysofweek = array("Mon","Tues","Weds","Thu","Fri","Sat","Sun");     
$smarty->assign("daysofweek",$daysofweek);
$smarty->display("daysofweek.tpl");     

以下是daysofweek.tpl模板文件:
{foreach from=$daysofweek item=$day}
      {$day}<br />
{/foreach}

      3、foreachelse
      foreachelse 标记与 foreach 一起使用,与用于字符串的 default 标记作用类似,数组为空时 foreachelse 标记可以生成某个候选结果。以下是一个使用 foreachelse 的模板示例:
{foreach key=key item=item from=$titles}
      {$key}: {$item}<br />
{foreachelse}
      <p>No states matching your query were found.</p>
{/foreach}
注意,foreachelse 不使用结束括号:它嵌入到foreach中,这与elseif嵌入到if语句中很类似。


      (4)语句
      Smarty 提供了几个用于完成特殊任务的语句。
      1、include
      include语句与PHP包中的同名语句相同,只是它只用于将其它模板导入到当前模板。例如,假设希望在Smarty模板中导入两个文件,header.tpl 和 footer.tpl ,可以如下完成:
{include file="header.tpl"}
{include file="footer.tpl"}

      2、insert
      insert 标记与 include 标记的功能相同,只是它要导入不会被缓存的数据。例如,可以使用这个函数插入经常更新的数据,如股票价格,天气预报或其它在很短时间内就要改变的内容。它也接受几个参数,一个是必要的,另外三个是可选的:
      name : 这个必要参数确定insert函数的名。
      assign : 这个可选参数可用于将输出给变量,而不是直接发送到输出。
      script : 这个可选参数可以指向在导入文件前直接执行的一个PHP脚本。当输出文件的内容依赖于脚本所完成的某个特定动作时,可以使用此参数。例如,可以执行一个PHP脚本,返回某个默认的股票价格放在不可缓存的输出中。
      var : 这个可选参数用于传入所有插入模板使用的其它参数。可以通过这种方式传递很多参数。

      3、literal
      literal 标记告诉Smarty :标记中嵌入的任何数据都应当原样输出,不需要转换。这个标记量常用于在模板中嵌入JavaScript 和CSS ,从而不需要担心与 Smarty 的定界符冲突。

      4、php
      可以使用php函数在模板中嵌入PHP代码。{php}{/php}标记中的任何代码都由PHP引擎处理。
posted @ 2008-07-29 13:49 姜大叔 阅读(374) | 评论 (0)编辑 收藏
      其实本人也正在学PHP,所以就把学习PHP时的心得体会与所学到的知识分享一下吧,所以这一系列教程(或者是心得吧),将围绕在初学PHP过程中遇到的问题和需要注意的地方。
      这是关于PHP中Smarty模板技术的第一编,为什么要说模板技术呢?原因很简单,如果你想做一个合格的PHP程序员的话,如果你想开发一个结构合理、移植方便的系统的话,那就要留意一下PHP的模板技术,而在PHP的模板技术中,Smarty是一个不错的选择。
      使用模板化主要有两个原因:1、可以使用同样的代码基为不同的目标生成数据。2、应用程序设计人员(负责创建和维护界面的人)可以与应用程序开发人员独立工作,因为用表现和逻辑并非密不可分地纠缠在一起。但模板化引擎如何完成这种分离?有趣的是,大多数实现的做法与编程语言非常相似,为完成各种与界面有关的任务提供了良好的定义的语法和命令集。
      Smarty提供了很多强大的功能。
      1、强大的表现逻辑
      2、模板编译
      3、缓存
      4、高度可配置和可扩展
      5、安全

      如何使用Smarty?
      使用Smarty与使用其它任何类库一样。对于初学者,只需要在执行脚本中使Smarty类库可用。实现这一点非常容易,使用  require()  语句即可:
      require("Smarty.class.php");
之后,就可以实例化Smarty类:
      $smarty = new Smarty;
现在,就可以用Smarty来做东西了。下面看看一个小例子:
以下是模板文件 index.tpl :
 1 <html>
 2     <head>
 3         <title>{$title}</title>
 4     </head>
 5     <body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080" alink="#ff0000">
 6         <p>
 7         Hi,{$name}.Welcome to the wonderful world of Smarty.
 8         </p>
 9     </body>
10 </html>

以下是PHP页面方面代码  index.php:
<?php
    
require('Smarty.class.php');
    
$smarty = new Smarty;
    
$smarty->assign("name","JiangZone");
    
$smarty->assign("title","Jiang's Blog");
   
    
$smarty->display("index.tpl");
?>


从以上两段代码可以看得到,index.tpl文件是页面文件,没有业务逻辑代码,只有{$name},{$title},初学者可能觉得怪,不过如果有Java基础的话,应该看得出,它跟Jsp的EL表达式有点类似,或者跟标签库功能有点像。这样看上去,页面跟程序逻辑就分开来了,设计师专注于他的页面设计,需要放入处理后的值的话,就加上个{$name}等标记,而程序员则专注于程序逻辑的实现,将处理结果放到模板页面那里相应的变量位置。明眼人可能很快看得出,上面PHP代码里,$smarty->assign("name","JiangZone");就是一个对模板赋值的过程,意为为模板中的变量$name 的值设为字符串“JiangZone”,下面的也是一样,而最后那句,$smarty->display("index.tpl");则是将上面设置好的值应用到index.tpl模板上,并将应用后的结果输出到客户端。
posted @ 2008-07-29 13:46 姜大叔 阅读(503) | 评论 (0)编辑 收藏
      我在初学PHP期间,学了点入门文章,学了学语法,就想做点小东西来练练手,做什么好呢?就做个购物车吧,页面都做好了,现在正写代码进去,测试运行,但有个小问题,我在产品列表里明明是选了几个产品的,即是选中了几个 Checkbox ,checkbox 的名字都是"prodno" 但怎么在PHP里用 $_POST['prodno'] 来获取它的值,总是只获取到最后的那个checkbox 的值,为什么?检查了form几遍,没有错误,再检查了PHP几遍,也没错啊[loo](其实是checkbox里的name错了,当时不知道PHP要这样),郁闷了,我以前做Java都是这样写的呀,有什么问题?做ASP时,也是这样写也没错呀,问题出在哪呢?
      后来用 is_array($_POST['prodno']) 得到的是false,不会吧,PHP不会获取重复名字的表单?唉,后来上网Google了一翻,原来PHP里获取重复名字的表单值跟JSP/ASP等的都不一样,JSP的直接用 request.getParameterValues("prodno"); 返回的是一个String[] 数组,但PHP的差别在于,要将form里的 checkbox 的 name 写成: prodno[] 就是要多了后面那对方括号,之后PHP里 $_POST['prodno'] 获得的就是一个 array ,唉,这样都行,不过后来想想,这个可能跟PHP的一个语法有关吧,在PHP里,数组是可以这样赋值的:

      $arr[] = 'aaa';
      $arr[] = 'bbb';
      $arr[] = 'ccc';

      这样写的话,$arr 里就有三个值,key分别是0,1,2,而value分别是'aaa','bbb','ccc',
就是说在PHP里,你给数组赋值的话,不写key的话,他会默认用递增的数字来自动当key,所以,当表单提交到PHP里时,实际上就是

      $prodno[] = 'a';
      $prodno[] = 'b';

      所以,当 $_POST['prodno'] 的值就是$prodno 的值,所以它是一个数组,
而如果表单里name的值写成 prodno 的话,就会是

      $prodno = 'a';
      $prodno = 'b';

      所以,大家可以看得出问题所在了,这样$prodno的值始终会给最后的那个值覆盖,所以就出现我之前的现像我用$_POST['prodno']获取到的值总是我最后的那个checkbox的值,所以更不用说is_array()了,当然是得到false了。
所以,对于一些有其它编程语言基础的人来说,学PHP的话,要注意这点,跟别的语言都不同。
posted @ 2008-07-29 13:45 姜大叔 阅读(1366) | 评论 (2)编辑 收藏
本文讨论的是如何彻底杜绝warning: Cannot add header information - headers already sent in......  这种令人莫明其妙的的错误。

只要你写过PHP代码,相信都遇上过这个大多时候都令人莫明其妙的warning吧..今天我们就来搞定它...............

看了PHP手册,回答如下:

消息“Warning: Cannot send session cookie - headers already sent。。。”或者“Cannot add header information - headers already sent。。。”。

函数 header(),setcookie() 和 session 函数需要在输出流中增加头信息。但是头信息只能在其它任何输出内容之前发送。在使用这些函数前不能有任何(如 HTML)的输出。函数 headers_sent() 能够检查您的脚本是否已经发送了头信息。请参阅“输出控制函数”。

意思是:不要在使用上面的函数前有任何文字,空行,回车,空格等。但。。。问题是,这答案并不令人满意。因为往往程序在其他PHP环境下运行却正常。
 

首先:这错误是怎么产生的呢?让我们来看看PHP是如何处理HTTP header输出和主体输出的。

PHP 脚本开始执行时,它可以同时发送header(标题)信息和主体信息。 Header信息(来自 header() 或 SetCookie() 函数)并不会立即发送,相反,它被保存到一个列表中。 这样就可以允许你修改标题信息,包括缺省的标题(例如 Content-Type 标题)。但是,一旦脚本发送了任何非标题的输出(例如,使用 HTML 或 print() 调用),那么PHP就必须先发送完所有的Header,然后终止 HTTP header。而后继续发送主体数据。从这时开始,任何添加或修改Header信息的试图都是不允许的,并会发送上述的错误消息之一。

好!那我们来解决它:

笨方法:把错误警告全不显示!
掩耳盗铃之计,具体方法就不说了 ^_^#

解决方案:

1)适用于有权限编辑PHP。INI的人

打开php。ini文件(你应试比我清楚你的php。ini在哪里),找到

output_buffering =改为on或者任何数字。如果是IIS6,请一定改为ON,不然你的PHP效率会奇慢。

2)使用虚拟主机,不能编辑PHP。INI,怎么办?

简单:

在你的空间根目录下建立一个。htaccess文件,内容如下:

AllowOverride All
PHP_FLAG output_buffering On

不幸的情况是:还是不行?全部网页都不能显示啦?

那么,你可以打电话骂一通空间商,然后让他给你把apache的。htaccess AllowOverride打开

3)在PHP文件里解决

ob_start()
启用output buffering机制。 Output buffering支持多层次 -- 例如,可以多次调用 ob_start() 函数。

ob_end_flush()
发送output buffer(输出缓冲)并禁用output buffering机制。

ob_end_clean()
清除output buffer但不发送,并禁用output buffering。

ob_get_contents()
将当前的output buffer返回成一个字符串。允许你处理脚本发出的任何输出。

原理:

output_buffering 被启用时,在脚本发送输出时,PHP并不发送HTTP header。相反,它将此输出通过管道(pipe)输入到动态增加的缓存中(只能在PHP 4。0中使用,它具有中央化的输出机制)。你仍然可以修改/添加header,或者设置cookie,因为header实际上并没有发送。当全部脚本终止时,PHP将自动发送HTTP header到浏览器,然后再发送输出缓冲中的内容。
posted @ 2008-07-29 13:44 姜大叔 阅读(169) | 评论 (0)编辑 收藏
      真的很久很久没有写过文章了,唉,惭愧啊!寒暄的说话就不多说了,直入主题。有人问过我,如何制作一些论坛的自动发言机器人?我说,这很简单啊,(如果没有图片验证码的话!)在Java里,有些URL,URLConnection的类啊,这些类可以访问一个URL获取数据,可以发送Request,你就可以结合一些类做一个自动发言的了,但用Post发送表单的话,就没有直接的,比较麻烦,如果还要处理Cookie的话,之后我想了想,想到了可以用Jakarta Commons 下面的开源项目啊,有一个项目名叫“HttpClient”的,这个就是用Java写的Http客户端,可以说是一个简单功能的浏览器吧,只是不能解析HTML标签,写这个解析可不是易事。既然我们是写个自动访问网站的程序,就不用解析显示HTML啦。朋友说能写个招聘网站的自动刷新简历的程序就好了,那就用51job为例吧。
      首先,你得去下载HttpClient的包。
http://jakarta.apache.org/commons/httpclient

代码不多,我们就先来看看代码吧:

 1 import java.io.*;
 2 import org.apache.commons.httpclient.*;
 3 import org.apache.commons.httpclient.methods.*;
 4 
 5 public class HttpTest {
 6 
 7     /**
 8      * @param args
 9      * @throws Exception
10      */
11     public static void main(String[] args) {
12         //先建立一个客户端实例,将模拟一个浏览器
13         HttpClient client = new HttpClient();
14        
15         //这个是URL地址,我经过分析51job网站登录后的跳转到的地址,并分析得它在JavaScript里提交的URL的参数,不同网站就自已分析了,这个就是登录后刷新简历的URL地址
16         String url = "http://my.51job.com/my/Pop_RefreshResume.php?en=0&ReSumeID=88888888&Read=0&ID=88888888";
17        
18         //之后再建立一个Post方法请求,提交刷新简历的表单,因为提交的参数较多,所以用Post请求好了
19         PostMethod method = new PostMethod(url);
20 
21         //下面的就是将要提交的表单的数据填入PostMethod对象里面,以name , value 对加入!
22         method.addParameter("HPNation""086");
23         method.addParameter("HPCity","020");
24         method.addParameter("HPNumber","88888888");
25         method.addParameter("FPNation","086");
26         method.addParameter("FPCity","020");
27         method.addParameter("FPNumber","88888888");
28         method.addParameter("FPExtension","000");
29         method.addParameter("MPNation","086");
30         method.addParameter("Mobile","13888888888");
31         method.addParameter("EmailAdd","888@888.com");
32         method.addParameter("ReSumeID","88888888");
33        
34         //这里是建立请求时服务器需要用到的Cookie。
35         Cookie cookie = new Cookie(".51job.com","51job","ccry%3D.0%252FZKBaMTmj82%26%7C%26cconfirmkey%3DcpwWgp7FC9FZM%26%7C%26cresumeid%3D88888888%26%7C%26cresumeids88888888d888826%7C8408ilstatus%3D2%26%7C%26cnickname826cenglis8cautologin%3D","/",null,false);
36        
37         //将设置好的Cookie加入模拟的客户端里。当请求发生时,就会将Cookie写进请求头里了
38         client.getState().addCookie(cookie);
39         int i=0;
40 
41         //开始死循环
42         while(true){
43             try{
44                 //这里是要求客户端发送一个请求。直接将PostMethod请求出去。
45                 client.executeMethod(method);
46                
47                 //下面是获取返回的结果
48                 InputStream in = method.getResponseBodyAsStream();
49                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
50                 byte[] buff = new byte[1024];
51                 int len = -1;
52                 while((len=in.read(buff))!=-1){
53                     baos.write(buff, 0, len);
54                 }
55                 String result = new String(baos.toByteArray());
56                
57                 //释放资源
58                 in.close();
59                 baos.close();
60 
61                 //在51job里,刷新简历成功的话,会返回一些JavaScript代码,里面有个alert()输出“简历已刷新”的信息的,你分析结果,如果有这句话,则成功刷新了。之后就让线程睡眠1分钟后循环刷新!
62                 if(result.indexOf("简历已刷新")!=-1){
63                     System.out.println("简历已刷新! " + ++i);
64                 }else{
65                     System.out.println("刷新失败!");
66                 }
67                 Thread.sleep(60000);
68             }catch(Exception ex){
69                 System.out.println("******** Error! ********");
70                 try{
71                     //出现错误时,再等待20秒后再重新进行刷新。
72                     Thread.sleep(20000);
73                 }catch(Exception e){
74                     System.out.println("******** Thread Error! ********");
75                 }
76             }
77         }
78     }
79 
80 }


我们再来看看,其实很简单,我们来说明一下。HttpClient将很多Http协议底层的东西都封装了,这样很方便使用,如果自已用Socket写的话,还有处理很多信息,Http协议的三次握手等等的操作,很是麻烦。现在用HttpClient就一步到位了。但要注意一下,51job里面的简历刷新是要先登录后才可以进行的,而熟悉Web开发的人员都知道,登录后服务器就会记录下你的Session,而Session也是基于Cookie的,所以Session ID是以Cookie的方式记录在客户机的,这样每次请求都要将该Cookie发送到服务器验证,这样才可以保证Web的状态。所以,你可以在浏览器里先登录一次。之后找出该网站的Cookie文件,将里面的内容复制出来放上上面代码的Cookie类里面。你也可以用这个HttpClient写一个登录的请求,之后再从ResponseHeader里获取Cookie。至于表单里的信息,就按自已需要填写就行了。就是模拟一个浏览器,将你的简历刷新的表单模拟出来再发送。

在下面,我给出一本电子书给大家下载参考:《Jakarta Commons Cookbook.chm》
[down=attachments/month_0803/020083401424.chm]点击下载此文件[/down]


posted @ 2008-07-29 13:09 姜大叔 阅读(1713) | 评论 (2)编辑 收藏
      现在双核的CPU已经卖到白菜价了,四核也将在08年迎来普及风暴,这样看来,硬件处理性能是得到很大提高了,但是不是说明程序的效率就可以忽视了呢?肯定不是,程序也将配合硬件的提高,开发出更有效率,更强大,更好的人工智能的程序。多核的趋势,这不得不提到程序的并发性能,不然的话,100核的CPU也只会英雄无用武之地。如何更大地发挥多核CPU的性能,就要用到软件的并发处理能力了。但要设计得合理的并发程序也不是这么简单的事情,线程的控制也是很头痛的问题,还有安全问题等等,我越来越感觉到并发的重要性,所以这段时间也在找Java并发,线程方面的资料,打算钻研一番,并在几天后整理一下,将一些心得放上来。将会是Java并发优化方面的文章!另外,好像听说Flash Player 10将会支持线程,不知道是不是真的,看现时的AS3里没有线程的概念,将会出AS4与之配合?不管怎么都好,期待是美好的事情!
posted @ 2008-07-29 13:07 姜大叔 阅读(246) | 评论 (0)编辑 收藏
      SVN的好处,不用多说了,当你的项目做到一定规模时,多人开发甚至异地多人协作开发时,可以为你的团队省去很多麻烦。可能很多人都用过SVN的客户端工具,如TortoiseSVN或者是Eclipse中的插件,网上有很多开源项目,或者很多源代码,都会用这种方式发布,稍有关注一下技术的很多时候都会下载别人的源程序结合自已的项目开发或者是学习,比如去Google Code有很多。我们只用客户端去连接SVN的服务器,之后更新代码副本到本地。但我们也应该要认识一下SVN的服务器端,比如你是个项目的负责人建立一个项目让大家协同开发等,就要在你的机子上打开SVN服务器程序放上你的项目,让其它人用客户端去连接获取或更新代码。

配置SVN服务器所需要的准备工具:
SubVersion  可从 http://subversion.tigris.org 下载。这里就是SVN服务器的程序
SVNService.exe  (非必要)这个是将你的SVN服务端程序注册成Windows系统服务的,就好比是Tomcat,当你系统启动时,该SVN服务器会自动启动并后台运行,不注册成服务的话,就要自已手动打开了。

现在工具都准备好了,动工。
下载好SubVersion后,就进行安装,如果你下载的是ZIP包,那就解压到自定的目录就可以使用了。
1.  打开CMD命令行模式,进入到SubVersion目录下的bin目录下,输入如下命令:

svnadmin create d:\svn_projects\project1   (路径可自定)

如图:



注:要先在D盘中建立 svn_projects目录 目录名称可以自已定,
之后打开该目录,你可以看到,SVN帮你建立了一个project1的目录,里面生成了几个方件夹与文件,先不理它

现在,存放项目的路径建好了,下面我们要来配置一下该项目的用户,密码等信息
来打开project1/conf/文件夹下的svnserve.conf文件,以记事本打开就行了,你将会看到很多注释(都是采用Unix风格的 # 注释)将
# anon-access = read
# auth-access = write
# password-db = passwd
# realm = My First Repository
这几句的的注释符号去掉找去掉前面的空格如下:
anon-access = read
auth-access = write
password-db = passwd
realm = My First Repository

之后打开passwd文件,以记事本打开,在 [users] 下面添加你的用户名与密码
比如我要添加一个 jiang 用户,密码是 123456 那么这样写
jiang = 123456
保存后就OK了,那么现在,可以运行SVN服务器程序了。
在Cmd命令行下进入到SubVersion目录下的bin目录下,输入如下命令:

svnserve -d -r d:\svn_projects

如图所示:


这样服务器就启动了,它会一直侦听的,所以不要关闭窗口。像Tomcat一样一直挂着就行,如果你觉得这样麻烦,就可以用SVNService.exe这个工具来注册成系统后台服务运行。

注意:你现在的项目的SVN地址就是:svn://localhost/project1  内网就更换你的内网IP就行了,公网也换为你的公网IP就行了

现在服务器就启动了,之后你可以用Eclipse的svn工具等将项目文件放到该SVN服务里共享,
如下图所示:



就这样,SVN的服务器端就搭建好了,现在大家可以用SVN客户端更新下载下来开发了。

关于其它SVN客户工具的登录,可以参考以下文章
如何结合使用Subversion和Eclipse

posted @ 2008-07-29 13:06 姜大叔 阅读(299) | 评论 (0)编辑 收藏
      在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息,以及动态调用对象的方法的功能来自于Java语言的反射(Reflection)机制。Java反射机制主要提供以下功能:

[*]在运行时判断任意一个对象所属的类;
[*]在运行时构造任意一个类的对象;
[*]在运行时判断任意一个类所具有的成员变量和方法;
[*]在运行时调用任意一个类的方法;
[*]生成动态代理;


      在JDK中,主要由以下类来实现Java反射机制,这些类都位于 java.lang.reflect 包中。

      [*] Class 类:代表一个类。
      [*] Field 类:代表类的成员变量
      [*] Method 类:代表类的方法
      [*] Constructor 类:代表类的构造方法
      [*] Array 类:提供了动态创建数组,以及访问数组元素的静态方法


看看下面例子:它读取命令行参数指定的类名,然后打印这个类的所具有的方法信息:
 1 import java.lang.reflect.*;
 2 public class DumpMethods{
 3     public static void main(String[] args)thorws Exception{
 4         //加载并初始化命令行参数指定的类
 5      Class classType = Class.forName(args[0]);
 6         //获得类的所有方法
 7      Method[] methods = classType.getDeclaredMethods();
 8         for(int i=0;i<methods.length;i++){
 9             System.out.println(methods[i].toString());
10         }
11     }
12 }


运行命令 “java DumpMethods java.util.Stack”,就会显示java.util.Stack 类所具有的方法。

这个只是十分之基本,很简单的示例,Java的反射还可以做很多东西,可以跟据用户的输入就可以得知哪些类,需要做什么操作,就是说动态跟据需要来调用相应的类与相应的方法,我之前也做过,用Struts结合Java反射来实现一些功能,有些时候,别人的接口代码里只返回一个Object给你,而你就要用反射来得知该Object是属于哪一个类型,之后根据设置做相应的操作,不知道大家有用过Hibernate没有,这个框架就是大量用到了Java反射,用户只需配置一下XML文件,Hibernate运行时,就会读取解析XML配置文件,之后动态找相应的类,实例化相应的POJO等等,这些都是全动态化的,也就是说,我请求这个表的数据时,就自动实例化该表的POJO实例,这些都是在XML配置文件里定义好映射关系。ORM框架就如此,很多中间件也是大量使用反射,将反射灵活的运用起来,将会得到意想不到的效果,这也是Java的半动态语言吧。使编程工作变得十分灵活。
posted @ 2008-07-29 13:00 姜大叔 阅读(272) | 评论 (1)编辑 收藏
     摘要:     不知道大家有没有用过农业银行的网上银行服务,该网上银行登录时,输入密码时,不可以直接打键盘输入,要用鼠标点击图形小键盘来输入,而小键盘里面的数字是随机排列的。     这样一来,可以防止木马记录用户键盘输入的密码被盗,确实是挻实用的功能,研究了一翻后,也大根掌握了它的工作原理,现在用Java来实现,大概是这样的:用Strut...  阅读全文
posted @ 2008-07-29 12:47 姜大叔 阅读(1185) | 评论 (1)编辑 收藏
仅列出标题
共4页: 上一页 1 2 3 4 下一页