[Flex]用Anvil构建企业级Flex应用

mikel阅读(1014)

download:http://www.ohloh.net/projects/anvilflex/download?filename=anvil-0.5.1.zip

OVERVIEW

Anvil was designed to help make enterprise flex projects easier and to provide a portal environment for running flex applications.  Today Anvil best serves as a sample of how to build enterprise applications.  We are working on making it easier to quickly create a customized environment for flex.

What we have found was the biggest challenge with developing a large enterprise framework was how to cleanly divide the application into multiple modules that can be built, maintained and loaded separately.  One of the primary challenges with multiple modules is how to cleanly separate the handling of non-visual events.  An example would be having one module call a service in another module.  Another issue we ran into was how to isolate events with-in a module, especially if there is multiple copies of the same module in an application.  An example of this is when you have a portal framework where the user can display the same sub-window multiple times.  The standard event dispatcher does not work for these cases and most frameworks do not handle this situation either.  For example the popular cairngorm framework was designed to only work in a monolthic environment and event handling gets messed up when you have duplicate copies of a module.

Anvil comes with two sample applications to help you get started.  One is a basic sample in the basicSample directory and the other is Anvil Portal in the anvilPortal directory.  The biggest difference is the basic sample does not use any security.  The anvil/dist directory has pre-built war files so you can easily see what basic Anvil applications look like.

The anvil/dist directory also contains compiled distribution files of the core Shell flex library, the FlexMDI flex library, the shell and utility jar files and the war files for the basic sample and anvil portal.

In the shell directory is the core library files of Anvil for both the Flex and Java side.  Then in the layouts directory is the primary visual layout library, FlexMDI, based on code from the Flex Lib project.

The utils directory contains a Java project with a number of utilities for working with Flex.  This includes a tool to create ActionScript Data Objects from Java Data Objects.  Another utility is Taz, a flex compiler built on top of mxmlc and compc that makes compiling large projects much faster and easier.  There are samples of how to call Taz from ant build scripts.  And the final utility is a FlexBuilder project file generator.

QUICK START

For the impatient here is a quick overview of setting up the sample applications.  Install Java and Tomcat to just run the samples.  We have a detailed post on this here.  Also install Flex and Ant to build the samples.  Be sure to setup the appropriate home environment variables, like JAVA_HOME, CATALINA_HOME, ANT_HOME and FLEX_HOME.

You can copy the sample war files out of the dist directory into your favorite servlet container.   Then to run anvil use the following url in your browser:
http://localhost:8080/anvilPortal/

To rebuild the application you can run ant at any directory level. So running ant under shell will re-compile the shell and under anvilPortal will rebuild the sample.  Running ant war  will rebuild the war files under anvilPortal/build and basicSample/build.

SETTING UP FLEX BUILDER

To setup the Flex Builder project files for any subproject, cd to that directory and modify anvil.conf.  Probally the only change will be to where you want it to output files and then run:
ant gen-proj

This will also work from the top level directory.

If you want to reset your project files run:
ant clear-proj

Then in Flex Builder go to file -> import -> other and then under General choose Existing Projects into Workspace. For the root directory first choose shell.  Once you have shell imported and build, then import FlexMDI, anvilPortal and basicSample.

USING THE ANVIL UTILITIES

Both the Taz compiler wrapper and the FlexBuilder project file generator use the same config files.  The root config file is called anvil.conf and contains the default values, like output directory and the order library files should be compiled in.

Then each project directory has its own config file, like anvilPortal.conf or basicSample.conf.  This contains information about each application, module or library.

The files are very short and simplistic, hopefuly making it easy to configure new projects.
To run the taz compiler there is a common ant macro definition in flex.ant.xml called <anvil.taz/>.

For an example of using it see the anvilPortal build.xml file.

To run the actionScript project generators there is a script in the root directory called runAsGen.sh.
This has the following parameters
1 – the input directory of the compiler java class files.  By default it is in out/production/shell
2 – the library directories to scan for the necessary jar files
3 – the output directory – this defaults to newAsClasses

BUILDING YOUR OWN APPLICATION BASED ON ANVIL

By using the AnvilPortal framework as a template, you can jumpstart a Flex Application with a Java, Spring, and Spring Security back end.  For now it requires a little bit of tedious copy and pasting, but hopefully in the future we can automate it with Maven.

First set up the basic directory structure for your project and then copy in the necessary files from Anvil.  The way anvil portal is organized is their is one directory for each module and then inside of there a src/flex and src/java.

As you copy across the files, you will want to get rid of the .svn directories.  The easiest way to do this is run this command from the starting directory of the project, before you import it into SVN!
find . -name ‘.svn’ | xargs rm -rf

Be sure to not put a * at the end, that will delete a lot more than expected!

Based on the AnvilPortal sample there are several file and directories we are going to need:

1 – The common ant build files from the anvil/dist:
flex.ant.xml    java.ant.xml    utils.ant.xml
2 – The config files from anvil/anvilPortal/etc – these are use to configure the basic security and java application options
3 – The /anvil/anvilPortal/web directory – be sure to delete the crossdomain.xml file!  These file configure BlazeDS remoting and the starting web page
4 – From the main /anvil/anvilPortal directory copy the following files:
anvil.conf  – This file configures the anvil compile process and the eclipse project file generator
common.ant.xml  –  This defines the common ant build tasks for the project.  This makes it easier to reuse ant tasks across multiple modules.
build.properties  – This defines the basic build properties
build.xml – The main build file

Now we need to modify the files to fit the new project.  Here is a list of recommended changes:

1 – build.properties – change the project.name.  Also if you want to use a non-standard directory layout you can change where the files are located in this file.  project.root is the parent folder of the project.  project.tail is the directory of the current module that is being compiled.
2 – In build.xml change anvil.root to point to the same directory as the project.root (or even better you could do a global search and replace across the entire project and replace anvil.root with project.root).
3 – Now in build.xml change the project name and the name of modules you are defining.
4 – Modify the config files in the etc directory according to your project.

[礼物]情人节:给另一半的10件礼物

mikel阅读(833)

1、用糖豆制作的内衣


  这些都是实实在在的能吃的糖豆,水果口味,每套用330可糖豆制成,售价20美元。

    

 

    2、“说你爱我”枕头


  同床时这句话好说,分隔两地时,可以用这个枕头来歪歪。。。售价36美元。

    

 

 

     3、8位色T恤


  两件T恤带有感应装置,当靠近时,T恤上的红心就会亮起,售价25美元。

 

    

 

    4、另一半的唠叨


  如果没人跟你拌嘴的话,生活也许过的没那么滋润了,当你们分隔两地时,听不到他或她的唠叨感觉空虚,咋办?用这个遥控,摁一下,就响起各种各样的声音:“听我说!”“你在想什么!?”“把走廊打扫干净!”每套售价36美元。

    

 

     5、男女钥匙孔


  放钥匙用的,位置容易引起一阵歪歪。。。每套售价34美元。

   

 

    6、心跳抱枕


  每个售价45美元,抱紧它,就会听到模拟心跳的声音,而且心率会逐渐跟你一致。看恐怖片时最好不要抱着它。

   

 

    7、个性化闹钟


  可手写或贴纸的指针,表盘,24小时都由你定制。每套售价40美元。

   

 

    8、戒指马克杯


  如果你对另一半有所期盼,可以用这个小杯子来暗示他:该结婚了!快去买戒指!每个杯子卖15美元。

   

 

    9、男友肩膀枕头


  每个售价40美元,当男朋友不在身边时,这个是不错的替代品。

   

 

    10、超大充气红心


  售价14美元,其实我见过更大的,只不过没这个做的这么精致。

   

 

[正则表达式]电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号)

mikel阅读(852)

((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
匹配格式:
11位手机号码
3-4位区号,7-8位直播号码,1-4位分机号
如:12345678901、1234-12345678-1234

"^\d+$"  //非负整数(正整数 + 0) 
"^[0-9]*[1-9][0-9]*$"  //正整数 
"^((-\d+)|(0+))$"  //非正整数(负整数 + 0) 
"^-[0-9]*[1-9][0-9]*$"  //负整数 
"^-?\d+$"    //整数 
"^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0) 
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数 
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0) 
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点
数 
"^(-?\d+)(\.\d+)?$"  //浮点数 
"^[A-Za-z]+$"  //由26个英文字母组成的字符串 
"^[A-Z]+$"  //由26个英文字母的大写组成的字符串 
"^[a-z]+$"  //由26个英文字母的小写组成的字符串 
"^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串 
"^\w+$"  //由数字、26个英文字母或者下划线组成的字符串 
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址 
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url 
/^13\d{9}$/gi手机号正则表达式
public static bool IsValidMobileNo(string MobileNo)
  {
   const string regPattern = @"^(130|131|132|133|134|135|136|137|138|139)\d{8}$";
   return Regex.IsMatch(MobileNo, regPattern);
  }
正则表达式–验证手机号码:13[0-9]{9}
实现手机号前带86或是+86的情况:^((\+86)|(86))?(13)\d{9}$
电话号码与手机号码同时验证:(^(\d{3,4}-)?\d{7,8})$|(13[0-9]{9}) 
提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F)  *=  *('|")?(\w|\\|\/|\.)+('|"|  *|>)?  
提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*  
提取信息中的图片链接:(s|S)(r|R)(c|C)  *=  *('|")?(\w|\\|\/|\.)+('|"|  *|>)?
提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+)    
提取信息中的中国手机号码:(86)*0*13\d{9}    
提取信息中的中国固定电话号码:(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}    
提取信息中的中国电话号码(包括移动和固定电话):(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}    
提取信息中的中国邮政编码:[1-9]{1}(\d+){5}    
提取信息中的中国身份证号码:\d{18}|\d{15}    
提取信息中的整数:\d+    
提取信息中的浮点数(即小数):(-?\d*)\.?\d+    
提取信息中的任何数字  :(-?\d*)(\.\d+)?  
提取信息中的中文字符串:[\u4e00-\u9fa5]*    
提取信息中的双字节字符串  (汉字):[^\x00-\xff]*

[技术]Open API分析、实践和思索

mikel阅读(905)

作者 岑文初 发布于 2009年2月6日 下午6时0分

SOA、SAAS、云计算等等热捧概念词汇层出不穷,也让很多开发者去重新审视未来的软件开发将会何去何从。而Open API的出现,其实已经给国外的互连网应用开发者带来了一种新的创新思维,一种新的开发模式,将SOA的信息互通的理念贯穿到整个互连网行业,让更多的“ 草根”开发者用创新思维将互联网信息的价值最大化。

对于国内的开发者来说,在SNS热潮中第一次接触了Open API,但这仅仅只是开始。SNS提供的API以及现有的一些分享类网站提供的API,仅仅只是Open API中的一角,所能给开发者带来的想象空间,以及所能够产生的商业价值还是十分有限。

今年很多时间都投入到Open API集成平台的设计和开发中,因此对于Open API有一些自己的收获和感想,同时希望通过对Open API的介绍、实践能让更多的人了解和投入到这种新兴开发模式中。这种开发模式是一种挑战,一种创新更是一种机会。

一. Open API 的介绍

Open API的发展

互联网应用最重要的就是创意和及时响应变更这两点。传统软件拚专业化和服务质量,但盗版,同质竞争,对用户个性化需求的服务支持,使得客户和软件生 产商都没有得到满意结果。SAAS模式的提出,其实部分也说明了市场和客户对于互联网应用的需求日趋增强,长尾理论更是让很多草根开发者看到了未来。但互 联网应用是否仅仅就把传统软件搬上网就算是适应潮流,改制创新了呢?其实不然,互联网开放带来的模仿远比盗版可怕,软件的开发周期长,版本迭代周期长,让 传统软件开发模式下的开发人员疲于满足用户需求。而最重要的创意,传统软件专注于专业化,而专业化带来的就是我们过去说SOA需要解决的那些信息竖井,只 有将不同行业的信息串联打通,原有的数据资源才会体现出其更大的商业价值。 因此Open API出现了,起初也许仅仅是互联网企业内部的一种需求,因为企业规模日趋庞大,组织内部的协作也需要模块化和服务接口化,随着业务的梳理以及抽象,服务 逐渐不仅仅可以满足内部交互,同时对外开放给一些商业合作伙伴,随之而来的就是数据资源价值的体现让开放服务的企业得到了回报。当越来越多的互联网企业将 自己内部的业务作为服务提供给外部使用者的时候,服务的发布,流程的规范化也逐渐形成。REST作为一种轻量级服务交互规范也得到了新一代互联网企业的认 同,加上RSS,JSON,XML已经广泛使用的多种数据格式,让Open API有了公共的基础,也为Open API的开发者集成开发提供了最基本的保障。

当前国外的Open API不论是种类,提供商的服务质量,规范化和使用情况都在这一年里面有了很大的提升,可以说已经由初期的发展转到了较为成熟的发展。而国内,就开放的企 业,提供商的服务提供成熟度,以及安全等方面的措施,都仅仅只是起步,不过好处在于有可借鉴的模式。不过,明年随着Open API带来的商业价值逐渐体现,会让更多的人加入到互联网这种新的应用开发模式中来,同时也会给很多开发者,特别是个人和小团队开发者带来机遇。互联网行 业就是一个以小博大的行业,当面对成千上万的新兴资源的时候,创意加行动才是成功的基石。

Open API的形态

就现在互联网上Open API的形态来看,主要分成两种:标准REST和类REST(也可以叫做RPC形态)。

RPC形态其实就是Web Service的一种延续,只是少了繁重的解析、安全规范等。Flickr的Open API大部分就是这种形态,看看下面的服务请求URL:

http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value

服务请求地址包括了两部分:1. 服务的总入口地址http://api.flickr.com/services/rest/。2.服务方法以及参数。这和过去的RPC模式就是一样的,只是通过Http方式请求,返回的是可以指定格式数据内容。

REST形态主要有这么几点特点:1.服务地址就是资源定位地址。2.服务操作就是Http请求中的方法类型 (GET,POST,Delete,PUT),这其实是抽象现实当中对于服务的增删改查操作。Google大部分的REST API就采用了标准的REST风格,服务请求地址URL如下:

http://www.google.com/calendar/feeds/wenchu.cenwc@alibaba-inc.com/allcalendars/full

这个服务请求地址是用来定位以我阿里巴巴邮箱注册的Google帐号的所有日程安排,通过在Http消息头中配置Get、Post、Delete、 PUT可以对我的日程进行操作,而无须登陆到Google上去操作。(后面部分的实践中会有部分介绍如何通过后台Java代码直接操作)

对于REST形式的讨论在网上一直有,但其实这种讨论没有什么意义,其实就好比争论吃饭是否一定要用筷子,没有什么技术是“万能药”,也没有什么技术好于不好,只有使用它的人是否有足够的智慧把它应用到适合的场景中。

对于类REST的形态来说优点在于对于原有系统的改造较小,“当前”用户使用接受度更高一些,对于逻辑抽象来说更加容易。而REST风格的优点在 于,资源容易管理,系统扩展容易,权限控制可以部分依托于已有的传输协议。两者的缺点其实就是对方的优点。采取什么模式,其实还是要根据企业本身情况来 看,类似于淘宝采用的就是类REST方式,而未来支付宝将会采用REST的方式,前者要改造整个系统架构和资源数据结构基本是不太可能完成的任务,后者对 于业务逻辑梳理以及在现有内部SOA架构体系下抽象出REST风格的API并不是一件难事。但最后还是那句话,形态仅仅只是外在,练功之人修炼好内力才是 根本,没有必要为了迎合一种所谓的潮流而去盲目的选择形态,因为服务提供商将要面对的是高过网站上百甚至更高流量的访问调用,如何满足开发者业务以及非业 务(稳定,高效,安全)的需求,才是最大的挑战。

Open API的类型

这里指的类型,主要从提供服务本身内容来看。当前服务类型主要可以分成三种:数据型,应用型,资源型。

现在很多SNS网站的Open API就是属于数据型,也就是将自身的数据开放,让应用开发者根据已有的数据进行二次应用开发。

应用型其实应该是数据型结合的比较紧密,Flickr的图片搜索,Google的日程,地图(地图数据其实可以自己定义)等等都是属于应用型。应用型的数据输入可以是外部的数据,也可以是基于已有的数据资源进行处理。

资源型的代表就是Amazon,Amazon S3就是典型的资源型,当然Flickr的图片存储服务等也可以属于资源型。其实今年还有一个被炒得火热的话题就是云计算,在云计算的背后就是需要提供这 么一个资源型的服务,Amazon EC2如果离开了S3,也就无法存在。其实这种类型的服务也是一种未来的趋势,未来互联网应用如果要培植草根级开发者,就需要有这样的温室,Google 的App engine如果在多一些语言环境版本,那么会让更多的开发者有梦想实现的空间。

在回过头来看三种类型的服务,其实有着很强的层次关系,就如下图:

图1 Open API的类型

Open API交互的数据格式

对于互联网应用来说,最大的特点也是最大的优点就是基于Http协议开发成为应用开发的统一标准。对于使用的语言,采用的操作系统和应用部署平台都 没有太多的限制。Web Service采用xml作为数据传输承载,制定了解析标准(以及后来安全,转发等标准)为开发者异构系统的信息交互带来了可能,也成为至今为止应用最广 泛的服务集成方式。而随着Web2.0发展,RSS、Atom、JSON的大规模应用,对于数据交互格式有了更多的选择。

服务请求就是标准的Http的请求,对于文件类上传的服务采用HTTP Multipart的格式。编码方式基本都采用UTF-8的编码方式。

在Open API的数据返回格式方面,大部分的网站优先提供Xml、JSON的数据返回,Google定义的GData就是在Atom基础上作了扩展,还有一些网站 提供了php的数据返回。同时有些网站会在Open API的基础上作更高的一层封装,类似于Google Map,可以通过java script框架来直接使用。

当前国外的Open API使用状况

我这里只列了前四名的一个比例对照,但是前面四名占有总的Mash-up 的比例已经高达80%左右。

从这个占有率可以看出,API首先吸引开发者的应该是API应用场景是否广泛,Google Map其实就是最好的说明,地图类服务可以和各种行业结合起来为人们生活服务。其次就是API的专业化,后面三位这方面都是本类服务中作的最出色或者说是 暂时还没有人可以作到的。Flickr的服务就是围绕着图片,但是Flickr对于图片Tag专业性的设计让使用者的需求得到了最大的满足,同时也为开发 者提供了很多隐性的资源。YouTube借助着Google在搜索领域的强大优势以及自身的行业能力也吸引了广大的开发者。而Amazon多层次的API 结构化设计,为开发者提供了整套的开发解决方案(EC2,S3,SQS,SimpleDB作为基础的Framework; FPS,DevPay作为配套支付服务支持,Alexa Web Search作为搜索),同时加上自身的强大的电子商务基础,也成为了很多开发者的首选。

其实从国外的Open API来看,如果要成为开发者的服务提供商首选,那么就需要在服务特色,服务质量,服务配套化(社区,SDK,开发框架,整体解决方案)上作文章。很多企 业已经有了吸引人的数据资源(类似于淘宝,YouTube,Flickr),或者拥有行业内强大的专业能力(类似于Google的搜索,地图,支付宝的支 付)都可以比较容易的占有市场优势,而类似于国内现在很多SNS网站商业模式已经被复制的差不多了,数据内容其实也部分上下,因此如何能够做好服务特色, 质量,配套化才是未来在Open API领域走的更远的基石。

二. Open API的实践

Open API实践部分根据授权策略的不同和使用方式的不同分成几阶段内容,完整的代码可以去Google Code下载(http://rest-demo.googlecode.com/files/demostore.rar )。

注:代码中的部分用户名和密码以及应用id都需要采用自己申请的内容作替换,代码都是Java的后台程序代码,主要考虑实践即可,同时这部分代码仅仅是作为测试,结构和错误处理都是没有作太多的关注。

三. 类授权策略

免授权只需要开发者申请应用ID即可使用服务。应用授权是最基础的Open API开发授权策略,作用是让服务提供商能够核对每一次服务请求者的身份,同时也保证了服务开发商的自身利益,与免授权之间的区别就是是否需要在请求中带 上数字签名来交验请求者身份。用户授权一般是基于应用授权之上的更高层次的授权认证,为了保障使用应用的终端用户数据不会在用户不知情或未授权的情况下被 访问和修改,使用户隐私泄露或者蒙受损失。

免授权和应用授权类服务的开发

Yahoo的Search引擎以及Boss服务(Build your Search Service)都是属于免授权类服务。

首先,上Yahoo开发者网站申请应用身份( http://developer.yahoo.com/),这里首先需要拥有一个Yahoo的Id,然后即可申请应用Id,一个开发者可以申请多个应用Id。

客户端测试代码片段如下:

接下来就看看运行效果吧:

testYahooSearch()的运行结果如下:

测试运行结果是搜索结果集的xml描述,可以根据ImageSearchResponse.xsd来解析返回的内容。

testBossSearch()运行的结果如下:

测试运行的结果是已经经过XPath初步处理的结果,提供了下一页的入口URL地址,以及本次搜索出来的结果集。

通过阿里软件服务集成平台访问淘宝非用户隐私信息类API就属于应用授权类服务。与上面范例差异在于调用发送方法时传入了secretcode,进行参数签名(参数中增加了时间戳)。

由上面的例子可以看出,对于公开信息的访问,Open API接入简单,使用方便。

用户授权类服务的开发

用户授权类服务,首先就要解决如何让用户能够在知情的情况下授权给应用开发商获取和操作用户个人的数据,实现用户需求。在传统意义上通常会让用户输 入某一个网站的用户名和密码,就类似于现在的很多SNS让用户输入msn,qq帐号来获取用户好友信息,但是其实这样对于用户来说风险很大,特别是一些个 人隐私性很强的信息或者是涉及到金钱的操作。因此现在大部分的服务提供商采取的是OAuth方式的认证或者是类似于OAuth,OAuth的具体细节我就 不在这里赘述了,网上有很详细地资料,这里就大致把流程原理画一下。

图2 OAuth流程

这里将采用Flickr图片上传作为测试范例:

首先,还是要拥有Flickr的帐号,然后同时去申请应用id。

具体的代码片断如下:

看看执行效果:

首先控制台会输出:if done then input 'ok' to console!,同时弹出IE窗口如下:

输入用户名和密码以后会看到如下界面,就表示授权成功了。

在控制台中输入ok,然后回车。看到如下提示:

然后就输入你需要上传的图片的地址,例如我输入我的blog的头像地址:http://avatar.profile.csdn.net/3/5/1/1_cenwenchu79.jpg。然后回车,会看到新弹出一个页面,里面就是上传到你Flickr中的图片。

以上就是一次用户授权API的完整操作,对比应用授权,个人授权相对来说会比较复杂一些,同时根据调用应用的不同,也会有不同的授权流程(Web应 用,桌面应用,手机应用)。但就现在国内外的Open API使用来看,大致的思想都比较相似,也就是OAuth的思想,但是细节部分会有不少差异,例如Token时效,维护方,操作范围等。

Mash-up 的范例

Mash-up在基维百科中定义是这样的(In web development, a mash-up is a web application that combines data from more than one source into a single integrated tool)。数据的一种集成。其实Open API真正的目的就是希望够让信息在交互中产生更大的价值。

这个范例的场景是淘宝卖家上传上品信息的同时需要有商品的图片,通常商家就不得不自己再去找一些符合自己商品的缩略图,这里我采用上面使用过的 Yahoo BOSS搜索缩略图,将符合条件的缩略图选择一个作为商品的描述图片再上传到淘宝。这样就将整个淘宝卖家编辑上传宝贝的流程简化了,并且对于商品图片描述 来说会有更多更好的选择。

淘宝的Open API都通过阿里软件的服务集成平台发布(后面章节会对服务集成平台有介绍和描述),具体的使用流程其实和前面描述的两种服务获取方式一样,只是在用户授权方面对于应用开发者来说更加简便。

第一步,还是申请应用帐号和安全密码,不过需要首先拥有一个阿里巴巴中文站或者淘宝、阿里软件的帐号,然后登录http://isv.alisoft.com/isv/portal/home/home.jspa,然后选择开发者联盟的标签,里面有说明文档和指南。

第二步,你需要有一个淘宝帐号,并且开了网店。

第三步,客户端代码,代码片断如下:

运行结果:

首先控制台会输出:if done then input 'ok' to console! 然后会有IE弹出界面如下:

输入用户信息以后将会进入如下页面:

点击确认,然后关闭网页。在控制台中输入ok,并且回车。此时就会发现,淘宝卖家中的一个宝贝被修改了价格和图片,不过由于淘宝店的更新会有滞后,因此需要去我的淘宝里面看正在出售中的宝贝。

可以看到,冰激凌图片已经上传到了地毯上去了,这里当然只是试验看效果而已。

三. 服务集成平台

经过前面的介绍和实践两部分,在Open API在概念和实际操作上都有了一定的理解和认识,这里就再谈谈服务集成平台的作用、角色和定位。这里大致描述一下集成平台当前的实现点,这些实现点也就是服务集成平台的价值所在。

服务集成平台(SIP)的角色和作用

图 3 SIP Role

ISV(独立软件开发商)最关心什么?

  1. 服务资源是否丰富。这关系着是否能够创新。
  2. 服务质量是否有保证。这关系着是否能够满足用户最基本的需求。
  3. 开发集成是否便利。这关系着开发成本。

ISP(独立服务提供商)最关心什么?

  1. 服务安全性是否可靠。如果损害到自身或者用户利益,则就失去了原来开放的初衷。
  2. 是否有足够多的应用开发者使用服务。
  3. 服务的非业务性需求是否可以满足。(服务监控告警,计费,统计分析等)

SIP是连接ISV和ISP的“桥梁”。它能解决什么双方最关心的什么问题?

  1. 丰富的ISV资源以及丰富的ISP资源。这其实是一个良性循环的过程,就好比一个建材市场,买家和卖家数量远远要比在单独一家实体店中多,从淘宝的B2C模式就可以看出,市场大了以后传统的“大鳄”都要聚集人气。
  2. 统一安全标准和多种控制策略,即保证了ISP的安全,又能够让ISV开发起来方便。在前面实践过程中可以很明显的看到,众多的应用id,各自的安全流程,让开发者Mash up无形中增加了很大的开发成本和维护成本。
  3. SIP目的就是让ISP专注于业务服务的开发,而将非业务性的需求,如安全,服务监控预警,日志分析统计,计费,社区等都一揽子解决。这样既解决了ISP的第三个问题,同时也为ISV关心的服务质量无形中作了促进。

在年初的时候,分析和研究国外的Open API时,感觉类似于SIP形态的产品在国外还没有,大家都是各做各的,但这阵子回过头来看,YouTube和Google开放平台,Flickr和 Yahoo开放平台,这些平台都属于SIP形态的产品,而且Google要比当前我们做的SIP还要更进一步,那就是数据格式规范化(GData),而 SIP当前仅仅只是做到流程规范化。

那是否任何公司都适合去做SIP这类形态的平台呢,这不仅仅是技术问题,还是一个资源的问题。阿里巴巴每一家子公司都有实力去做一个这样的开放平 台,但各自独做一套的结果就是资源浪费,同时技术没有得到积累(SIP技术积累是在ISV和不同形态的ISP接入中逐渐产生的),最重要的是这些子公司其 实真正需要关注的是如何将业务和数据开放给开发者,吸引更多的开发者来构建出围绕Open API的创新应用,最大化数据和服务的商业价值。

服务集成平台功能特性

服务路由

服务集成平台就好比硬件里面的“路由器”,服务调用者只需要提供服务注册的名称,就可以调用到某一个服务提供商提供的服务,对于调用者来说无需关心此服务的地址以及提供者。

根据现阶段的服务集成来看,主要分成四类的服务路由,同步服务路由,异步服务路由,订阅服务路由,大数据量上传服务。同步服务路由就是普通的 Http无状态单次请求和响应。异步服务路由应用于服务提供商提供的服务无法在当时处理完毕,先返回一个请求响应,当服务处理结束以后再将服务处理结果返 回给服务调用者(短信业务就是一种异步服务)。订阅服务和互联网上RSS之类的订阅十分相似,服务调用者只需要订阅服务即可获得服务提供商推送的服务内 容。大数据量上传服务其实也是属于同步服务,但是由于消耗资源和性能压力不同,因此被单独作优化处理。

对于服务形态不同,服务路由需要支持REST风格的服务路由和类REST风格服务的路由,但对于开发者来说,调用的方式都是用服务名称来路由。

正式环境和测试环境的隔离和切换

对于服务开发者来说,在应用开发期间需要有外部测试环境的支持,在商用以后需要有正式环境支持,同时两个环境的切换需要尽量的简单。

服务集成平台支持服务提供商提供测试环境和正式环境的不同服务路由,同时两套环境切换成本低。当服务提供商只有一套环境的时候可以根据策略配置的不同,对调用者访问的范围,频度,次数作限制,保证测试服务不影响正式服务。

安全

提供对应用身份认证以及服务提供商身份认证的支持,采用多种数字签名算法实现基本的身份认证,支持IP白名单和动态算法更新后端插件提供更高级别的服务安全保证。

细化了用户授权流程。对于用户Token细分为请求级别和会话级别,同时对于会话级别的权限操作,失效时间可根据服务提供商的配置自定义。同时平台托管维护每个应用每个用户的多身份绑定Token,降低服务提供商开发维护成本。

服务提供商可配置服务访问量控制和频率控制(所有应用或者单个应用)。也支持配置需要订购才可以使用的服务(有限次数订购,无限次数订购)。

支持多级服务安全策略配置,为服务配置(无授权,应用授权,用户授权,可选用户授权)等多种级别的安全策略。注:可选用户授权是指如果没有被用户授权的情况下使用接口将返回部分公开数据,而在用户授权情况下使用则返回全部的私有和公开数据。

对服务提供商多级分类,提供不同的安全策略组合。

监控与告警

服务使用者服务使用出错监控和告警。

服务提供商提供的服务可用性,超时状况的监控和告警。

服务集成平台服务处理状况,内部模块运行状况监控和告警。

日志采集与统计分析

高并发下日志采集异步处理,采集服务正常访问和异常访问日志,采集用户绑定类,异步服务类,平台内部服务类等特殊日志。

每日,每周,每月访问日志统计分析,基础报表和趋势分析图的创建。

支持分析结果预警配置。

历史统计数据管理和归档。

平台内置服务

平台为服务提供商以及服务调用者提供了平台级别的服务,为开发商和服务提供者获取平台业务数据以及运行期配置安全策略提供方便。

平台提供一系列平台模块监控、配置、重置服务,支持在线问题查找、定位、解决的一套机制。

非功能性需求(当前情况)

性能:压力测试单机500并发用户1600+的tps,多机处理能力线性增长。

模块化:内部处理模块化结构,支持运行期配置、装载、卸载。

容错:服务集成平台核心数据都缓存在Memcache中,因此Memcache集群以及容错策略的扩展都为平台稳定和容错作了基础保证。

配套支持

通过ISV,ISP,Admin三个Portal,使开发者,服务提供商以及后台维护人员能够自主维护基本信息和查看相关数据。

为开发者提供社区,测试区的支持,并且提供开发工具包和文档,方便开发。

扩展集成

支持不同平台的服务集成。支持Google,Flickr,Yahoo等等不同的服务平台的服务集成,当前还没有完全将安全体系集成,只能够支持安全流程透传,消息数据完整过滤。

服务集成平台的一些发展趋势

  1. 数据集成和流程集成
    当前很多服务都是基础的数据型服务,使用者通过数据筛选获取相应的数据,然后展现给用户,这些服务的集成相对来说功能比较单一,流程也不复杂。但随着服务 提供商的发展,数据类型服务将会作为基础服务的一部分,而越来越多业务处理型服务会成为使用者的首选,此时,如何让服务和服务之间数据互通,服务可以通过 一定的描述编排,就会变得越来越有价值,就如前面提到的,Google采用GData作为数据规范格式,同时对于安全流程的统一制定,为第二阶段的集成打 下了基础。
  2. 服务基础平台间的互通
    最近Open ID也再次由于各大网站的支持而被人们广泛关注,在未来Open API体系中,伴随着Open ID的发展,服务基础平台之间的服务互通也将会变得越来越容易,但是数据的安全性也会对每个服务平台要求更高。
  3. 服务集成平台的层次化
    在这篇文章的介绍中仅仅介绍的是最基础的Open API的Mash up,其实当前已经有更高层次的Mash up被广为使用,JavaScript、ActionScript、Flash/Flex这些技术使得展现更为灵活和丰富。因此未来的服务集成平台将会层 次化,从数据集成到流程集成到UI集成,会成为一套自下而上的解决方案,适合各种场景的裁剪选择。

四. 对Open API的一些思索和感触

不同角色,不同收获

平台开发者:

这是我的本职工作和角色。当淘宝等服务提供商的服务接上来以后我就要为它的安全和稳定负责。当SIP一旦出现问题,那么服务提供商和软件开发商将都无法再正常工作,套用蜘蛛侠的一句话:“能力越大,责任越大”。作平台的尤为如此。

服务提供商:

服务提供商接触的最多的就是淘宝的同学,首先看到的就是做一个服务提供商很不容易,要把原有系统中复杂的逻辑抽象出来并不是抽象一个公用函数那么简 单,同时对于模块化,边界性,容错性方面的要求要远远高于封闭系统开发本身,因为你现在要面对的是倍于原有访问量上百甚至上千的调用者,对任何一个小疏漏 都可能带来灾难性的影响。

软件开发商:

在写这个文档以前,最多也就是写几个测试的Demo来测试SIP环境中的服务,在淘宝API讨论群中会看到很多新的或者老的ISV在抱怨或者询问一 些自己觉得很简单的问题(例如签名等等),同时在监控中也看到很多及其简单错误统计数都会有很高的比例。但是经历过这次对于各种各样国内国外的API的开 发,让我深刻体会到了开发者的一些痛苦(当然我没有去使用各个开发社区的第三方语言开发包,这也增加部分的开发难度),我也曾因为签名问题在豆瓣API测 试的时候折腾了半天,在调试Google Calendar的时候不得不跟踪开发包代码才找到了一些隐晦的设置通过测试。其实Open API在国内国外都没有完全可以称得上成熟,因此开发者其实是最容易受到影响的。同时他们面对着最难应付的客户,平台或者服务提供商出现问题,客户最先抱 怨的也是服务开发商,因此作为平台开发者和ISP其实都要给与一定的支持和帮助,这样才会走向更好的良性循环。

其实上面说的那些无非都是大家最长说的换位思考,一个新兴的开发模式需要各方合作才会走向良好的发展方向。

创意就是财富

记得前一阵子支付宝能够在上海交水电费引起了很多人关注,杭州本地论坛中都有很多人在问:“什么时候杭州能够也用支付宝交水电费就好了”。其实如果 开放了支付服务和水电缴费服务,这种Mash up的应用又有什么难的呢?你都可以直接每个自然月通过Google Calendar设置好日程安排,自动缴完所有的费用,然后短信提示一下即可。未来当各行各业发现了自身资源的潜在价值以后,以服务的方式通过平台互通, 那么创意就是财富。


作者介绍:岑文初,就职于阿里软件公司研发中心平台一部,任架构师。当前主要工作涉及阿里软件开发平台服务框架(ASF)设计与实现,服务集成平台(SIP)设计与实现。没有什么擅长或者精通,工作到现在唯一提升的就是学习能力和速度。个人Blog为:http://blog.csdn.net/cenwenchu79

[Javascript]JSINQ——LINQ的JavaScript实现

mikel阅读(1206)

JSINQ代表JavaScript INtegrated Query,它是用JavaScript实现LINQ to Objects的beta项目,最近由Kai Jäger在CodePlex网站上发布。JSINQ包含两个模块,Enumerable和Query相应地实现System.Linq.EnumerableSystem.Linq.Queryable ,它可枚举字符串、DOM节点类别或者其他对象。

两个模块分别是jsinq.Enumerable和jsinq.Query。查询示例,如下所示:

var query = new jsinq.Query('\
from order in $1 \
group order by order.customerId into g \
select {customerId: g.getKey(), items: g.sum(function(g) { return g.items; })} \
into h \
join customer in $0 on h.customerId equals customer.id \
where h.items > 10 \
orderby h.items descending \
select {lastname: customer.lastname, items: h.items} \
');
query.setValue(0, customers);
query.setValue(1, orders);
var result = query.execute();

枚举示例,如下所示:

var enumerator = namesThatStartWithAnA.getEnumerator();
while (enumerator.moveNext()) {
var name = enumerator.current();
document.write(name + '<br />');
}

根据Kai的说法,JSINQ可以完成下列任务:

  • 针对JavaScript字符串、DOM节点列表或者自定义枚举类型,编写任意复杂的查询
  • 在HTML的DOM树中使用SQL风格的查询语法找出相应的元素
  • 从藉由XMLHttpRequest获取而来的JSON中以声明的方式动态创建HTML元素
  • 修改XML并把它转换为其他格式
  • 把正使用的JavaScript或Ajax框架以有趣的方式关联
  • 利用声明性编程的好处来减少编码量
  • 以及让喜欢挑战的编程人员编写射线追踪器(算法)、包含多个单一解析器的组合器等

Kai已经提供了相关网页让大家测试JSINQ 。可以从CodePlex免费下载基于MIT许可证源代码。类似的项目还有:JSLINQ 和JLINQ。

查看英文原文:JSINQ, a JavaScript Implementation of LINQ

[C#]网页信息抓取实现

mikel阅读(903)

最近公司需要开发一个简历导入功能,类似博客搬家或者邮箱搬家,之前抓取信息是利用火车采集器,但是简历导入功能需要用户登陆以后才能获取简历数据,无奈只好自己开发了。

首先是遇到的问题是:如何实现模拟登陆?

我们知道一般的网站都是通过Cookies来维护状态的,我抓的网站也是支持利用Cookies来验证用户的,构造一个post数据包,向服务器提 交数据,在配置火车采集器的时候,也是要先利用WSockExpert.exe工具获得Post数据包,之后修改用户名和密码,向服务器提交的。

提交了登陆数据后还没完成登陆,虽然服务器会返回登陆后的页面数据,但是如果在进入其他的链接页面,还是不允许的,因为服务器每次都需要通过你提交 过去Cookies来验证你是否登陆,在ASP.NET里,利用Cookies存储身份验证票证,每次都需要向服务器提交的,初学ASP.NET总是弄不 明它的form验证机制,它封装了太多信息,虽然用几行代码就能实现验证,后来看了些web开发基础知识才弄明白,在这个你需要保存上次登陆后返回的 Cookies,在下次有其他请求时带上这个Cookies就可以了,怎么带上呢?下面是我在.net里的实现,很简单!

利用HttpWebRequest类的CookieContainer来保存,这个CookieContainer会保存服务器回传的 Cookies,但是前提是你在初始化HttpWebRequest的时候,记得实例化这个CookieContainer,一般的请求不需要实例它的, 简单的代码如下:

 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(URL);            
  httpWebRequest.CookieContainer = new CookieContainer();
  httpWebRequest.ContentType = "application/x-www-form-urlencoded";
 httpWebRequest.Method = "POST"

 为了能全局使用这个CookieContainer ,你可以把它作为全局变量,这样在下次request的时候将其赋给CookieContainer 属性就行了。

详细了解CookieContainer 见:http://msdn.microsoft.com/zh-cn/vstudio/system.net.cookiecontainer(VS.80).aspx

维护了这个CookieContainer 后,我们就可以访问登陆后的页面了,模拟登陆问题解决。

其次遇到的问题自然是:如果从网页上获得想要的信息?

 要在网页抓取信息,实现起来最简单,同时也是最繁琐的方法,那就是模板方法获取了,从火车采集器的配置过程看出来,它也就是用这种方法而已,不过 人家能把抓取器做成成熟的产品,并且热卖,这个比不了,所以成功与否不完全取决于技术,火车采集器虽然配置起来挺繁琐,但是用起来还不错。

用这种方式你需要做个一个模板,你需要知道目标网页的结构,知道要找的信息在什么地方,之后记录在它的前面和后面的字符串,你可以利用截取字符串的 方式获得目标信息,也可以利用正则标式获得,要保证前面和后面的字符串是唯一的,很简单,计算一下,或者匹配一下就可以获得目标信息,但是实际做起来还是 会遇到一些问题:

下面是我遇到问题;

1.首先我是想利用正则表达式匹配,但是模块里设置的前缀和后缀里有回车换行\r\n,结果总是匹配不成功,我正则的功底很差,最后知道怎么回事了,把\r\n替换成(\s*),问题解决,您可以想出为什么了吧?

2.利用字符串截取方式获取,在正则还不是很精通,用这种方式最保险了,但是在截取字符串前记得调整下目标页代码,从xml配置文件里读取的前缀和 后缀中可能有回车和换行,但是回车换行在不同系统里字符表现是不一样的,Windows里是\r\n,Linux里是\n,所以要记得统一。

3.前后缀不唯一,有时在页面里有两个不同的目标信息,但却有相同的前缀,比如:

<td width="25%" class="ResTbLfPd">数据库</td>
<td width="25%" class="ResTbLfPd">软件工程师</td>

如果用相同的前缀就比较难截到想要的信息了,我想了个办法,当然方法可能比较笨,但是问题解决了,也是火车给我的启示,利用多个字符串定位目标信息,比如我想抓去 软件工程师 ,前缀就是:

<td width="25%" class="ResTbLfPd">*</td>
<td width="25%" class="ResTbLfPd">

在信息可能不同的地方用*代替,类似通配符,这样利用*将一个字符串切割为两个,先找到第一个,之后以这个索引位置为起点,再找第二个字符串,这样就可以定位到最终的信息了,同样可以用多个字符串三个或更多,这样实现是解决了问题,希望有更好的方式,希望以后会改进。

4.在抓取信息的时候还可以利用MITHtmlPparser,这是一个开源的类库,在codeproject找搜到的,将网页内的所以标签都分析出来,如果获取信息不是很多、很碎的话,用这个也比较好用,只需知道那个最终要得到信息在那个标签里,然后直接取出就行了。

好了,希望在新的一年里能学到更多,能经得住考验!

文章引用:http://www.elooog.cn/view.asp?id=41

[C#]公交车路线查询系统后台数据库设计

mikel阅读(958)

 

数据库下载

 

1. 公交车路线信息在数据库中的存储方式

显然,如果在数据库中简单的使用表bus_route(路线名,路线经过的站点,费用)来保存公交车路线的线路信息,则很难使用查询语句实现乘车线路查询,因此,应该对线路的信息进行处理后再保存到数据库中,笔者使用的方法是用站点路线关系表stop_route(站点,路线名,站点在路线中的位置)来存储公交车路线,例如,如果有以下3条路线

R1: S1->S2->S3->S4->S5

R2: S6->S7->S2->S8

R3: S8->S9->S10

则对应的站点路线关系表stop_route

Stop

Route

Position

S1

R1

1

S2

R1

2

S3

R1

3

S4

R1

4

S5

R1

5

S6

R2

1

S7

R2

2

S2

R2

3

S8

R2

4

S8

R3

1

S9

R3

2

S10

R3

3

 

注:Stop为站点名,Route为路线名,Position为站点在路线中的位置

2.直达乘车路线查询算法

基于表stop_route可以很方便实现直达乘车路线的查询,以下是用于查询直达乘车路线的存储过程InquiryT0

create proc InquiryT0(@StartStop varchar(32),@EndStop varchar(32))

as

begin

     select

         sr1.Stop as 启始站点,

         sr2.Stop as 目的站点,

         sr1.Route as 乘坐线路,

         sr2.Position-sr1.Position as 经过的站点数

     from

         stop_route sr1,

         stop_route sr2

     where

         sr1.Route=sr2.Route

         and sr1.Position<sr2.Position

         and sr1.Stop=@StartStop

         and sr2.Stop=@EndStop

end

3.查询换乘路线算法

(1)直达路线视图

直达路线视图可以理解为一张存储了所有直达路线的表(如果两个站点之间存在直达路线,那么在直达路线视图中就有一行与之相对应)

create view RouteT0

as

     select

         sr1.Stop as StartStop, 启始站点

         sr2.Stop as EndStop,   目的站点

         sr1.Route as Route,    乘坐线路

         sr2.Position-sr1.Position as StopCount    经过的站点数

     from

         stop_route sr1,

         stop_route sr2

     where

         sr1.Route=sr2.Route

         and sr1.Position<sr2.Position

 (2)换乘路线算法

显然,一条换乘路线由若干段直达路线组成,因此,基于直达路线视图RouteT0可以很方便实现换乘查询,以下是实现一次换乘查询的存储过程InquiryT1

create proc InquiryT1(@StartStop varchar(32),@EndStop varchar(32))

as

begin

     select

         r1.StartStop as 启始站点,

         r1.Route as 乘坐路线1,

         r1.EndStop as 中转站点,

         r2.Route as 乘坐路线2,

         r2.EndStop as 目的站点,

         r1.StopCount+r2.StopCount as 总站点数

     from

         RouteT0 r1,

         RouteT0 r2

     where

         r1.StartStop=@StartStop

         and r1.EndStop=r2.StartStop

         and r2.EndStop=@EndStop

end

同理可以得到二次换乘的查询语句

create proc InquiryT2(@StartStop varchar(32),@EndStop varchar(32))

as

begin

     select

         r1.StartStop as 启始站点,

         r1.Route as 乘坐路线1,

         r1.EndStop as 中转站点1,

         r2.Route as 乘坐路线2,

         r2.EndStop as 中转站点2,

         r3.Route as 乘坐路线3,

         r3.EndStop as 目的站点,

         r1.StopCount+r2.StopCount+r3.StopCount as 总站点数

     from

         RouteT0 r1,

         RouteT0 r2,

         RouteT0 r3

     where

         r1.StartStop=@StartStop

         and r1.EndStop=r2.StartStop

         and r2.EndStop=r3.StartStop

         and r3.EndStop=@EndStop

end

 

3.测试

exec InquiryT0 'S1','S2'

exec InquiryT1 'S1','S8'

exec InquiryT2 'S1','S9'

运行结果:

 

 

数据库下载

[应用]轻量级网页客户端矢量图形绘制技术总结(lightweight techniques for

mikel阅读(788)

提到在线绘图,目前最流行的技术应该属Flex了(可参见另一篇文章:15个强大的在线图片编辑器 ),另外Silverlight在此方面也很有潜力。相比之下,诸多轻量级的客户端矢量图形绘制技术却显得有点鲜为人知。谨以此文总结我一年以来收集的此方面的相关资料与心得,与大家分享!

在一些web客户端客户端开发中,轻量级客户端矢量图形绘制技术还能够起到重要的作用。

1. VML 矢量标记语言

维基百科对VML的解释如下:

VML(Vector Markup Language) is an application of Extensible Markup Language (XML) 1.0 which defines a format for the encoding of vector information together with additional markup to describe how that information may be displayed and edited.

例子:使用VML与鼠标绘图:

 

online drawing

 

VML作为一种XML的扩展,还在数据处理上很有用途,这里还有个例子:

例子:VML+XML绘制树型图表(Create a Tree Graph by VML+XML)

code is pick from internet, connect me if you are the author, Thanks.

 

 

data.xml

 

vml.htm

 

VML的相关资料:

http://www.w3.org/TR/NOTE-VML
http://en.wikipedia.org/wiki/Vector_Markup_Language
http://www.vml.org/Wnew.html

VML的在线案例:

http://www.tool.la/VMLPalette/

注:VML只支持IE5 以上的IE浏览器,请参见:

http://www.causeway.co.uk/demos/vml/index.htm

To view these charts you will need a VML enabled browser; this means IE5 or above with the VML component installed. Please don't be too annoyed if this page looks a complete mess in Firefox or Opera – VML is a Microsoft-specific format and will never be supported by standards-aware browsers.

 

2. SVG可扩展矢量图形

W3C网站对SVG的介绍:

SVG(Scalable Vector Graphics ) is a language for describing two-dimensional graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation and forms the core of the current SVG developments. SVG Tiny 1.2 is the specification currently being developed as the core of the SVG 1.2 language (comments welcome). The SVG Mobile Profiles: SVG Basic and SVG Tiny are targeted to resource-limited devices and are part of the 3GPP platform for third generation mobile phones. SVG Print is a set of guidelines to produce final-form documents in XML suitable for archiving and printing. Read more about SVG.

严格的来说,SVG并不是一种轻量级的绘图方案,因为它需要安装Adobe的SVG Viewer插件(2.78M),但SVG同样也是基于XML的,其强大的功能可以轻松的制作出各种动态和静态图型:

大量SVG例子:

下转自中国w3c联盟

动态
普通效果
http://www.adobe.com/svg/dynamic/transformations2.html

无JS干预效果
http://www.adobe.com/svg/dynamic/declarative.html

JS干预效果
http://www.adobe.com/svg/dynamic/javascript.html

鼠标事件效果,注意可以在HTML元素中干预效果,甚至可以在各个不同的SVG间互相干预
http://www.adobe.com/svg/dynamic/mouseevents.html

键盘事件效果,鼠标点击SVG后敲击键盘,如果字体完全消失,需要再点击
http://www.adobe.com/svg/dynamic/keyboardevents.html

动态插入对象
http://www.adobe.com/svg/dynamic/insertion.html

语言支持演示,支持国际任何语言(拿了日本的语言,中国啊,自强!)
http://www.adobe.com/svg/dynamic/insertion.html

SVG优秀的压缩算法及与JPG、GIF的质量比较
http://www.adobe.com/svg/workflow/optimizing.html

浏览插件的自动安装
http://www.adobe.com/svg/workflow/autoinstall.html

SVG在GoLive、Office、FramwMaker中的使用
http://www.adobe.com/svg/workflow/workflow.html

————–
静态
点击以显示不同区域
http://www.adobe.com/svg/basics/boundbox.html

动态改变SVG字体及文字内容(无中文字体)
http://www.adobe.com/svg/basics/text.html

动态改变CSS
http://www.adobe.com/svg/basics/css.html

填充
http://www.adobe.com/svg/basics/fills.html

加边
http://www.adobe.com/svg/basics/strokes.html

渐变
http://www.adobe.com/svg/basics/grads.html

滤镜特效1、2
http://www.adobe.com/svg/basics/filtereffects.html
http://www.adobe.com/svg/basics/filtereffects2.html

与传统位图(Jpeg、Gif、Png)的结合
http://www.adobe.com/svg/basics/jpgs.html

ICC标准的色彩支持
http://www.adobe.com/svg/basics/icc.html

选择可见元素的设置
http://www.adobe.com/svg/basics/printing.html

SVG参考资料:

http://www.w3.org/Graphics/SVG/

 

3. Canvans

Firefox官方网站对Canvans的介绍:

<canvas>是一个新的HTML元素,这个元素可以被Script语言(通常是JavaScript)用来绘制图形。例如可以用它来画图、合成图象、或做简单的(和不那么简单的)动画。右面的图象展示了一些<canvas>的应用示例,我们将会在此教程中看到他们的实现。

注意:Canvans是HTML5标准中的新技术,这意味着所有不支持HTML5的浏览器都不能支持Canvans,包括IE

并不是所有现代浏览器都支持<canvas>元素,所以你需要 Firefox 1.5或更新版本、或者其他基于Gecko的浏览器例如Opera 9、或者最近版本的Safari才能看到所有示例的动作。

例子:简单Canvans例子,来自FF社区

请使用FF或Safari观看

 

Canvans不仅能够绘制2D、3D的矢量图形,还可以与JS交互来实现一些复杂的动画:

 

Canvans教程:

https://developer.mozilla.org/cn/Canvas_tutorial

  • Canvas示例集
  • Canvas articles and other resources

     

    4. 推荐的第三方开源框架:

    除了上述三种技术之外,一些开源的WEB绘图框架也做的很好,尤其是在浏览器兼容方面,在此向大家推荐下列两个:

    http://www.c-point.com/javascript_vector_draw.htm

    http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm

     

    文章写的仓促,其实这方面技术有很深,不足之处请多多补充

    Thanks. 

  • 作者:Lance ZhangLance Zhang's Tech Blog
    出处:http://blodfox777.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权

    [C#]推荐一个操作Zip文件的开源类库:DotNetZip

    mikel阅读(1067)

    DotNetZip 是一个短小易用的用来操作 zip 文件的 .NET 类库,支持.NET的任何语言,可很方便的创建,读取,和更新zip文件。而且还可以使用在.NETCompact Framework中。

    下面是一些简单的例子:

    1.加密压缩:

    using (ZipFile zip = new ZipFile())
    {
    zip.Password = sPassword; //set pwd
    zip.AddDirectory(sZipDir);
    zip.Save(sSavePath + @"\" + sSaveName);
    }

    2.向压缩文件中添加:

    using (ZipFile zip = new ZipFile("Backup.zip"))
    {
    zip.Password= "123456!";
    zip.AddFile("ReadMe.txt");
    zip.AddFile("7440-N49th.png");
    zip.AddFile("2005_Annual_Report.pdf");
    zip.Save();
    }
    

    3.解压缩到制定目录:

    using (ZipFile zip = ZipFile.Read("D:\\test\\2007.zip"))
    {
    foreach (ZipEntry e in zip)
    {
    Console.WriteLine("file name:{0}", e.FileName);
    Console.WriteLine(e.Comment);
    e.Extract("D:\\test\\pwdata", true);  // overwrite == true
    }
    }
    

     

    其他详细的使用请参考:http://www.codeplex.com/DotNetZip