正在加载...
 
  • 共 36 文章
  • 1
  • 2
  • 3
  • >
新手该学哪门编程语言  

 在某个论坛上看到有人在问——“Which programming language should I learn first?”,看到了下面的这个回答,有点意思。

Depends.

  • To program in an expressive and powerful language: Python
  • To get a website up quickly: PHP
  • To mingle with programmers who call themselves “rockstars”: Ruby.
  • To really learn to program: C.
  • To achieve enlightenment: Scheme.
  • To feel depressed: SQL
  • To drop a chromosome: Microsoft Visual Basic
  • To get a guaranteed, mediocre, but well paying job writing financial applications in a cubicle under fluorescent lights: Java.
  • To do the same thing with certifications and letters after your name: C#
  • To achieve a magical sense of childlike wonder that you have a hard time differentiating from megalomania: Objective C

I could go on… but I’m not feeling hateful enough today.

翻译如下:

 

看你的需要了。

  • 如果你想找一门表达力和功能都很强的语言:Python
  • 如果你想更快速地开发WEB程序:PHP
  • 如果你想和那些“摇滚明星”的程序员为伍:Ruby
  • 如果你想学真正的编程:C
  • 如果你想顿入空门的话:Scheme
  • 如果你想压抑的话:SQL
  • 如果你想基因突变成为非人类的话:Microsoft Visual Basic
  • 如果你想要得到一个有保证的,但普普通通的,收入还不错的,在一间小卧室的荧光灯下写一些金融应用的工作:Java
  • 如果你想在你的名字后放上一些认证和证书:C#
  • 如果你想得到一些很难在自大狂和孩子气中区分的那种魔幻般的感觉:Objective C

我还可以再写去,因为今天我还没有足够的愤怒。

跟着这个思路,我也补充几条吧,

  • 如果你想寻找在被虐中被大众称道的感觉:C++
  • 如果你想整天都在说Fxxk的脏话:JavaScript (哪种程序员嘴最脏)
  • 如果你想成为无所不能的BS一切的神:汇编
  • 如果你想成为一个像春哥或犀利哥一样真正的男人:Brainfuck (BT雷人的程序语言

呵呵,欢迎留下你的回答!

来源:http://coolshell.cn/?p=2402

标签:其他文章,Web开发 | 浏览数(306) | 评论数(0) | 05-26 09:08
ASP.Net的Application  

 ASP.Net的Application

 
 
在ASP.Net中Application用法与ASP是一样的,几乎是没有什么说的,但是它多了两个特别有用的事件,Application_OnBeginRequest和Application_OnEndRequest。他们的和原来的Application_OnStart和Application_OnEnd一样是放在global文件中的(注意这个文件在ASP中名字是global.asa,在ASP.Net中是global.asax)。
 
注:这个事件,写不写On是一样的。如Application_End与Application_OnEnd是一样的
 
  Application_OnStart是在整个ASP.Net应用首先被触发的事件,也就是在一个虚拟目录中第一个ASP.Net程序执行时触发,Application_OnEnd就正好相反,在整个应用停止时被触发(通常发生在服务器被重启/关机时)。Application_OnRequestStart和Application_OnRequestEnd则是在每一个ASP.Net程序被请求时就发生,也就是说客户访问一次一个ASP.Net程序,这两个事件就会被触发。我们可以从下面的程序看到他的应用.我们先建立一个global.asax,内容如下:
 
<script language="C#" runat="server">
void Application_OnBeginRequest(Object sender, EventArgs E)
{
  Response.Write("Request is Starting...<br>");
}
 
void Application_OnEndRequest(Object sender, EventArgs E)
{
  Response.Write("Request is Ending...<br>");
}
</script>
 
然后将其放到本虚拟目录的根目录下,然后我们随便打开一个什么aspx文件
我们在global.asax中定义的语句Request is Starting...和Request is Ending...这个不是我们在这个文件中独加的,我们将会再任何一个ASP.Net文件中看到它的影子。

标签:.NET,Web开发 | 浏览数(305) | 评论数(0) | 05-17 13:55
ASP.Net的Session  

 ASP.NET 中的SESSION

ASP.Net中的Session是我见过最好的处理,是其它动态网页技术不能比拟的。ASP.Net中的Session再也不需要Cookies的支持,也就是说如果用户关闭了Cookie,Session的值一样也可以被保存。
不过,我们需要对config.web文件进行一些配制,因为在其中找到关于Session的设置文本,如:
<sessionstate cookieless="false" />

把cookieless="false" 改成cookieless="true" ,那么以后Session就不储存在cookies中了,而在储存在URL中。
其实,我发现,不用改config.web文件,关掉cookies后,不用URL也照样能传递session值,这种情况下Session是如何保值的,这个就不太清楚了:)
Session还可保持不死之术,就是当服务器重启,还是能保证Session中的值不变,不过这又要改动config.web文件。也是通过下面的语句设定.
<sessionstate inproc="false" server="localhost" port="42424" />

是不是发现这里的Session是不是很强大啊:),把localhost改成您要的主机,Session还能在另外一台主机上保持。

来源于:互联网

标签:.NET,Web开发 | 浏览数(279) | 评论数(0) | 05-17 13:51
如何在Silverlight中切换“页面”  

作者:
来源:来自“Jesse Liberty”的视频“USING MULTIPLE PAGES, PART 1”
标题:如何在Silverlight中切换“页面”

最近初学Silverlight,有海量的问题需要解决。先把这个切换页面的方法记录一下。

这个做法是来自“Jesse Liberty”的视频“USING MULTIPLE PAGES, PART 1”,基本方法是创建一个PageSwticher,这个PageSwitcher不直接显示页面,而是作为一个后台,负责切换各个页面。 具体做法是:

新建一个UserControl,名字可以叫做PageSwitcher。然后将PageSwitcher.xaml中的Grid控件去掉,编程下面这样:


CODE:PageSwitcher.xaml
<UserControl x:Class="SilverlightDemo.PageSwitcher"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml%22>
</UserControl>

然后在后台代码中增加一个方法,比如叫做SwitchPage,用来切换页面,然后在构造函数中调用,用来显示第一个要显示页面:


CODE:SwitchPage方法
public partial class PageSwitcher : UserControl
{
public PageSwitcher()
{
InitializeComponent();
SwitchPage(
new Page()); //显示第一个要显示的页面
}

/// <summary>
/// 切换页面
/// </summary>
/// <param name="newPage">需要被切换到的页面</param>
public void SwitchPage(UserControl newPage)
{
this.Content = newPage;
}
}

然后在我们的各个页面中,在需要切换页面的事件响应方法中,只需要这么做:

CODE:需要切换页面的事件响应方法中
private void btn_Click(object sender, RoutedEventArgs e)
{
    PageSwitcher switcher 
= this.Parent as PageSwitcher;
    switcher.SwitchPage(
new AnotherPage());
}

最后,我们需要修改app.xaml.cs中的Application_Startup方法,修改起始页面

CODE:app.xaml.cs
private void Application_Startup(object sender, StartupEventArgs e)
{
    
this.RootVisual = new PageSwitcher();
}

标签:.NET,解决方案,Web开发,C#,Silverlig... | 浏览数(1002) | 评论数(0) | 2009-12-25
在C#应用程序中获取和设置IE浏览器Cookie  

使用部分代码


CODE:设置cookie
if (!InternetSetCookie("http://xxxx/xxxx.htm", "Test", "Sent as Test via VB+ ;expires=Sun,22-Feb-2099 00:00:00 GMT")) { MessageBox.Show(GetLastError().ToString()); }

CODE:读取cookie
int size = 1000; StringBuilder cookie = new StringBuilder(size); if (!InternetGetCookie("http://xxxx/xxxx.htm", "Test", cookie, ref size)) { MessageBox.Show(GetLastError().ToString()); } else { MessageBox.Show(cookie.ToString()); }

阅读全文...
标签:.NET,Web开发,C# | 浏览数(1059) | 评论数(0) | 2009-11-21
ASP.NET 3.5 要如何安裝在 IIS 5.0/6.0 中  

作者:大师
来源:互联网
标题:ASP.NET 3.5 要如何安裝在 IIS 5.0/6.0 中

这几天在研究 .Net 3.5,发现了一个疑问,就是在 IIS 里面为什么看不到 ASP.NET 3.5 的选项?且以前在 .NET 2.0 的时候有个 aspnet_regiis.exe 的执行档 在.NET 3.5 也看不到!!

后来我才搞懂,原來 ASP.NET 3.5 只是使用 .Net Framework 3.5 的组件(assembly)而已!整个核心的架构还是建立在 .NET 2.0 之上,.NET Framework 的 API 都沒变,只是到了 .NET 3.5 很多 assembly 都重新写过了,且执行的速度也比 .NET 2.0 的组件还快。

如果你用 Visual Studio 2008 开一个网站,你开启 web.config 会发现在 <assemblies> 区段中出现了一堆 assembly 的定义,其版本都是 3.5.0.0


CODE:web.config
<compilation debug="true"> <assemblies>; <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> </assemblies> </compilation>

所以 ASP.NET 3.5 的程式要安装在 IIS 上不需要特別指定 ASP.NET 3.5 的版本,继续沿用 ASP.NET 2.0 的版本即可,但作業系統本身必須要先安裝 .Net Framework 3.5 runtime 就是了!

标签:.NET,Web开发,C# | 浏览数(838) | 评论数(0) | 2009-11-21
Servlet输出图片(验证码)  


CODE:web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <description> This is the description of my J2EE component </description> <display-name> This is the display name of my J2EE component </display-name> <servlet-name>imgServlet</servlet-name> <servlet-class> com.zouzhxi.test.servlet.imgServlet </servlet-class> <init-param> <param-name>imgWidth</param-name> <param-value>80</param-value> </init-param> <init-param> <param-name>imgHeight</param-name> <param-value>25</param-value> </init-param> <init-param> <param-name>codeLength</param-name> <param-value>4</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>imgServlet</servlet-name> <url-pattern>/servlet/imgServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

阅读全文...
标签:Web开发,Java,JSP/Servlet | 浏览数(1587) | 评论数(0) | 2009-06-24
Hibernate中数据检索方法的比较  

Hibernate中数据检索方法的比较


query:使用hsql语句,可以设置参数是常用的一种方式

criteria:尽量避免了写hql语句,看起来更面向对象了。

get和load方式是根据id取得一个记录。

1、从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null

2、从检索执行机制上对比:
get方法是直接从数据库中检索,而load方法的执行则比较复杂:

1,首先查找session的persistent Context中是否有缓存,如果有则直接返回

2,如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常

3,如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null

4, 在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果找不到就抛出异常。

标签:Web开发,Java,JSP/Servlet,SSH | 浏览数(1106) | 评论数(0) | 2009-04-11
JSP中出现According to TLD or attribute directive in tag file, attribute value does not accept any expre  

JSP中出现According to TLD or attribute directive in tag file, attribute value does not accept any expressions 

应用部署运行的时候出现JSP异常, 发生在使用JSTL库的时候: According to TLD or attribute directive in tag file, attribute value does not accept any expressions, 可能是因为使用了JSP2.0版本, 同时又没有使用JSTL core库的备用版本(RT库), 以下有两种处理方法: 

第一种:修改web.xml文件
原来的
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

修改后
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

第二种:使用JSTL core RT库
JSTL core库的有两种taglib伪指令, 其中RT库即是依赖于JSP传统的请求时属性值, 而不是依赖于EL来实现(称为EL库.JSP2.0将支持EL)
JSP中使用<%@ taglib uri=http://java.sun.com/jstl/core prefix="c"%>在2.3版本都可以,在2.4就不行了, 难道是版本不兼容吗?

只要将<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
改为<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>


由于我自己也遇上这问题
本文来源于互联网上

标签:Web开发,Java,JSP/Servlet | 浏览数(2161) | 评论数(0) | 2009-02-19
Java和JSP编程的六个常见问题  

作者:佚名
来源:希赛网
标题:Java和JSP编程的六个常见问题

1.对应String类型的对象使用println()方法时,如果对象为null,将打印null而不是引发NullPointerException,由此引用的问题是容易造成错觉,对于以后对字符串的操作容易引起问题。

2.引发NullPointerException异常,主要原因是没有对对象的存在性进行验证,在jsp编程中经常出现:

if (request.getParameter(“username”)。
equals(“xxx”))
out.println(session.getAttribute(“record”))等。
解决这个问题的方法是在使用前进行判空比较:

CODE:
if (request.getParameter(“username”)!=null) {if if (request.getParameter(“username”). equals(“xxx”))…}

3.引发NumberFormatException异常:主要原因是将用户提交的内容转换为整数或者浮点数时用户输入了其它非法字符。处理的主要方式是在需要进行转换的地方使用try/catch块捕获此异常然后提示用户输入合法数据。

4.引发StringIndexOutOfBoundsException异常:主要原因是使用String的substring()、charAt()等方法,而字符串的长度不够,就会引发此异常;在字符串为null时也会引发NullPointerException.解决的方法是判空,判断长度或者转换为字节数组。考虑到这些操作很多,可以将之封装到javabean中。

5.引发NoClassDefFoundError错误,主要原因是类路径或者类文件放置错误,类文件的放置要符合服务器的要求。

6.引发java.lang.Error错误,主要原因是对系统所访问外部资源,未执行关闭操作,导致外部资源大量浪费,最终可能导致系统无法正常运行;对系统所访问的外部资源关闭次数太多,外部系统无法正常处理;所系统访问的外部资源出现异常情况。

解决的方法是:访问外部资源前,首先检查该资源(如数据库)是否可正常连接或操作;访问外部资源时,如果进行了连接,一定进行关闭操作,并仅进行一次关闭操作;尽量在同一操作中共享外部资源,以减少该操作对资源的消费,提高程序的执行效率。

标签:Web开发,Java,JSP/Servlet | 浏览数(1565) | 评论数(0) | 2009-01-06
用 JSON 处理缓存  

作者:Bakul L. Patel 
来源:developerWorks
标题:用 JSON 处理缓存
内容摘要:
在本文中,您将了解如何在服务器代码的帮助下将元数据缓存在客户端的优秀方法,服务器代码将提供 JSON(JavaScript Object Notation)形式的字符串化元数据。这种方法还允许以类似 Ajax 的方式来处理多值和多组属性。

  数据验证是每个企业 Web 应用程序中最富于挑战性、日新月异的部分。通常验证元数据会使 JavaScript 模块中混入服务器端代码。在本文中,您将了解如何在服务器代码的帮助下将元数据缓存在客户端的优秀方法,服务器代码将提供 JSON(JavaScript Object Notation)形式的字符串化元数据。这种方法还允许以类似 Ajax 的方式来处理多值和多组属性。

  每个应用程序的开发都是为了解决某个领域的问题。而每个领域都有自己的一套约束数据的规则和规范。应用程序将这些约束应用于数据时,约束也就成了验证。所有应用程序都需要验证用户输入的数据。

  目前,应用程序一般都使用 if-else 语句组合来验证数据。这些语句包含了开发人员硬编码或通过服务器端代码置入的验证数据。通常,开发人员会使用服务器端代码来避免可能导致 JavaServer Page(JSP)的细微数据更改。

  您可以使用 JavaScript Object Notation(JSON)来分组和缓存元数据,并使用 JavaScript 函数来访问元数据以验证用户输入。

  JavaScript 中有分散的元数据时,您无法控制服务器将评估多少数据以及有多少数据传递到客户机。所有服务器端代码片段都将被评估并发送到服务器上。但是,使用 JSON 缓存数据时,您可以完全控制向客户机发送的元数据量,因为服务器端代码将生成 JSON 形式的元数据。这有助于仅将元数据发送至与看到或输入数据的用户相对应的客户机上。

  您还可以使用 JSON 来缓存用户输入的数据。程序缓存数据后,将擦除数据字段而不是刷新屏幕,这与 Ajax 类似。通过这种方法,用户可以为同一属性输入另一组数据。

  让我们一起来探究一下如何使用 JSON 来缓存元数据。

  JSON 概览

  使用 JSON(即 JavaScript Object Notation),将以一种特定的字符串形式来表示 JavaScript 对象。如果将具有这样一种形式的字符串赋给任意一个 JavaScript 变量,该变量随后将引用一个通过指定给该变量的字符串构建的对象。

 

  例如,假定有一个 policy 对象,它拥有以下属性:
  计划名称 
  描述 
  持续时间 
  您可以使用以下这种 JSON 形式的字符串来表示该 policy 对象:

 


CODE:policy 对象
{ "Plane" : { "Full Life Cover" }, "Description" : { "The best life insurance plan" }, "Term" : { "20 years" } }

如果将此字符串赋给任意一个 JavaScript 变量,则该变量将接受以这种对象为单位的数据。要访问数据,请提供需要访问的属性所在的路径。对于本例,将以上字符串赋给一个名为 policy 的变量:


CODE:policy 的变量
var policy = { "Plane" : { "Full Life Cover" }, "Description" : { "The best life insurance plan" }, "Term" : { "20 years" } }

将此字符串粘贴到 HTML 页面的标题部分中,然后编写以下警报:

警报代码:
alert(policy.Plan);

如果在任何支持 JavaScript 的浏览器中查看此页面,您都会看到显示策略计划的警报。

示例
  为了演示 JSON 的性能,我们来看一个有 vehicle 对象列表的 person 对象
  和一个可以拥有一台或多台车辆的 person 对象。每台车辆都有以下属性:
  品牌 
  注册码 
  CC 
浏览器 UI 应当允许用户添加多台具有优秀应用性能的车辆(通常为固有要求)。
  每个属性都有一些与之关联的限制或验证规则。
  您需要指定以下规则:
  品牌名称
  品牌名称决不能包含数字。 
  品牌名称最多可包含两个单词,中间可加一个空格。 
  注册码 
  注册码必须全都是数字。 
  CC 
  CC 必须全都是数字。 
  CC 的最小值为 50,最大值为 5000。

 

将有三个与车辆属性相对应的输入字段,用户可在其中输入信息。接下来,您将看到如何将验证消息分组到 JSON 组中以及如何访问这些验证消息。

  传统方法

  现在,当用户输入的车辆数据为 40CC 时,程序必须显示一条消息,说明输入的数据不在有效的 CC 范围内。您可以用 清单 1 中的代码简单地显示这条消息:


CODE:清单 1. 传统代码
if(cc < <%= minCC %> || cc > <%= maxCC %>) {    alert(<%= ResourceList.vehicleCCRangeMsg >); }

ResourceList 是一个服务器端类,该类中含有关于车辆的国际化消息(如 vehicleCCRangeMsg)。这种方法解决问题时略显混乱:

  在这种方法中,您将把服务器端代码添加到所有客户端验证函数中,以检查条件并显示消息。

  如果更改了元数据和消息(例如服务器端类或变量)的组织方法,您将会为更改使用这些元数据和消息的客户机脚本验证函数感到十分头痛。

  JSON 能帮助您做什么?

  如果只需在条件语句和警报中引用一个 JavaScript 变量而不是服务器端代码,您感觉怎么样?不需要把服务器端代码包含在 JavaScript 中,而保存的服务器端元数据和消息中的更改也不会影响客户端脚本。这种方法太棒了,是不是?好的,那就是使用基于 JSON 缓存元数据时要做的。

  您将使用一个 JavaScript 对象把我们的验证数据和消息分组到一个层级中。然后就像访问层级的 JavaScript 对象一样访问这些消息。就是这样,您已经做到了!

  当此 JSON 元数据对象就绪后,先前的 JavaScript 代码片段将类似于 清单 2。


CODE:清单 2. 带有 JSON 元数据缓存对象的警报
if(cc < vehicleValidationsMetadata.CC.minCC ||            cc > vehicleValidationsMetadata.CC.maxCC) {    alert(vehicleValidationsMetadata.CC.RangeMessage);    }

  现在,问题是谁来准备 JSON 元数据对象?嗯,只有服务器能做这项工作。服务器必须生成这个 JSON 对象,并将其提供给客户机(浏览器)。一些 Java API 可以帮助您准备此类(事实上是任意一类)JSON 对象。请参阅 参考资料 来查看那些 API。

  生成 JSON 元数据对象的典型方法为:

  为实体及其验证消息准备一个层级 Java 对象。

  对这些实体及其验证消息调用 toString()。这些实体及其验证消息最有可能把一个 JSON 形式的字符串提供给您。

  将该字符串另存到一个请求范围内。

  在 JSP 中,获取该字符串,并将其指派到 JavaScript 变量值的大括号内。

  最终的车辆元数据对象看上去就会像 清单 3 一样。


CODE:清单 3. 验证元数据 JSON 对象
var vehicleValidationsMetadata = { "BrandName":{ "CanContainDigits":{false}, "MaxWords":{2}, "FormatMessage":{"Brand Name cannot contain digits."}, "WordLimitMessage":{"Brand Name cannot contain more than two words"} }, "RegistrationNumber":{ "CanContainAlphabets":{false}, "CanContainDigits":{"true"}, "FormatMessage":{"Registration Number can contain only digits."} }, "CC":{ "minCC":{50}, "maxCC":{5000}, "FormatMessage":{"CC can only be numeric"}, "RangeMessage":{"CC can be within range of 50 and 5000"} } }

  服务器必须生成整个字符串,第一行和最后一行除外,因为当前的用户语言环境可能要求使用这些消息(并且只有服务器端代码能完成这项工作)。在这里,需要注意的一点是此元数据对象仅用于验证车辆。更理想的情况是将 vehicle 元数据对象封装到 person 元数据对象中。那样,您就不需要再创建另一个 JavaScript 变量,而只需将该元数据对象包含到 person 元数据对象中。

  在将此元数据对象准备好后,您可以使用该对象中的元数据和消息来验证数据输入和显示消息。现在,验证车辆输入信息的 JavaScript 函数看上去就会跟 清单 4 一样。


CODE:清单 4. 车辆数据验证函数
function validateVehicleData() { var brandName = //get brand name from form field var registrationNumber = //get Registration Number from form field. var CC = //get CC from form field var brandNameTokens = brandName.split(' '); if(brandNameTokens.length > vehicleValidationsMetadata.BrandName.MaxWords) { alert(vehicleValidationMessages.BrandName.WordLimitMessage); } . . . if((!vehicleValidationsMetadata.RegistrationNumber.CanContainAlphabets) && isNaN(parseInt(registrationNumber))) { alert(vehicleValidationMessages.RegistrationNumber.FormatMessage); } var ccNum = parseInt(CC); if(ccNum < vehicleValidationMessages.CC.minCC || ccNum > vehicleValidationMessages.CC.maxCC) { alert(vehicleValidationMessages.CC.RangeMessage); } }

  这段代码看上去是不是好多了?它没有在 JavaScript 中混入服务器代码。如果服务器端更改存储元数据的方法,则无需再重写客户机脚本。这会使 JSP 编程人员的日子更轻松些。

  扩展客户端数据缓存

  某些 Web 应用程序要求用户为同一个属性或对象输入多个数据。例如,person-vehicle 要求人员为其拥有的每台车辆都输入数据。如果此人拥有多台车辆,应用程序必须允许输入多台车辆的数据。我将把此类对象作为一个 多组属性 来引用。如果多组属性包含任何可以保存多个数据实例的属性,我将称之为 多值属性。

  现在,多组属性和多值属性面临的问题是必须将数据输入到相同的输入字段中。那意味着在输入第二台车辆的数据之前,必须先保存已输入的第一台车辆的数据。您可以通过两种方法来解决此问题:

  将第一台车辆的数据发送到服务器上并清空输入字段,以允许用户输入下一台车辆的数据。

  将数据缓存到客户机上并清空输入字段,以允许用户输入下一台车辆的数据。

  第一种方法存在的问题是每输入一台车辆的数据就需要访问一次服务器。这不太好;如果在输入车辆数据后都必须等待服务器响应,用户会觉得很失望。换种方法,第二种方法的响应时间几乎为零。用户可以快速输入所有车辆数据而无需等待。但这里需要考虑的是如何将数据存储到客户端上。这里有更多方法可将数据存储到客户机上:

  在用户单击以添加下一台车辆的数据时将数据以某种形式缓存到隐藏的表字段中。

  将数据缓存到一个 JavaScript 对象中。

  如果要将数据存储到隐藏字段中,您会为用户每次输入新的车辆数据都要处理很多隐藏字段或处理隐藏字段数据而感到烦恼。这就像有字符串操作就需要频繁处理字符串一样。

  但是第二种缓存数据的方法提供了一种面向对象的方法来缓存。当用户输入新车辆数据时,您将在数组对象中创建一个新元素。不需要任何笨拙的字符串操作。当用户输完所有车辆数据后,您只需构建一个源于该对象的 JSON 字符串,并通过存储到某个隐藏字段中的方式将该字符串发送至服务器。这种方法要比第一种方法好得多。

  JSON、数据缓存和 Ajax 功能

  当使用 JSON 将数据缓存到客户端时,系统将在用户每次单击 Add Vehicle 按钮时更新数据缓存对象。用于完成此项任务的 JavaScript 函数看起来可能跟 清单 5 一样。


CODE:清单 5. 用于将车辆数据添加到 JavaScript 对象中以进行客户端缓存的函数
function addVehicleData() { var brand = //get vehicle brand; var regNo = //get registration number; var cc = //get cc; vehicleData[vehicleData.length] = new Object(); vehicleData[vehicleData.length].brandName = new Object(); vehicleData[vehicleData.length].brandName = brand; //same way update other two properties }

  在这里,vehicleData 是用于在用户装入页面时进行初始化的 JavaScript 变量。它被初始化为一个新的数组对象,该数组对象为空或者含有用户先前输入的车辆的车辆元素。

  当此函数将数据保存到 JavaScript 对象中后,程序可以调用另一个函数来清空输入字段以允许用户输入新数据。

  在此类应用程序中,要求用户输入出现次数最少或出现次数最多的多组或多值属性。您可以将这些限制置入 JSON 元数据对象中。在这种情况下,先前的元数据对象将变为 清单 6 中所示的代码。


CODE:清单 6. 带有出现次数限制的 JSON 元数据对象
var vehicleValidationsMetadata = {    "MIN_OCC":{0},    "MAX_OCC":{10},    "MAX_OCC_MSG":{"...."},    "MIN_OCC_MSG":{".....},    //Everything else is the same }

然后,addVehicleData() 函数将先验证数据的出现次数,然后在仅当总出现次数未超出允许的限制时再将数据添加到 JavaScript 对象中。清单 7 显示了检查方法。


CODE:清单 7. JSON 元数据对象限制检查
function addVehicleData() {   if(vehicleData.length == vehicleValidationsMetadata.MAX_OCC-1) {      alert(vehicleValidationsMetadata.MAX_OCC_MSG);    }  //Everything else is the same }

  当用户提交一个页面时调用的函数实际上用于验证最少的出现次数。这种方法的最大好处是屏幕不需要刷新以输入新车辆数据。提供此类静态屏幕曾经是 Ajax 技术的主要目标,而您现在用 JSON 也能完成此目标。这是关于更新 JSON 数据对象和通过 JavaScript 处理 HTML DOM 树的全部内容。用户响应时间是最小值,因为所有操作仅在客户端上执行。您可以使用 JSON 来为应用程序提供 Ajax 功能。

  当用户单击 Save 按钮时,程序将调用另一个 JavaScript 函数,该函数将把此 JSON 对象 字符串化 并将其存储到程序提交到服务器上的隐藏表字段中。JSON.js(请参阅 参考资料)有一个 JSON.stringify() 函数,该函数将获取 JavaScript 对象作为输入并返回字符串输出。

  服务器端必须能够理解 JSON 形式的字符串并生成一个服务器端对象,以处理和保存数据。Web 站点 http://www.json.org/java/index.html 提供了一个 Java API,该 API 用于处理基于 Java 的应用程序的大部分需求。

结束语
  您在本文中看到了 JSON 的强大用途。归结如下: 
  JSON 提供了一种优秀的面向对象的方法,以便将元数据缓存到客户机上。 
  JSON 帮助分离了验证数据和逻辑。 
  JSON 帮助为 Web 应用程序提供了 Ajax 的本质。

标签:Javascript/Ajax,Web开发,Java | 浏览数(1029) | 评论数(0) | 2009-01-04
Silverlight .XAML切换场景 参数传递  

作者:雪儿
来源:bbs.jishu.me
标题:Silverlight .XAML切换场景 参数传递
问题:
1. page.xaml第一个场景  
1. scene2.xaml第二个场景  
   在资源管理器中增加了一个scene2.xaml文件,
   而Silverlight Application默认是启动的Page.xaml,
   而不会放完page.xaml后播放scene2.xaml文件内容。
   这时如何才能全新的进入第二个scene2.xaml文件呢?  

分析 
  如果在page.xaml场景里的某个事件,不管是storyboard.Completed放完事件,
  还是按扭点击事件里让当前的跟控件换成scene2控件,事实上sl把跟控件作为场景。
实现代码如下:

CODE:C# Code
//通过接口调用UserControl的跟节点,如果不合用此接口,会执行几次后失败! public interface IContent { UIElement Content { get; set; } } public partial class Page : UserControl,IContent { public Page() { InitializeComponent(); this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown); } void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { //scene2是scene2.xaml,因为这里需要直接实例化,并把现在的跟节点替换为新页。 (Application.Current.RootVisual as IContent).Content = new scene2(); } public new UIElement Content { get { return base.Content; } set { base.Content=value; } } }
以上代码来自:WPF之家

标签:Web开发,C#,Silverlight | 浏览数(1645) | 评论数(0) | 2008-12-31
Silverlight里C#绘制Path的方法  

作者:雪儿
来源:bbs.jishu.me
标题:Silverlight里C#绘制Path的方法

以下是C#代码


CODE:C# Code
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace slArrow { public partial class Page : UserControl { public Page() { InitializeComponent(); LayoutRoot.Loaded += new RoutedEventHandler(LayoutRoot_Loaded); } void LayoutRoot_Loaded(object sender, RoutedEventArgs e) { drawArrow(new Point(300, 300)); } public void drawArrow(Point endP) { double slopy; double cosy; double siny; double Par = 8.0; //slopy = Math.atan2((StartP.y-endP.y+20),(StartP.x-endP.x)); slopy=3.1415926; cosy = Math.Cos(slopy); siny = Math.Sin(slopy); PathGeometry aPathGeometry = new PathGeometry(); arrowPath.Data = aPathGeometry; aPathGeometry.Figures = new PathFigureCollection(); PathFigure aPathFigure = new PathFigure(); aPathFigure.StartPoint = endP; LineSegment Line1 = new LineSegment(); LineSegment Line2 = new LineSegment(); LineSegment Line3 = new LineSegment(); Point p1 = new Point(); Point p2 = new Point(); Point p3 = new Point(); p1.X = endP.X + ( Par * cosy - ( Par / 2.0 * siny ) ); p1.Y = endP.Y + ( Par * siny + ( Par / 2.0 * cosy ) ); p2.X = endP.X + ( Par * cosy + Par / 2.0 * siny ); p2.Y = endP.Y - ( Par / 2.0 * cosy - Par * siny ); p3.X = endP.X; p3.Y = endP.Y; Line1.Point = p1; Line2.Point = p2; Line3.Point = p3; aPathFigure.Segments.Add(Line1); aPathFigure.Segments.Add(Line2); aPathFigure.Segments.Add(Line3); aPathGeometry.Figures.Add(aPathFigure); } } }
以下代码放在XAML文档里边

CODE:XAML Code
<UserControl x:Class="slArrow.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <Path x:Name="arrowPath" Stroke="Red" StrokeThickness="4"/> </Grid> </UserControl>
源码下载:下载地址

标签:Web开发,C#,Silverlight | 浏览数(2404) | 评论数(0) | 2008-12-31
Delphi的JSON库 - DJSON- JSONTokener(下)  

作者:杨芹勍
来源:博客园
标题:Delphi的JSON库 - DJSON- JSONTokener(下)

CODE:Delphi源代码:
{ Copyright (c) 2002 JSON.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The Software shall be used for Good, not Evil. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. } { * A JSONTokener takes a source string and extracts characters and tokens from * it. It is used by the JSONObject and JSONArray constructors to parse * JSON source strings. * @author JSON.org * @version 2 } unit JSONTokener; interface uses   SysUtils,   StrUtils,   AutoPtr,    JSONException; type   TJSONTokener = class   private     fMyIndex: Integer;     fMySource: string;   public     constructor Create(aMySource: string); virtual;     procedure Back;     class function DeHexChar(c: Char): Integer;     function More: Boolean;     function Next: Char; overload;     function Next(c: Char): Char; overload;     function Next(n: Integer): string; overload;     function SyntaxError(aMsg: string): EJSONException;     function ToString: string; override;     function NextClean: Char;     function NextString(quote: Char): string;     function NextTo(d: Char): string; overload;     function NextTo(delimiters: string): string; overload;     function NextValue: IAutoPtr<TObject>;     function SkipTo(toc: Char): Char;     function SkipPast(tos: string): Boolean;   end; implementation uses   StringObject,   BooleanObject,   IntegerObject,   LongObject,   DoubleObject,   Utils,   JSONObject,   JSONArray; { TJSONTokener } procedure TJSONTokener.Back; begin   if fMyIndex > 0 then     Dec(fMyIndex); end; constructor TJSONTokener.Create(aMySource: string); begin   inherited Create;   fMyIndex := 0;   fMySource := aMySource; end; class function TJSONTokener.DeHexChar(c: Char): Integer; begin   if (c >= '0') and (c <= '9') then     Exit(Ord(c) - Ord('0'));   if (c >= 'A') and (c <= 'F') then     Exit(Ord(c) - (Ord('A') - 10));   if (c >= 'a') and (c <= 'f') then     Exit(Ord(c) - (Ord('a') - 10));   Result := -1; end; function TJSONTokener.More: Boolean; begin   Result := fMyIndex < Length(fMySource); end; function TJSONTokener.Next(n: Integer): string; var   i, j: Integer; begin   i := fMyIndex;   j := i + Ord(n);   if j >= Length(fMySource) then     raise SyntaxError('Substring bounds error');   Inc(fMyIndex, n);   Result := SubString(fMySource, i, j); end; function TJSONTokener.NextClean: Char; var   c: Char; begin   while True do   begin     c := Next;     if Ord(c) = Ord('/') then     begin       case Next of         '/':         begin           repeat             c := Next;           until (Ord(c) = 13) or (Ord(c) = 10) or (Ord(c) = 0);         end;         '*':         begin           while True do           begin             c := Next;             if Ord(c) = 0 then               raise SyntaxError('Unclosed comment');             if Ord(c) = Ord('*') then             begin               if Ord(Next) = Ord('/') then                 Break;               Back;             end;           end;         end;         else begin           Back;           Exit('/');         end;       end;     end     else if Ord(c) = Ord('#') then     begin       repeat         c := Next;       until (Ord(c) = 13) or (Ord(c) = 10) or (Ord(c) = 0);     end     else if (Ord(c) = 0) or (Ord(c) > Ord(' ')) then     begin       Exit(c);     end;   end; end; function TJSONTokener.NextString(quote: Char): string; var   c: Char; begin   while True do   begin     c := Next;     case c of       #0, #13, #10:       begin         raise SyntaxError('Unterminated string');       end;       #92: // ''       begin         c := Next;         case c of           'b': Result := Result + #8;           't': Result := Result + #9;           'n': Result := Result + #10;           'f': Result := Result + #12;           'r': Result := Result + #13;           'u': Result := Result + Char(StrToInt('$' + Next(4)));           'x': Result := Result + Char(StrToInt('$' + Next(2)));           else begin             Result := Result + c;           end;         end;       end;       else begin         if Ord(c) = Ord(quote) then           Exit;         Result := Result + c;       end;     end;   end; end; function TJSONTokener.NextTo(delimiters: string): string; var   c: Char; begin   while True do   begin     c := Next;     if (Pos(c, delimiters) >= 1) or (Ord(c) = 0) or       (Ord(c) = 13) or (Ord(c) = 10) then     begin       if Ord(c) <> 0 then         Break;       Exit(Trim(Result));     end;     Result := Result + c;   end; end; function TJSONTokener.NextValue: IAutoPtr<TObject>; var   c, b: Char;   s, sb: string; begin   c := NextClean;   case c of     '"', '''': Exit(TAutoPtr<TObject>.New(TStringObject.Create(NextString(c))));     '{':     begin       Back;       Exit(TAutoPtr<TObject>.New(TJSONObject.Create(Self)));     end;     '[', '(':     begin       Back;       Exit(TAutoPtr<TObject>.New(TJSONArray.Create(Self)));     end;   end;   {    /*      * Handle unquoted text. This could be the values true, false, or      * null, or it can be a number. An implementation (such as this one)      * is allowed to also accept non-standard forms.      *      * Accumulate characters until we reach the end of the text or a      * formatting character.      */   }   b := c;   while (Ord(c) >= Ord(' ')) and (Pos(c, ',:]}/"[{;=#') < 1) do   begin     sb := sb + c;     c := Next;   end;   Back;   // If it is true, false, or null, return the proper value.   s := Trim(sb);   if Length(s) = 0 then     raise SyntaxError('Missing value');   if LowerCase(s) = 'true' then     Exit(TAutoPtr<TObject>.New(TBooleanObject.TRUE));   if LowerCase(s) = 'false' then     Exit(TAutoPtr<TObject>.New(TBooleanObject.FALSE));   if LowerCase(s) = 'null' then     Exit(TAutoPtr<TObject>.New(TJSONObject.NULL));   {     /*      * If it might be a number, try converting it. We support the 0- and 0x-      * conventions. If a number cannot be produced, then the value will just      * be a string. Note that the 0-, 0x-, plus, and implied string      * conventions are non-standard. A JSON parser is free to accept      * non-JSON forms as long as it accepts all correct JSON forms.      */   }   if ((Ord(b) >= Ord('0')) and (Ord(b) <= Ord('9')))     or (Ord(b) = Ord('.'))     or (Ord(b) = Ord('-'))     or (Ord(b) = Ord('+')) then   begin     if Ord(b) = Ord('0') then     begin       if (Length(s) > 2) and ((s[2] = 'x') or (s[2] = 'X')) then       begin         try           Exit(TAutoPtr<TObject>.New(TIntegerObject.Create(             StrToInt('$' + SubString(s, 2)))));         except           // Ignore the error         end;       end       else       begin         try           Exit(TAutoPtr<TObject>.New(TIntegerObject.Create(             Utils.Base8(s))));         except         end;       end;     end;     try       Exit(TAutoPtr<TObject>.New(TIntegerObject.Create(         StrToInt(s))));     except       try         Exit(TAutoPtr<TObject>.New(TLongObject.Create(           StrToInt64(s))));       except         try           Exit(TAutoPtr<TObject>.New(TDoubleObject.Create(             StrToFloat(s))));         except           Exit(TAutoPtr<TObject>.New(TStringObject.Create(s)));         end;       end;     end;   end;   Exit(TAutoPtr<TObject>.New(TStringObject.Create(s))); end; function TJSONTokener.NextTo(d: Char): string; var   c: Char; begin   while True do   begin     c := Next;     if (Ord(c) = Ord(d)) or (Ord(c) = 0) or (Ord(c) = 13) or (Ord(c) = 10) then     begin       if Ord(c) <> 0 then         Break;       Exit(Trim(Result));     end;     Result := Result + c;   end; end; function TJSONTokener.SkipPast(tos: string): Boolean; begin   fMyIndex := PosEx(tos, fMySource, fMyIndex) - 1;   if fMyIndex < 0 then   begin     fMyIndex := Length(fMySource);     Exit(False);   end;   Inc(fMyIndex, Length(tos));   Result := True; end; function TJSONTokener.SkipTo(toc: Char): Char; var   c: Char;   index: Integer; begin   index := fMyIndex;   repeat     c := Next;     if Ord(c) = 0 then     begin       fMyIndex := index;       Exit(c);     end;   until Ord(c) = Ord(toc);   Back;   Result := c; end; function TJSONTokener.SyntaxError(aMsg: string): EJSONException; begin   Result := EJSONException.Create(aMsg + ToString); end; function TJSONTokener.ToString: string; begin   Result := ' at character ' + IntToStr(fMyIndex) + ' of ' + fMySource; end; function TJSONTokener.Next(c: Char): Char; var   n: Char; begin   n := Next;   if Ord(n) <> Ord(c) then     raise EJSONException.Create('Expected ''' + c + ''' and instead saw ''' + n + '''');   Result := n; end; function TJSONTokener.Next: Char; var   c: Char; begin   if More then   begin     c := fMySource[fMyIndex];     Inc(fMyIndex);     Exit(c);   end;   Result := #0; end;

标签:Web开发,Java,jQuery | 浏览数(1186) | 评论数(0) | 2008-12-31
Delphi的JSON库 - DJSON- JSONTokener(上)  

作者:杨芹勍
来源:博客园
标题:Delphi的JSON库 - DJSON- JSONTokener(上)
1、Java支持垃圾回收,Delphi不支持,在此我使用Delphi中的智能指针替代。
2、Java中有Boolean、Integer、Long等类,Delphi没有,
   我便按照Java的方法分别创建了TBooleanObject、TIntegerObject、TLongObject等类。
3、在C语法和Pascal语法之间切换,头有点疼……

但我已下定决心把DJson做完!

现在用Delphi的人不多,原因有两点:
1、公司管理层的问题。
2、关于Delphi相关成熟的库太少。

既然第一点已经无法挽回,那就让我们在第二点上做努力吧!

CODE:首先贴出Java源代码
 1package org.json;
 2
 3/**//*
 4 * Copyright (c) 2002 JSON.org
 5 * 
 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
 7 * of this software and associated documentation files (the "Software"), to deal
 8 * in the Software without restriction, including without limitation the rights
 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 * 
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 * 
16 * The Software shall be used for Good, not Evil.
17 * 
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27/**
28 * A JSONTokener takes a source string and extracts characters and tokens from
29 * it. It is used by the JSONObject and JSONArray constructors to parse
30 * JSON source strings.
31 * @author JSON.org
32 * @version 2
33 */
34public class JSONTokener {
35
36  /** *//**
37   * The index of the next character.
38   */
39  private int myIndex;
40
41
42  /** *//**
43   * The source string being tokenized.
44   */
45  private String mySource;
46
47
48  /** *//**
49   * Construct a JSONTokener from a string.
50   *
51   * @param s   A source string.
52   */
53  public JSONTokener(String s) {
54    this.myIndex = 0;
55    this.mySource = s;
56  }
57
58
59  /** *//**
60   * Back up one character. This provides a sort of lookahead capability,
61   * so that you can test for a digit or letter before attempting to parse
62   * the next number or identifier.
63   */
64  public void back() {
65    if (this.myIndex > 0) {
66      this.myIndex -= 1;
67    }
68  }
69
70
71
72  /** *//**
73   * Get the hex value of a character (base16).
74   * @param c A character between '0' and '9' or between 'A' and 'F' or
75   * between 'a' and 'f'.
76   * @return An int between 0 and 15, or -1 if c was not a hex digit.
77   */
78  public static int dehexchar(char c) {
79    if (c >= '0' && c <= '9') {
80      return c - '0';
81    }
82    if (c >= 'A' && c <= 'F') {
83      return c - ('A' - 10);
84    }
85    if (c >= 'a' && c <= 'f') {
86      return c - ('a' - 10);
87    }
88    return -1;
89  }
90
91
92  /** *//**
93   * Determine if the source string still contains characters that next()
94   * can consume.
95   * @return true if not yet at the end of the source.
96   */
97  public boolean more() {
98    return this.myIndex < this.mySource.length();
99  }
100
101
102  /** *//**
103   * Get the next character in the source string.
104   *
105   * @return The next character, or 0 if past the end of the source string.
106   */
107  public char next() {
108    if (more()) {
109      char c = this.mySource.charAt(this.myIndex);
110      this.myIndex += 1;
111      return c;
112    }
113    return 0;
114  }
115
116
117  /** *//**
118   * Consume the next character, and check that it matches a specified
119   * character.
120   * @param c The character to match.
121   * @return The character.
122   * @throws JSONException if the character does not match.
123   */
124  public char next(char c) throws JSONException {
125    char n = next();
126    if (n != c) {
127      throw syntaxError("Expected '" + c + "' and instead saw '" +
128          n + "'");
129    }
130    return n;
131  }
132
133
134  /** *//**
135   * Get the next n characters.
136   *
137   * @param n   The number of characters to take.
138   * @return   A string of n characters.
139   * @throws JSONException
140   *  Substring bounds error if there are not
141   *  n characters remaining in the source string.
142   */
143   public String next(int n) throws JSONException {
144     int i = this.myIndex;
145     int j = i + n;
146     if (j >= this.mySource.length()) {
147      throw syntaxError("Substring bounds error");
148     }
149     this.myIndex += n;
150     return this.mySource.substring(i, j);
151   }
152
153
154  /** *//**
155   * Get the next char in the string, skipping whitespace
156   * and comments (slashslash, slashstar, and hash).
157   * @throws JSONException
158   * @return A character, or 0 if there are no more characters.
159   */
160  public char nextClean() throws JSONException {
161    for (;;) {
162      char c = next();
163      if (c == '/') {
164        switch (next()) {
165        case '/':
166          do {
167            c = next();
168          } while (c != 'n' && c != 'r' && c != 0);
169          break;
170        case '*':
171          for (;;) {
172            c = next();
173            if (c == 0) {
174              throw syntaxError("Unclosed comment");
175            }
176            if (c == '*') {
177              if (next() == '/') {
178                break;
179              }
180              back();
181            }
182          }
183          break;
184        default:
185          back();
186          return '/';
187        }
188      } else if (c == '#') {
189        do {
190          c = next();
191        } while (c != 'n' && c != 'r' && c != 0);
192      } else if (c == 0 || c > ' ') {
193        return c;
194      }
195    }
196  }
197
198
199  /** *//**
200   * Return the characters up to the next close quote character.
201   * Backslash processing is done. The formal JSON format does not
202   * allow strings in single quotes, but an implementation is allowed to
203   * accept them.
204   * @param quote The quoting character, either
205   *   " (double quote) or
206   *   ' (single quote).
207   * @return   A String.
208   * @throws JSONException Unterminated string.
209   */
210  public String nextString(char quote) throws JSONException {
211    char c;
212    StringBuffer sb = new StringBuffer();
213    for (;;) {
214      c = next();
215      switch (c) {
216      case 0:
217      case 'n':
218      case 'r':
219        throw syntaxError("Unterminated string");
220      case '':
221        c = next();
222        switch (c) {
223        case 'b':
224          sb.append('b');
225          break;
226        case 't':
227          sb.append('t');
228          break;
229        case 'n':
230          sb.append('n');
231          break;
232        case 'f':
233          sb.append('f');
234          break;
235        case 'r':
236          sb.append('r');
237          break;
238        case 'u':
239          sb.append((char)Integer.parseInt(next(4), 16));
240          break;
241        case 'x' :
242          sb.append((char) Integer.parseInt(next(2), 16));
243          break;
244        default:
245          sb.append(c);
246        }
247        break;
248      default:
249        if (c == quote) {
250          return sb.toString();
251        }
252        sb.append(c);
253      }
254    }
255  }
256
257
258  /** *//**
259   * Get the text up but not including the specified character or the
260   * end of line, whichever comes first.
261   * @param d A delimiter character.
262   * @return  A string.
263   */
264  public String nextTo(char d) {
265    StringBuffer sb = new StringBuffer();
266    for (;;) {
267      char c = next();
268      if (c == d || c == 0 || c == 'n' || c == 'r') {
269        if (c != 0) {
270          back();
271        }
272        return sb.toString().trim();
273      }
274      sb.append(c);
275    }
276  }
277
278
279  /** *//**
280   * Get the text up but not including one of the specified delimeter
281   * characters or the end of line, whichever comes first.
282   * @param delimiters A set of delimiter characters.
283   * @return A string, trimmed.
284   */
285  public String nextTo(String delimiters) {
286    char c;
287    StringBuffer sb = new StringBuffer();
288    for (;;) {
289      c = next();
290      if (delimiters.indexOf(c) >= 0 || c == 0 ||
291          c == 'n' || c == 'r') {
292        if (c != 0) {
293          back();
294        }
295        return sb.toString().trim();
296      }
297      sb.append(c);
298    }
299  }
300
301
302  /** *//**
303   * Get the next value. The value can be a Boolean, Double, Integer,
304   * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
305   * @throws JSONException If syntax error.
306   *
307   * @return An object.
308   */
309  public Object nextValue() throws JSONException {
310    char c = nextClean();
311    String s;
312
313    switch (c) {
314      case '"':
315      case ''':
316        return nextString(c);
317      case '{':
318        back();
319        return new JSONObject(this);
320      case '[':
321      case '(':
322        back();
323        return new JSONArray(this);
324    }
325
326    /**//*
327     * Handle unquoted text. This could be the values true, false, or
328     * null, or it can be a number. An implementation (such as this one)
329     * is allowed to also accept non-standard forms.
330     *
331     * Accumulate characters until we reach the end of the text or a
332     * formatting character.
333     */
334
335    StringBuffer sb = new StringBuffer();
336    char b = c;
337    while (c >= ' ' && ",:]}/"[{;=#".indexOf(c) < 0) {
338      sb.append(c);
339      c = next();
340    }
341    back();
342
343    /**//*
344     * If it is true, false, or null, return the proper value.
345     */
346
347    s = sb.toString().trim();
348    if (s.equals("")) {
349      throw syntaxError("Missing value");
350    }
351    if (s.equalsIgnoreCase("true")) {
352      return Boolean.TRUE;
353    }
354    if (s.equalsIgnoreCase("false")) {
355      return Boolean.FALSE;
356    }
357    if (s.equalsIgnoreCase("null")) {
358      return JSONObject.NULL;
359    }
360
361    /**//*
362     * If it might be a number, try converting it. We support the 0- and 0x-
363     * conventions. If a number cannot be produced, then the value will just
364     * be a string. Note that the 0-, 0x-, plus, and implied string
365     * conventions are non-standard. A JSON parser is free to accept
366     * non-JSON forms as long as it accepts all correct JSON forms.
367     */
368
369    if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
370      if (b == '0') {
371        if (s.length() > 2 &&
372            (s.charAt(1) == 'x' || s.charAt(1) == 'X')) {
373          try {
374            return new Integer(Integer.parseInt(s.substring(2),
375                16));
376          } catch (Exception e) {
377            /**//* Ignore the error */
378          }
379        } else {
380          try {
381            return new Integer(Integer.parseInt(s, 8));
382          } catch (Exception e) {
383            /**//* Ignore the error */
384          }
385        }
386      }
387      try {
388        return new Integer(s);
389      } catch (Exception e) {
390        try {
391          return new Long(s);
392        } catch (Exception f) {
393          try {
394            return new Double(s);
395          } catch (Exception g) {
396            return s;
397          }
398        }
399      }
400    }
401    return s;
402  }
403
404
405  /** *//**
406   * Skip characters until the next character is the requested character.
407   * If the requested character is not found, no characters are skipped.
408   * @param to A character to skip to.
409   * @return The requested character, or zero if the requested character
410   * is not found.
411   */
412  public char skipTo(char to) {
413    char c;
414    int index = this.myIndex;
415    do {
416      c = next();
417      if (c == 0) {
418        this.myIndex = index;
419        return c;
420      }
421    } while (c != to);
422    back();
423    return c;
424  }
425
426
427  /** *//**
428   * Skip characters until past the requested string.
429   * If it is not found, we are left at the end of the source.
430   * @param to A string to skip past.
431   */
432  public boolean skipPast(String to) {
433    this.myIndex = this.mySource.indexOf(to, this.myIndex);
434    if (this.myIndex < 0) {
435      this.myIndex = this.mySource.length();
436      return false;
437    }
438    this.myIndex += to.length();
439    return true;
440
441  }
442
443
444  /** *//**
445   * Make a JSONException to signal a syntax error.
446   *
447   * @param message The error message.
448   * @return A JSONException object, suitable for throwing
449   */
450  public JSONException syntaxError(String message) {
451    return new JSONException(message + toString());
452  }
453
454
455  /** *//**
456   * Make a printable string of this JSONTokener.
457   *
458   * @return " at character [this.myIndex] of [this.mySource]"
459   */
460  public String toString() {
461    return " at character " + this.myIndex + " of " + this.mySource;
462  }
463}

标签:Web开发,Java,jQuery | 浏览数(1140) | 评论数(0) | 2008-12-31
解读System.Web.UI.Page中关键方法ProcessRequestMain()  

作者:dudu
来源:http://www.cnblogs.com/dudu
标题:解读System.Web.UI.Page中关键方法ProcessRequestMain() 

为了更好地优化博客园程序的性能,最近我在优化代码的同时,更深入地去研究asp.net的源代码。asp.net的源代码通过Reflector工具一鉴无遗, 虽然不是原版的代码, 但已经足够了,其中的原理与思想已经清楚地摆在我们面前。这是.NET开发人员的幸运!

在我们开发asp.net应用程序时, System.Web.UI.Page是我们最熟悉并用的最多的一个类。但有多少人真正对这个类的源代码仔细研究过? 从相关搜索中可以看出并不是很多, 比如,用Google搜索ProcessRequestMain方法中开始的“OnPageStartSessionObjects”,结果只有四个。

今天我花了半天时间,研究了Page中处理请求的最关键的方法:ProcessRequestMain(),在这里我将自己的理解写出来与大家共享,欢迎大家批评并指正。一切尽在代码注释 中:

注:为了方便阅读与理解,已去掉源代码中输出Trace信息的部分。


CODE:
public class Page { private void ProcessRequestMain() { try { if (this.IsInAspCompatMode) { AspCompatApplicationStep.OnPageStartSessionObjects(); } //将当前Context的Session中的对象传递给asp的OnStartPage //通过<%@ ASPCOMPAT="true" %>进行设置 //参考文章: http://samples.gotdotnet.com/quickstart/aspplus/doc/cominterop.aspx this._requestValueCollection = this.DeterminePostBackMode(); //检查PostBackMode, 如果启用了PostBack, 获取VIEWSTATE数据并赋值给_requestValueCollection base.InitRecursive(null); //调用基类的InitRecursive方法通过递归对子控件进行初始化, 比如: 生成控件ID,设置控件的Page属性。 //OnInit()方法将会在此时被调用 if (this.IsPostBack) { this.LoadPageViewState(); //从_requestValueCollection通过反序列化载入视图状态数据, //如果页面的Layout发生了改变,子控件重新递归载入(LoadViewStateRecursive)视图状态 //载入后,从视图状态数据从得到所有要处理PostBack的控件并注册到_controlsRequiringPostBack. this.ProcessPostData(this._requestValueCollection, true); //处理PostBack数据, 从PostBack数据中得到所有控件ID并检查每个控件, //如果不能在当前页面中找到该控件(FindControl), 将其存入_leftoverPostData. //如果存在该控件,继续检查,若该控件没有实现IPostBackDataHandler, //但实现了 IPostBackEventHandler,注册该控件进行事件处理。 //若该控件实现了System.Web.UI.IPostBackDataHandler, //该控件的LoadPostData()方法在此时被调用,并将其加入到_changedPostDataConsumers, //并从._controlsRequiringPostBack(LoadPageViewState时对它进行了赋值)中移除该控件. //这样就从_controlsRequiringPostBack中移除了所有实现IPostBackDataHandler接口的控件. //接着继续对 _controlsRequiringPostBack中余下的控件进行处理, //但奇怪的是又对这些余下的控件检查是否存在并实现了IPostBackDataHandler, 如果实现, //调用该控件的LoadPostData()(有点多此一举了, 可能是Relector生成的代码有误) //并放入_changedPostDataConsumers,如果没实现,放入一个新ArrayList变量, //检查结束后,将其赋值给_controlsRequiringPostBack. //那现在_controlsRequiringPostBack中剩下什么呢?没有实现IPostBackDataHandler, //但实现了 IPostBackEventHandler的控件以及没有被Load的控件, // 也就是在PostBack数据中存在但FindControl没有找到的控件。 //为什么会有找不到的控件呢?我们这里需要注意的是OnLoad()事件还没执行, //有些控件还没有被加载.下面的base.LoadRecursive()就是触发OnLoad()事件的。 } base.LoadRecursive(); //触发页面的OnLoad()事件->递归触发子控件的OnLoad()事件->将 //页面的_controlState状态设置为ControlState.Loaded if (this.IsPostBack) { this.ProcessPostData(this._leftoverPostData, false); //理解了ProcessPostData(this._requestValueCollection, true)之后, //这个就很好理解了,就是检查_controlsRequiringPostBack中的控件是否存在并实现了 //IPostBackDataHandler, 如果实现,调用该控件的LoadPostData()方法并将其加入 //到_changedPostDataConsumers.ProcessPostData(this._leftoverPostData, false) //这个方法就是为OnLoad()之后加载的控件服务的。 } this.RaiseChangedEvents(); //在_changedPostDataConsumers(在两个ProcessPostData方法中向它添加了数据) //中没有实现IPostBackDataHandler接口的控件触发RaisePostDataChangedEvent. this.RaisePostBackEvent(this._requestValueCollection); //触发_registeredControlThatRequireRaiseEvent及PostBack数据中 //实现IPostBackEventHandler接口的控件的RaisePostBackEvent事件。 base.PreRenderRecursiveInternal(); //首先调用EnsureChildControls,检查子控件是否创建, //如果没有, 调用进行创建CreateChildControls. //触发OnPreRende事件. //递归调用子控件的PreRenderRecursiveInternal方法 //设置._controlState为 ControlState.PreRendered this.SavePageViewState(); //保存视图状态数据至._viewStateToPersist base.RenderControl(this.CreateHtmlTextWriter(this.Response.Output)); //输出当前及所有子控件的内容 } catch (ThreadAbortException) { base.UnloadRecursive(true); return; } catch (ConfigurationException) { throw; } catch (Exception exception1) { PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_DURING_REQUEST); PerfCounters.IncrementCounter(AppPerfCounter.ERRORS_TOTAL); if (!this.HandleError(exception1)) { throw; } return; } } }

标签:Web开发 | 浏览数(1926) | 评论数(0) | 2008-12-22
  • 共 36 文章
  • 1
  • 2
  • 3
  • >

Powered by Haiwit