
在某个论坛上看到有人在问——“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
我还可以再写去,因为今天我还没有足够的愤怒。
跟着这个思路,我也补充几条吧,
呵呵,欢迎留下你的回答!
来源:http://coolshell.cn/?p=2402
ASP.Net的Application
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还能在另外一台主机上保持。
来源于:互联网
作者: 来源:来自“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:需要切换页面的事件响应方法中最后,我们需要修改app.xaml.cs中的Application_Startup方法,修改起始页面
CODE:app.xaml.cs使用部分代码
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());
}
作者:大师 来源:互联网 标题: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 就是了!
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>
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,如果找不到就抛出异常。
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"%>
由于我自己也遇上这问题
本文来源于互联网上
作者:佚名 来源:希赛网 标题: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错误,主要原因是对系统所访问外部资源,未执行关闭操作,导致外部资源大量浪费,最终可能导致系统无法正常运行;对系统所访问的外部资源关闭次数太多,外部系统无法正常处理;所系统访问的外部资源出现异常情况。
解决的方法是:访问外部资源前,首先检查该资源(如数据库)是否可正常连接或操作;访问外部资源时,如果进行了连接,一定进行关闭操作,并仅进行一次关闭操作;尽量在同一操作中共享外部资源,以减少该操作对资源的消费,提高程序的执行效率。
作者:Bakul L. Patel 来源:developerWorks 标题:用 JSON 处理缓存
数据验证是每个企业 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 页面的标题部分中,然后编写以下警报:
如果在任何支持 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 的本质。
作者:雪儿 来源: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之家
作者:雪儿 来源: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>
源码下载:下载地址
作者:杨芹勍 来源:博客园 标题: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;
作者:杨芹勍 来源:博客园 标题: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}
作者: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;
}
}
}
Powered by Haiwit