<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>litoueva</title>
    <description></description>
    <link>http://litoueva.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>表达式2</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/191940" style="color:red;">http://litoueva.javaeye.com/blog/191940</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">Case 表达式


Ruby的 case 表达式非常强大，就像多个if的固化物一样。它有两种风格。




第一种风格特别像多个if语句：它让你列出一些条件并执行第一个条件为true的语句。例如，闰年必须可被400除，或可被4除而不可被100除。

leap = case

when year % 400 == 0: true

when year % 100 == 0: false

else year % 4 == 0

end

第二种风格的case语句或许更常用。你在case语句的顶部指定一个目标，然后每个when子句列出一或多个比较。

case input_line

when "debug"

dump_debug_info

dump_symbols

when /ps+(w+)/

dump_variable($1)

when "quit", "exit"

exit

else

print "Illegal command: #{input_line}"

end

像if一样，case返回最后执行的语句的结果，如果你的条件和后面的语句都在一行，你也需要加一个then关键字。

kind = case year

when 1850..1889 then "Blues"

when 1890..1909 then "Ragtime"

when 1910..1929 then "New Orleans Jazz"

when 1930..1939 then "Swing"

when 1940..1950 then "Bebop"

else "Jazz"

end

像if语句，你也可以使用冒号：来代替then关键字。

kind = case year

when 1850..1889 : "Blues"

when 1890..1909 : "Ragtime"

when 1910..1929 : "New Orleans Jazz"

when 1930..1939 : "Swing"

when 1940..1950 : "Bebop"

else "Jazz"

end

case操作数用when关键字后面的比较表达式与目标(关键字case后面的表达式)进行比较。这个测试使用comparison===target。只有一个类定义了===语义(所有内建类都定义了===)，那个类的对象就可以被用在case表达式中。

例如，正则表达式定义===为简单的模式匹配。

case line

when /title=(.*)/

puts "Title is #$1"

when /track=(.*)/

puts "Track is #$1"

when /artist=(.*)/

puts "Artist is #$1"

end

Ruby类是类Class的实例，它的定义===用来测试参数是不是类或它的超类的一个实例。所以(abandoning the benefits of polymorphism and bringing the gods of refactoring down around your ears), 你可以测试对象的类。

case shape

when Square, Rectangle

# ...

when Circle

# ...

when Triangle

# ...

else

# ...

end




循环


不要告诉他人，Ruby支持原始的灵巧的内建循环结构。

while循环根据它的条件的真假来执行0次或者多次语句，比如，下面程序将一直运行，直到输入被打断。

while line = gets

# ...

end

util循环与之相反；知道条件为真，才停止操作。

until play_list.duration > 60

play_list.add(song_list.pop)

end

像if和unless一样，while和until也可以用作语句修饰句。 

a = 1

a *= 2 while a &lt; 100

a -=10 until a &lt; 100

a => 98

在89页的布尔表达式一节中，我们说过range也可以作为布尔表达式，当一些事件发生时返回true然后保持这个true直到下一个事件发生。这个机制多用于循环中，在下面的例子中，我们从一个包含从first到tenth的数字的文本文件中读取数据，但是只打印从以third开头的行，直到遇到fifth开头的行为止。

file = File.open("ordinal")

while line = file.gets

puts(line) if line =~ /third/ .. line =~ /fifth/

end

produces:

third

fourth

fifth

你可以看到用Perl写上面例子时两者的轻微差别。

file = File.open("ordinal")

while file.gets

print if ~/third/ .. ~/fifth/

end

produces:

third

fourth

fifth

这儿有些隐藏在背后的行为：gets将读入的最后行赋值给全局变量$_，~操作符完成与$_的正则表达式的匹配操作，然后不带参数的print打印$_。这种代码是Ruby社区的公认风格。

布尔表达式中的range元素本身也可以是个表达式。它们在布尔表达式每次被计算时都会被求值。例如，下面代码使用了变量$.来包含当前输入的行数，并显示在/eig/和/nin/之间的行号一到三。

File.foreach("ordinal") do |line|

if (($. == 1) || line =~ /eig/) .. (($. == 3) || line =~ /nin/)

print line

end

end

produces:

first

second

third

eighth

ninth

这里有一点需要注意，当while和until用作语句修饰句的时候，如果它们修饰的语句以begin开头，end结尾的块，块内这段代码将总会执行，而不管后面的条件。

print "Hellon" while false

begin

print "Goodbyen"

end while false

produces:

Goodbye




迭代器


如果你读了前面几节，你可能会有些灰心。”Ruby有基本的内建循环结构”，它说。不要失望，亲爱的读者，这是个好消息。Ruby不需要任何内建循环，因为所有的东西都由Ruby的迭代器实现。

例如，Ruby没有for循环，至少没有C，C++和Java的那种。代替的是，Ruby使用定义在各种内建类中定义的方法，它们提供相同的功能，而且更少有错误。

让我们看看一个例子：

3.times do

print "Ho! "

end

produces: 

Ho! Ho! Ho!

这可以轻易地避免off-by-one 错误；这个循环将执行3次。除了times，整数可以调用downto，和upto在指定范围内循环，还可使用step循环所有数字。例如，传统的从0到9的循环(类似i=0; i &lt; 10; i++)可写成下面这样： 

0.upto(9) do |x|

print x, " "

end

produces:

0 1 2 3 4 5 6 7 8 9

一个从0到12，步长为3的循环如下：

0.step(12, 3) {|x| print x, " " }

produces: 

0 3 6 9 12

用于数组和其它容器的迭代的each方法也可以用来循环。

[ 1, 1, 2, 3, 5 ].each {|val| print val, " " }

produces: 

1 1 2 3 5

如果一个类支持了each方法，那么在模块Enumerable(文档在433页，总结在113-113页)中的方法也可以直接使用。比如，File类提供了each方法，依次返回一个文件的每一行。使用Enumerable中的grep方法，我们可以只迭代符合条件的行。

File.open("ordinal").grep(/d$/) do |line|

puts line

end

produces:

second

third

最后也是最简单的，Ruby提供了一个内建的最基本的迭代器loop。

loop {

# block ...

}

loop迭代器一直调用给定的block（或者你调用了break跳出循环，后面会讲到）。




For ... In


前面我们说道Ruby支持的最基本循环是while和until，而for指的什么呢？for几乎只是一块语法糖。当你这样写时

for song in songlist

song.play

end

Ruby将会把它翻译为如下：

songlist.each do |song|

song.play

end




for循环和each形式的唯一区别是它们体内定义的局部变量的作用域。这个讨论在99页。

你可以在支持each的类上使用for方法进行迭代，比如Array或者Range。 

for i in ['fee', 'fi', 'fo', 'fum']

print i, " "

end

for i in 1..3

print i, " "

end

for i in File.open("ordinal").find_all {|line| line =~ /d$/}

print i.chomp, " "

end

produces:

fee fi fo fum 1 2 3 second third

一旦你的类支持了each方法，你就可以使用for来进行遍历。

class Periods

def each

yield "Classical"

yield "Jazz"

yield "Rock"

end

end

periods = Periods.new 

for genre in periods 

print genre, " " 

end

produces: 

Classical Jazz Rock

</pre><br /><br /><span style="font-size: xx-small"><a href="http://my4java.itpub.net/post/9983/65272" target="_blank">easytime</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/191940#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 15:06:13 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/191940</link>
        <guid>http://litoueva.javaeye.com/blog/191940</guid>
      </item>
      <item>
        <title>表达式</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/191938" style="color:red;">http://litoueva.javaeye.com/blog/191938</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">Break, Redo, 和 Next


循环控制结构 break, redo, 和 next 让你可以改变循环或者迭代器的流程。




break 立即结束当前循环；然后跳出去执行循环后面的语句。redo从这次循环体的头开始重新执行，但是不会在对条件进行运算或者从迭代中取下一个值。next跳到本次循环末尾，开始执行下一次循环。 

while line = gets

next if line =~ /^s*#/ # skip comments

break if line =~ /^END/ # stop at end

# substitute stuff in backticks and try again

redo if line.gsub!(/`(.*?)`/) { eval($1) }

# process line ...

end

这些关键字也可以用在任何基于迭代器的循环机制中。

i=0

loop do

i += 1

next if i &lt; 3

print i

break if i > 4

end

produces: 

345

在Ruby 1.8中，break和next可以接受参数。当在传统的循环中使用时，它或许break and next can be given arguments. When used in conventional loops, it probably makes sense only to do this with break (as any value given to next is effectively lost). If a conventional loop doesn’t execute a break, its value is nil.

result = while line = gets

break(line) if line =~ /answer/

end

process_answer(result) if result

If you want the nitty-gritty detail of how break and next work with blocks and procs, have a look at the reference description starting on page 343. If you are looking for a way of exiting from nested blocks or loops, have a look at Kernel.catch, described on pages 347 and 498.




Retry


redo语句使一个循环从当前迭代中重新执行。有时候，你需要从新开始一个循环，retry语句就是个入场卷。它重新开始任何的迭代循环。

for i in 1..100

print "Now at #{i}. Restart? "

retry if gets =~ /^y/i

end

运行这个会话，你可看到

Now at 1. Restart? n

Now at 2. Restart? y

Now at 1. Restart? n

. . .

retry 将重新计算条件值，然后再开始循环。这儿有个例子： 

def do_until(cond)

break if cond

yield

retry

end

i = 0

do_until(i > 10) do

print i, " "

i += 1

end

produces:

0 1 2 3 4 5 6 7 8 9 10




变量作用域，循环和块


while，until和for循环内建于Ruby语言之中，没有引入新的作用域，前面定义的局部变量可以在循环中使用，在循环中创建的变量在后面的代码也可以使用。

用于迭代器(如loop和each)的块则有些小区别。通常，在这些块内创建的局部变量是不可以从块的外部访问的。

[ 1, 2, 3 ].each do |x|

y = x + 1

end

[ x, y ]

produces:

prog.rb:4: undefined local variable or method `x' for

main:Object (NameError)

然而，如果block中的变量和前面已经定义的变量重名的话，已经存在的变量将会在块中使用，而在块执行完成后，这个变量的值也会改变。下面的例子显示，它应用了块内通常变量和块的参数两者。

x = nil

y = nil

[ 1, 2, 3 ].each do |x|

y = x + 1

end

[ x, y ] => [3, 4]

注意：这个变量不需要被给出外部作用域的值：Ruby解释器只需要看到它就可以了。

if false

a = 1

end

3.times {|i| a = i }

a => 2

变量作用域和块的观点在Ruby社区中有很大争论。当前的解决方案有一定的问题(明显的是，变量有可能成为块内的变量的别名)，但当前还没更好的解决办法。Matz表示在Ruby2.0中会解决这个问题，但在此其间，我们还是有些建议来减少变量和块变量之间冲突。

n 保持你的方法和块尽可能地小。少的变量，可以减少彼此间出现碰撞的机会。也很容易地看到代码中产生冲突的名字。

n 为局部变量和块参数使用不同的命名方案。例如，你或许不想有名为”i”的局部变量，但可以接评受它是个块参数。

实际上，这个问题对你在应用上的思想没有影响。
</pre><br /><br /><span style="font-size: xx-small"><a href="http://my4java.itpub.net/post/9983/65275" target="_blank">easytime</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/191938#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 11 May 2008 15:04:29 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/191938</link>
        <guid>http://litoueva.javaeye.com/blog/191938</guid>
      </item>
      <item>
        <title>ssh2整合</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/191442" style="color:red;">http://litoueva.javaeye.com/blog/191442</a>&nbsp;
          发表时间: 2008年05月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          此项目增删改查基本要的都有了，集合了国际化，校验框架加上无法提交，还需要研究<br />Action类<br /><pre name="code" class="java">package com.struts.action;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.hibernate.po.UserTab;
import com.hibernate.service.IUserService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UserAction extends ActionSupport {

	private IUserService dao;

	public IUserService getDao() {
		return dao;
	}

	public void setDao(IUserService dao) {
		this.dao = dao;
	}

	private UserTab user;

	public UserTab getUser() {
		return user;
	}

	public void setUser(UserTab user) {
		this.user = user;
	}

	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		try {
			System.out.println("find");
			Map request = (Map) ActionContext.getContext().get("request");
			request.put("list", dao.findAll());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String save() throws Exception {
		try {
			dao.save(user);
			System.out.println("save");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String see() throws Exception {
		try {
			user = dao.findById(user.getId());
			System.out.println("see");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String delete() throws Exception {
		try {
			dao.delete(user);
			System.out.println("delete");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String update() throws Exception {
		try {
			dao.update(user);
			System.out.println("update");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SUCCESS;
	}

}
</pre><br /><br />测试类<br /><pre name="code" class="java">import java.util.Iterator;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hibernate.impl.UserService;
import com.hibernate.po.UserTab;

public class Test {

	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		// UserTab user = new UserTab();
		UserService um = (UserService) ctx.getBean("userService");
		// user.setFirstname("张");
		// user.setLastname("三");
		// um.save(user);

		Iterator it = um.findAll().iterator();
		while (it.hasNext()) {
			UserTab u = (UserTab) it.next();
			System.out.println(u.getFirstname());
		}
	}
}
</pre><br />struts.xml<br /><pre name="code" class="java">&lt;?xml version="1.0" encoding="UTF-8" ?>
&lt;!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
&lt;struts>

	&lt;package name="user" extends="struts-default">

		&lt;action name="find" class="userAction">
			&lt;result>/list.jsp&lt;/result>
		&lt;/action>

		&lt;action name="save" class="userAction" method="save">
			&lt;interceptor-ref name="defaultStack" />
			&lt;interceptor-ref name="token" />
			&lt;result>/list.jsp&lt;/result>
			&lt;result name="invalid.token">save.jsp&lt;/result>
			&lt;result name="input">/save.jsp&lt;/result>
		&lt;/action>

		&lt;action name="see" class="userAction" method="see">
			&lt;result>/update.jsp&lt;/result>
			&lt;result name="input">/update.jsp&lt;/result>
		&lt;/action>

		&lt;action name="update" class="userAction" method="update">
			&lt;result type="redirect">find.action&lt;/result>
			&lt;result name="input">/index.jsp&lt;/result>
		&lt;/action>

		&lt;action name="delete" class="userAction" method="delete">
			&lt;result type="redirect">find.action&lt;/result>
			&lt;result name="input">/index.jsp&lt;/result>
		&lt;/action>
	&lt;/package>

&lt;/struts></pre><br />请问类级的国际化没办法调用什么原因
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/191442#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 09 May 2008 14:55:19 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/191442</link>
        <guid>http://litoueva.javaeye.com/blog/191442</guid>
      </item>
      <item>
        <title>struts2校验问题</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/191420" style="color:red;">http://litoueva.javaeye.com/blog/191420</a>&nbsp;
          发表时间: 2008年05月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在项目中加入校验框架就无法提交，去掉校验框架之后又正常可以进行提交，请问这样的问题有解决办法吗..<br />struts2+spring2+hibernate3整合出现的
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/191420#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 09 May 2008 13:44:05 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/191420</link>
        <guid>http://litoueva.javaeye.com/blog/191420</guid>
      </item>
      <item>
        <title>向页面传值接收不到</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/191044" style="color:red;">http://litoueva.javaeye.com/blog/191044</a>&nbsp;
          发表时间: 2008年05月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Action<br /><pre name="code" class="java">	public String find() throws Exception {
		Map request = (Map) ActionContext.getContext().get("request");
		request.put("list", dao.findAll());
		System.out.println("find");
		return SUCCESS;
	}</pre><br /><br />list.jsp<br /><pre name="code" class="java">	&lt;body>
		&lt;p>
			User
		&lt;/p>
		&lt;s:iterator value="#request.list" status="u">
			&lt;s:property value="u.id" />
			&lt;s:property value="u.firstname" />
			&lt;s:property value="u.lastname" />
		&lt;/s:iterator>
	&lt;/body></pre><br /><br /><br /><br />报错页面<br />HTTP Status 404 - No result defined for action com.struts.action.UserAction and result input<br /><br />--------------------------------------------------------------------------------<br /><br />type Status report<br /><br />message No result defined for action com.struts.action.UserAction and result input<br /><br />description The requested resource (No result defined for action com.struts.action.UserAction and result input) is not available.<br /><br /><br />--------------------------------------------------------------------------------<br /><br />Apache Tomcat/6.0.16
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/191044#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 08 May 2008 13:52:08 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/191044</link>
        <guid>http://litoueva.javaeye.com/blog/191044</guid>
      </item>
      <item>
        <title>spring2整合hibernate3</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/189926" style="color:red;">http://litoueva.javaeye.com/blog/189926</a>&nbsp;
          发表时间: 2008年05月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          加入需要的包就可以了
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/189926#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 May 2008 22:01:36 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/189926</link>
        <guid>http://litoueva.javaeye.com/blog/189926</guid>
      </item>
      <item>
        <title>Range对象 </title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/169409" style="color:red;">http://litoueva.javaeye.com/blog/169409</a>&nbsp;
          发表时间: 2008年03月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">Range对象表现为一个间隔，有开始与结束的值集。Range对象可以由范围操作符s..e及s…e字面值，或者用Range::new构建。由..操作符构建的Range对象包括范围的终点end值，而由…操作符构建的Range对象不包括范围的终点end值。当用于迭代器对象时，Range对象返回序列内的每一个值。



例如：

for i in 1..5

…

end

生成从1到5的Range对象，然后对分别每个值进行迭代操作。



再如：

(-1..-5).to_a      #=> [](-5..-1).to_a      #=> [-5, -4, -3, -2, -1]('a'..'e').to_a    #=> ["a", "b", "c", "d", "e"]('a'...'e').to_a   #=> ["a", "b", "c", "d"]

Range对象可以由任何类型的对象构建，只要这个对象能够使用它们的&lt;=>操作符，而且它们支持succ方法来返回序列内的下一个对象。也就是说，范围操作符的操作对象必须实现&lt;=>比较操作，而且实现succ方法，则这个操作对象才能执行Range#each操作。

例如：

   class Xs                # 'x'表示字符串     include Comparable     attr :length     def initialize(n)       @length = n     end     def succ              #succ方法的定义       Xs.new(@length + 1) #生成新对象     end     def &lt;=>(other)        #比较操作符的定义       @length &lt;=> other.length     end     def to_s       sprintf "%2d #{inspect}", @length     end     def inspect       'x' * @length     end   end    r = Xs.new(3)..Xs.new(6)   #=> xxx..xxxxxx   r.to_a                     #=> [xxx, xxxx, xxxxx, xxxxxx]   r.member?(Xs.new(5))       #=> true前面的例子中，类Xs包括了Comparable模块。这是因为Enumerable#member?使用==操作符检查等同性(equality)。包括Comparable可确保==操作符在实现&lt;=>方法的Xs中被定义。



Range类的超为是Object，同时它也包含了模块Enumerable。



类方法：

(1) Range.new(start, end, exclusive=false) => range 生成并返回一个从start到end间隔范围的Range对象。第三个参数若省略或为false，则Range对象包含终点end对象，否则，不包含终点end对象。生成对象时，会执行 start &lt;=> end 操作以检查参数的合法性。若返回nil ，则引发ArgumentError异常。



实例方法：

(1) rng === obj => true or false rng.member?(val) => true or false rng.include?(val) => true or false 若val 在Range对象rng的范围内则返回真。===主要用在case句的比较中。


case 79   when 1..50   then   print "lown"   when 51..75  then   print "mediumn"   when 76..100 then   print "highn"   end返回: high


p (0.1 .. 0.2).include?(0.15) # => true

p (0.1 .. 0.2).member?(0.15) # => cannot iterate from Float (TypeError)



# 比较字符串时，include?将按照字典顺序进行比较

p ("a" .. "c").include?("ba") # => true

p ("a" .. "c").member?("ba") # => false



(2)rng.first => obj rng.begin => obj rng.end => obj rng.last => obj 返回rng中的start与end对象。last的返回值与Range对象是否包含范围的终点无关。

p (1..5).end # => 5

p (1...5).end # => 5




(3) rng.exclude_end? => true or false rng对象不包含范围终点时返回真。




(4) rng.each {| i | block } => rng 在rng对象的每个元素上进行迭代操作，传递每个值到block块中。你只可以在Range对象范围内的对象支持succ方法时进行迭代。(这句话的意思是你不可以使用Float对象，因为它没有实现succ方法)。


Range#each使用各元素的succ 方法进行迭代操作。截止1.6版本为止，对Numeric对象一直采用的是算术运算。正因为作出了这个变更，所以不得不修改Float中的Range的处理方法。(Float没有succ)。


   (10..15).each do |n|      print n, ' '    endproduces: 10 11 12 13 14 15




(5) rng.step(n=1) {| obj | block } => rng 以step为步长对范围内的元素进行迭代操作。向block块传递每个nth元素。如果Renge对象的范围包含数字或字符串，则使用自然次序。否则step将调用succ方法来对范围内的元素进行迭代。step是正整数。默认值为1。

下面代码使用了前面的类Xs。

   range = Xs.new(1)..Xs.new(10)   range.step(2) {|x| puts x}   range.step(3) {|x| puts x}produces: 


    1 x    3 xxx    5 xxxxx    7 xxxxxxx    9 xxxxxxxxx    1 x    4 xxxx    7 xxxxxxx   10 xxxxxxxxxx再如：("a" .. "f").step(2) {|v| p v} # => "a" "c" "e"



(6) rng.to_s => string rng.inspect => string ruby 1.7 特性：取消了length和size方法。若确实需要的话，可以这样


p ("a" .. "z").to_a.size #=> 26 即可。</pre><span style="font-size: xx-small"><a href="http://my4java.itpub.net/post/9983/55333" target="_blank">EasyTime</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/169409#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 08 Mar 2008 22:36:34 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/169409</link>
        <guid>http://litoueva.javaeye.com/blog/169409</guid>
      </item>
      <item>
        <title>Ruby and Metaprogramming</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/166658" style="color:red;">http://litoueva.javaeye.com/blog/166658</a>&nbsp;
          发表时间: 2008年03月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">J2EE app 一般都有用到 xDoclet 做一些宣告然後再產生程式碼. Java 1.5 開始支援 Annotation 功能來解決這方面需要. 其實 Ruby 拜本身就是 dynamic 語言之賜, 它這方面的方法可就高明多了, 這也就是為何 Rails 看起來又像是 metaprogramming 的原因. 




請參考這篇說明, Metaprogramming Ruby 
Ruby 不用 setXXX, getXXX, 而是用稱為 attribute accessor 這種方法.

class Book
  def initialize(title)
    @title = title
  end

  def title
    @title
  end
  def title=(value)
    @title = value
  end
end

b = Book.new("Ruby Programming");
puts b.title
b.title = "Ruby Programming 2nd" 
puts b.title
更進一步, 可以用 Ruby 來開發你自己的 programming language 一樣, 可以將上面存取 @title 的兩個方法給作掉, Ruby 內建 attr_reader, attr_write, attr_accessor 這幾個 methods 就是為了這個目地. 如此一來, 你就可以把程式改寫為:

class Book
  attr_accessor :title

  def initialize(title)
    @title = title
  end
end

b = Book.new("Ruby Programming");
puts b.title
b.title = "Ruby Programming 2nd" 
puts b.title
是不是簡單又直覺? 就是提供一些新的 methods, 就可以輕鬆咦髂愕?class. 這就是 Rails 為何都不需用其它檔案來輔助做設定, 利用這些技巧在加上 coding convention, 就很漂亮, 所以不知道 Rails 用法時就是找那些 method 說明就對了. 
Showing changes from revision #3 to #4: Added | Removed 

J2EE app 一般都有用到 xDoclet 做一些宣告然後再產生程式碼. Java 1.5 開始支援 Annotation 功能來解決這方面需要. 其實 Ruby 拜本身就是 dynamic 語言之賜, 它這方面的方法可就高明多了, 這也就是為何 Rails 看起來又像是 metaprogramming 的原因. 
請參考這篇說明, Metaprogramming Ruby 
Ruby 不用 setXXX, getXXX, 而是用稱為 attribute accessor 這種方法.

class Book
  def initialize(title)
    @title = title
  end

  def title
    @title
  end
  def title=(value)
    @title = value
  end
end

b = Book.new("Ruby Programming");
puts b.title
b.title = "Ruby Programming 2nd" 
puts b.title

		更進一步, 可以用 Ruby 來開發你自己的 programming language 一樣, 可以將上面存取 @title 的兩個方法給作掉, Ruby 內建 attr_reader, attr_write, attr_accessor 這幾個 methods 就是為了這個目地. 如此一來, 你就可以把程式改寫為:
class Book
  attr_accessor :title

  def initialize(title)
    @title = title
  end
end

b = Book.new("Ruby Programming");
puts b.title
b.title = "Ruby Programming 2nd" 
puts b.title

		是不是簡單又直覺? 就是提供一些新的 methods, 就可以輕鬆咦髂愕?class. 這就是 Rails 為何都不需用其它檔案來輔助做設定, 利用這些技巧在加上 coding convention, 就很漂亮, 所以不知道 Rails 用法時就是找那些 method 說明就對了.
</pre><br /><span style="font-size: xx-small">摘自:<a href="http://anw.stikipad.com/ocean/show/Ruby+and+Metaprogramming" target="_blank">EasyTime</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/166658#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 02 Mar 2008 16:21:11 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/166658</link>
        <guid>http://litoueva.javaeye.com/blog/166658</guid>
      </item>
      <item>
        <title>Digest 支援 MD5 和 SHA1 兩種編碼, 你若有儲存密碼的需求就要用到, 一般是用 SH</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/166656" style="color:red;">http://litoueva.javaeye.com/blog/166656</a>&nbsp;
          发表时间: 2008年03月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          MD5 計算<br /><pre name="code" class="ruby">
require 'digest/md5'
puts Digest::MD5.hexdigest("Hello World!")
計算檔案的 MD5, 可以確保檔案未曾被修改

require 'digest/md5'

#method 1
puts Digest::MD5.hexdigest(File.read("o.rb"))

#method 2
class Digest::MD5
  def self.open(path)
    o = new
    File.open(path) { |f|
      buf = "" 
      while f.read(256, buf)
        o &lt;&lt; buf
      end
    }
    o
  end
end
puts Digest::MD5.open("o.rb").hexdigest
SHA1 計算

require 'digest/sha1'

puts Digest::SHA1.hexdigest("Hello World!")</pre><br /><br /><span style="font-size: xx-small">摘自:<a href="http://anw.stikipad.com/ocean/show/Digest+MD5+%26+SHA1" target="_blank">EasyTime</a><br /></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/166656#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 02 Mar 2008 16:17:27 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/166656</link>
        <guid>http://litoueva.javaeye.com/blog/166656</guid>
      </item>
      <item>
        <title>Blocks, Closures and Proc Objects</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/166655" style="color:red;">http://litoueva.javaeye.com/blog/166655</a>&nbsp;
          发表时间: 2008年03月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Ruby 的 block 是個不錯的設計. 一個 block 就是一些程式碼, 其 context 為正在動態執行的環境. 有點像是一般稱為 callback 機制, 但 block 方法精巧多了 <br /><br /><br /><br />當你呼叫 method 時, 你可以給它一個 block. 下面 “each” 是 method, do ~ end 中間就是 block, |x|, x 就是傳給 block 的參數.<br /><pre name="code" class="ruby">
books = ["Ruby", "Rails"]
books.each do |b|
  puts b
end
</pre><br /><br />那麼 method 裡如何執行 block? 利用 “yield” <br /><br /><pre name="code" class="ruby">
def three_times
  for i in 1..3 do 
    yield i
  end
end

#invoke
three_times do |i|
  puts "#{i}, see you!" 
end
</pre><br />那要是你的 method 不論有沒有 block 都可以接受的話, 你就要用 block_given? 來測試<br /><pre name="code" class="ruby">
class File
  def self.my_open(*args)
    result = f = File.new(*args)
    if block_given?
      result = yield f
      f.close
    end

    return result
  end
end

File.my_open("x.txt", "w") { |f|
  f.puts "Hello World!" 
}
</pre><br />另外 block 會被 Ruby 轉成參數列的最後一個參數. Ruby 會幫你把 block 轉成 Proc 物件, 你就可以當成一般參數哂? 範例中 “&block” 是標準寫法, Ruby 才會給你名為 “block” 的 Proc 物件, 你就可以 nil? 或呼叫 “call” 執行 block. <br /><pre name="code" class="ruby">
def n_times(n, &block)
  #puts block.inspect
  i = 1
  while i &lt;= n do
    block.call i
    i+=1
  end
end

n_times(5) do |i|
  puts "#{i}, see you!" 
end</pre><span style="font-size: xx-small"><a href="http://my4java.itpub.net/post/9983/66963" target="_blank">专家</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/166655#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 02 Mar 2008 16:12:07 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/166655</link>
        <guid>http://litoueva.javaeye.com/blog/166655</guid>
      </item>
      <item>
        <title>在ASP.NET 2.0中实现URL重写</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/166653" style="color:red;">http://litoueva.javaeye.com/blog/166653</a>&nbsp;
          发表时间: 2008年03月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="postText">URL重写技术在今天已不是什么新鲜的话题了，在Apache服务器提供了名为<a href="http://httpd.apache.org/docs/mod/mod_rewrite.html"><span style="color: #0000ff">mod_rewrite</span></a>的URL重写模块，而在IIS服务器上，也有很多商业的ISAPI 筛选器模块可供使用。然而这对于我们，没有很多的资金或使用的共享服务器，使得以上的方法都不是最佳的解决方案。幸而ASP.NET给我们提供了强大的可扩展性，能让我们自己定义页面的访问规则，很方便实现URL重写。</p><p class="postText">&nbsp;</p><p>在ASP.NET中实现URL重写，需要创建HTTP模块（HttpModule）或HTTP处理程序（HttpHandler），通过调用HttpContext的RewritePath方法来近进行URL重写。本篇文章使用的是HTTP模块做的示例。</p><p><strong><span style="color: #0000ff">使用HTTP模块执行URL重写</span></strong></p><p>首先需要定义一个实现了IHttpModule接口的类。IHttpModule接口定义了两个方法需要实现： </p><ul><li>Init(HttpApplication)。此方法在初始化HTTP模块后触发。在此方法中，您将把事件处理程序绑定到相应的HttpApplication事件。 </li><li>Dispose()。当请求已完成并已发送回IIS时调用此方法。您应当在此处执行所有最终的清除操作。 </li></ul><p>[code=&quot;c#&quot;]</p><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   1:  </span>        <span class="kwrd">public</span> <span class="kwrd">virtual</span> <span class="kwrd">void</span></span> Init(HttpApplication app)</pre><pre><span class="lnum"><span style="font-family: Courier New">   2:  </span></span>        {</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   3:  </span>            <span class="rem">// WARNING!  This does not work with Windows authentication!</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">   4:  </span>            <span class="rem">// If you are using Windows authentication, change to app.BeginRequest</span></span></pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   5:  </span>            app.AuthorizeRequest += <span class="kwrd">new</span> EventHandler(<span class="kwrd">this</span></span>.URLRewriter);</pre><pre><span class="lnum"><span style="font-family: Courier New">   6:  </span></span>        }</pre></div><blockquote><p>[/code]<strong>&nbsp;</strong></p><p><strong>注意</strong>：<em>如果要使用窗体身份验证而不使用Windows身份验证，请将URL重写放在AuthorizeRequest事件处理程序中执行。如果要使用Windows身份验证，请在BeginRequest或AuthenticateRequest事件进行过程中安排URL重写。</em></p></blockquote><p>在URLRewriter方法里的第7行从配置文件里读取URL重写信息，进行处理，如对正则表达式的处理。如您对如何扩展标准的配置文件还不清楚，请看这篇Blog：<a href="http://www.cnblogs.com/superstone/archive/2007/03/27/689307.html"><span style="color: #0000ff">扩展.NET 2.0标准配置文件</span></a>[code=&quot;c#&quot;]</p><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   1:  </span>        <span class="kwrd">protected</span> <span class="kwrd">void</span> URLRewriter(<span class="kwrd">object</span></span> sender, EventArgs e)</pre><pre><span class="lnum"><span style="font-family: Courier New">   2:  </span></span>        {</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   3:  </span></span>            HttpApplication app = (HttpApplication) sender;</pre><pre><span style="font-family: Courier New"><span class="lnum">   4:  </span>            <span class="kwrd">string</span></span> requestedPath = app.Request.Path;</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   5:  </span></span>        </pre><pre><span style="font-family: Courier New"><span class="lnum">   6:  </span>            <span class="rem">// get the configuration rules</span></span></pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   7:  </span></span>            UrlsCollection rules = UrlsConfig.GetConfig().Urls;</pre><pre><span class="lnum"><span style="font-family: Courier New">   8:  </span></span>&nbsp;</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   9:  </span>            <span class="kwrd">for</span> (<span class="kwrd">int</span></span> i = 0; i &lt; rules.Count; i++)</pre><pre><span class="lnum"><span style="font-family: Courier New">  10:  </span></span>            {</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  11:  </span>                <span class="rem">// get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">  12:  </span>                <span class="kwrd">string</span> lookFor = <span class="str">&quot;^&quot;</span> + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].VirtualUrl) + <span class="str">&quot;$&quot;</span></span>;</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  13:  </span></span>&nbsp;</pre><pre><span style="font-family: Courier New"><span class="lnum">  14:  </span>                Regex re = <span class="kwrd">new</span></span> Regex(lookFor, RegexOptions.IgnoreCase);</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  15:  </span>                <span class="kwrd">if</span></span> (re.IsMatch(requestedPath))</pre><pre><span class="lnum"><span style="font-family: Courier New">  16:  </span></span>                {</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  17:  </span>                    <span class="kwrd">string</span></span> sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].DestinationUrl));</pre><pre><span class="lnum"><span style="font-family: Courier New">  18:  </span></span>                    RewriterUtils.RewriteUrl(app.Context, sendToUrl);</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  19:  </span>                    <span class="kwrd">break</span></span>;</pre><pre><span class="lnum"><span style="font-family: Courier New">  20:  </span></span>                }</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  21:  </span></span>            }</pre><pre><span class="lnum"><span style="font-family: Courier New">  22:  </span></span>        </pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  23:  </span></span>        }</pre><pre class="alt">[/code]</pre></div><p>如果匹配，则调用RewriteUrl方法，将URL分解成路径和查询字符串两部分，以调用HttpContext.RewritePath方法来实现URL的重写。其中对&ldquo;URL资源的附加路径信息&rdquo;（如：Http://www.microsoft.com/virdir/page.html/tail&nbsp;的tail部分）未做处理，直接用String.Empty来表示，如您需要，可以自行扩展一下。</p><p>OK，到此为止，一个简单的URL重写程序就初步完成了，但还没有大功告成，还有一个细节的问题需要我们处理一下，就是页面回发后又会在地址栏显示出重写前的地址，也就是真实的地址，影响美观：）。有两种方法可以解决这个问题：</p><ul><li><span style="color: #0080ff">自定义一个继承form控件的控件</span> </li><li>[code=&quot;c#&quot;]</li></ul><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span></span> Form : System.Web.UI.HtmlControls.HtmlForm</pre><pre><span class="lnum"><span style="font-family: Courier New">   2:  </span></span>    {</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   3:  </span>        <span class="rem">/// &lt;summary&gt;</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">   4:  </span>        <span class="rem">/// The RenderAttributes method adds the attributes to the rendered &amp;lt;form&amp;gt; tag.</span></span></pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   5:  </span>        <span class="rem">/// We override this method so that the action attribute is not emitted.</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">   6:  </span>        <span class="rem">/// &lt;/summary&gt;</span></span></pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   7:  </span>        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span></span> RenderAttributes(HtmlTextWriter writer)</pre><pre><span class="lnum"><span style="font-family: Courier New">   8:  </span></span>        {</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   9:  </span>            <span class="rem">// write the form's name</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">  10:  </span>            writer.WriteAttribute(<span class="str">&quot;name&quot;</span>, <span class="kwrd">this</span></span>.Name);</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  11:  </span>            <span class="kwrd">base</span>.Attributes.Remove(<span class="str">&quot;name&quot;</span></span>);</pre><pre><span class="lnum"><span style="font-family: Courier New">  12:  </span></span>&nbsp;</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  13:  </span>            <span class="rem">// write the form's method</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">  14:  </span>            writer.WriteAttribute(<span class="str">&quot;method&quot;</span>, <span class="kwrd">this</span></span>.Method);</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  15:  </span>            <span class="kwrd">base</span>.Attributes.Remove(<span class="str">&quot;method&quot;</span></span>);</pre><pre><span class="lnum"><span style="font-family: Courier New">  16:  </span></span>&nbsp;</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  17:  </span>            <span class="rem">// remove the action attribute</span></span></pre><pre><span style="font-family: Courier New"><span class="lnum">  18:  </span>            <span class="kwrd">base</span>.Attributes.Remove(<span class="str">&quot;action&quot;</span></span>);</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  19:  </span></span>&nbsp;</pre><pre><span style="font-family: Courier New"><span class="lnum">  20:  </span>            <span class="rem">// finally write all other attributes</span></span></pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  21:  </span>            <span class="kwrd">this</span></span>.Attributes.Render(writer);</pre><pre><span class="lnum"><span style="font-family: Courier New">  22:  </span></span>&nbsp;</pre><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  23:  </span>            <span class="kwrd">if</span> (<span class="kwrd">base</span>.ID != <span class="kwrd">null</span></span>)</pre><pre><span style="font-family: Courier New"><span class="lnum">  24:  </span>                writer.WriteAttribute(<span class="str">&quot;id&quot;</span>, <span class="kwrd">base</span></span>.ClientID);</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  25:  </span></span>        }</pre><pre><span class="lnum"><span style="font-family: Courier New">  26:  </span></span>&nbsp;</pre><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  27:  </span></span>    }[/code]</pre></div><p>这个方法直接去掉了form的action属性，所以页面就直接回发给自己了，能够解决问题，但使用起来比较麻烦。想象一下在每个需要重写URL的页面都要去改写form标记，够崩溃的了。</p><ul><li><span style="color: #0080ff">利用ASP.NET 2.0控件适配器扩展架构来定制控件的输出</span> </li></ul><p>在ASP.NET 2.0中，有个比较干净的诀窍可以用来重写&lt;form&gt;控件的action属性。具体地来说，利用新的ASP.NET 2.0控件适配器扩展架构来定制控件的输出，用提供的值来覆盖action属性的值。这不要求在.aspx页面里做任何编码改动，而只要在/app_browsers文件夹里添加一个.browser文件，注册使用一个控件适配类即可输出新的action属性。 </p><p>.browser文件 </p><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   1:  </span></span>&lt;browsers&gt;</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">   2:  </span>  &lt;browser refID=<span class="str">&quot;Default&quot;</span></span>&gt;</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   3:  </span></span>    &lt;controlAdapters&gt;</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">   4:  </span>      &lt;adapter controlType=<span class="str">&quot;System.Web.UI.HtmlControls.HtmlForm&quot;</span></span></pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   5:  </span>               adapterType=<span class="str">&quot;URLRewriter.Form.FormRewriterControlAdapter&quot;</span></span> /&gt;</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   6:  </span></span>    &lt;/controlAdapters&gt;</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   7:  </span></span>  &lt;/browser&gt;</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   8:  </span></span>&lt;/browsers&gt;</pre></div><div class="csharpcode"><pre>&nbsp;</pre></div><p class="csharpcode">URLRewriter.Form.cs文件</p><p class="csharpcode">[code=&quot;c#&quot;]</p><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   1:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span></span> FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   2:  </span></span>    {</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   3:  </span>        <span class="kwrd">public</span></span> FormRewriterControlAdapter()</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   4:  </span></span>        {</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">   5:  </span></span>        }</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   6:  </span></span>&nbsp;</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   7:  </span>        <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span></span> Render(HtmlTextWriter writer)</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">   8:  </span></span>        {</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">   9:  </span>            <span class="kwrd">base</span>.Render(<span class="kwrd">new</span></span> RewriteFormHtmlTextWriter(writer));</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  10:  </span></span>        }</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  11:  </span></span>    }</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  12:  </span></span>&nbsp;</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  13:  </span>    <span class="kwrd">public</span> <span class="kwrd">class</span></span> RewriteFormHtmlTextWriter : HtmlTextWriter</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  14:  </span></span>    {</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  15:  </span>        <span class="kwrd">public</span></span> RewriteFormHtmlTextWriter(HtmlTextWriter writer)</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  16:  </span>            : <span class="kwrd">base</span></span>(writer)</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  17:  </span></span>        {</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  18:  </span>            <span class="kwrd">base</span></span>.InnerWriter = writer.InnerWriter;</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  19:  </span></span>        }</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  20:  </span>        <span class="kwrd">public</span></span> RewriteFormHtmlTextWriter(System.IO.TextWriter writer)</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  21:  </span>            : <span class="kwrd">base</span></span>(writer)</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  22:  </span></span>        {</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  23:  </span>            <span class="kwrd">base</span></span>.InnerWriter = writer;</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  24:  </span></span>        }</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  25:  </span></span>&nbsp;</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  26:  </span>        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> WriteAttribute(<span class="kwrd">string</span> name, <span class="kwrd">string</span> <span class="kwrd">value</span>, <span class="kwrd">bool</span></span> fEncode)</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  27:  </span></span>        {</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  28:  </span>            <span class="rem">//If the attribute we are writing is the &quot;action&quot; attribute, and we are not on a sub-control, </span></span></pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  29:  </span>            <span class="rem">//then replace the value to write with the raw URL of the request - which ensures that we'll</span></span></pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  30:  </span>            <span class="rem">//preserve the PathInfo value on postback scenarios</span></span></pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  31:  </span>            <span class="kwrd">if</span> (name == <span class="str">&quot;action&quot;</span></span>)</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  32:  </span></span>            {</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  33:  </span></span>                HttpContext context = HttpContext.Current;</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  34:  </span>                <span class="kwrd">if</span> (context.Items[<span class="str">&quot;ActionAlreadyWritten&quot;</span>] == <span class="kwrd">null</span></span>)</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  35:  </span></span>                {</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  36:  </span>                    <span class="rem">//We will use the Request.RawUrl property within ASP.NET to retrieve the origional </span></span></pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  37:  </span>                    <span class="rem">//URL before it was re-written.</span></span></pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  38:  </span>                    <span class="kwrd">value</span></span> = context.Request.RawUrl;</pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  39:  </span>                    <span class="rem">//Indicate that we've already rewritten the &lt;form&gt;'s action attribute to prevent</span></span></pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  40:  </span>                    <span class="rem">//us from rewriting a sub-control under the &lt;form&gt; control</span></span></pre></div><div class="csharpcode"><pre class="alt"><span style="font-family: Courier New"><span class="lnum">  41:  </span>                    context.Items[<span class="str">&quot;ActionAlreadyWritten&quot;</span>] = <span class="kwrd">true</span></span>;</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  42:  </span></span>                }</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  43:  </span></span>            }</pre></div><div class="csharpcode"><pre><span style="font-family: Courier New"><span class="lnum">  44:  </span>            <span class="kwrd">base</span>.WriteAttribute(name, <span class="kwrd">value</span></span>, fEncode);</pre></div><div class="csharpcode"><pre class="alt"><span class="lnum"><span style="font-family: Courier New">  45:  </span></span>        }</pre></div><div class="csharpcode"><pre><span class="lnum"><span style="font-family: Courier New">  46:  </span></span>    }[/code]</pre></div><div class="csharpcode" align="right">直接将action属性的值赋予成URL重写后的地址，简单又实惠，何乐而不为呢</div><div class="csharpcode" align="right">资料来源:<a href="http://www.51aspx.com/CT/Z9UMK7ZUJXE31/">http://www.51aspx.com/CT/Z9UMK7ZUJXE31/</a></div>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/166653#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 02 Mar 2008 16:01:40 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/166653</link>
        <guid>http://litoueva.javaeye.com/blog/166653</guid>
      </item>
      <item>
        <title>初步了解</title>
        <author>litoueva</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://litoueva.javaeye.com">litoueva</a>&nbsp;
          链接：<a href="http://litoueva.javaeye.com/blog/127011" style="color:red;">http://litoueva.javaeye.com/blog/127011</a>&nbsp;
          发表时间: 2007年09月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title">ruby 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-rb">
    <li class="alt"><span><span class="keyword">class</span><span>&nbsp;SampleCode &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">def</span><span>&nbsp;say() &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">#什么都不表示的只可以做局部变量 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;name=</span><span class="string">&quot;sd&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="string">&quot;Goddnight,&nbsp;#{name}&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">end</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">def</span><span>&nbsp;say1() &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">#以@开始的是局部变量,放到方法外都不会报错,放到别的类中一样不报错 </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="variable">@name</span><span>=</span><span class="string">&quot;sd&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="string">&quot;Goodnight,#{@name}&quot;</span><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">end</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="comment">#以@@开头的是全局变量,设置在别的方法里,找不到会报错,在同文件不同类中访问不到 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;@</span><span class="variable">@name</span><span>=</span><span class="string">&quot;1&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">def</span><span>&nbsp;say2() &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="string">&quot;Goddnight,&nbsp;#{@@name}&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="keyword">end</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span><span class="comment">#以$开头是超级全局在同个文件不同类中都可以访问,在不同的文件中就访问不到,不定义都不会报错 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">def</span><span>&nbsp;say3() &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="string">&quot;Goddnight,&nbsp;#{$name}&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">end</span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="keyword">end</span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>sc=SampleCode.</span><span class="keyword">new</span><span>() &nbsp;&nbsp;</span></li>
    <li class="alt"><span>puts&nbsp;sc.say()&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://litoueva.javaeye.com/blog/127011#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Sep 2007 22:59:42 +0800</pubDate>
        <link>http://litoueva.javaeye.com/blog/127011</link>
        <guid>http://litoueva.javaeye.com/blog/127011</guid>
      </item>
  </channel>
</rss>