2006年6月29日

动作映射

这个时候,你可能会问自己:“当控制器接受到一个请求的时候,它如何知道调用哪个Action实例?”控制器要通过查看请求消息并使用一组动作
映射(action mapping)来做出决定。动作映射是Struts配置信息(配置一个特殊的XML文件中)的一部分。这个配置信息会在启动时加载到内存中
,让Struts框架得以在运行时加以利用。每个action元素在内存中都被表示为org.apache.struts.action.ActionMapping类的实例。
ActionMapping对象包含一个path属性,用来与外部请求的URI部分匹配。如下:
<action
    path="/login"
    type="com.oreilly.struts.banking.action.LoginAction"
    scope="request"
    name="loginForm"
    validate="true"
    input="/login.jsp"
    <forward name="Success" path="/action/getaccountinformation" redirect="true"/>
    <forward name="Failure" path="/login.jsp" redirect="true"/>
</action>
这里的登录动作映射把路径"/login"映射到了com.oreilly.struts.banking.LoginAction这个Action类。无论何时,当控制器接受到一个URI
路径中包含"/login"字符串的请求时,就会调用LoginAction实例的execute()方法。Struts框架还会使用映射来指出“动作"完成后要让用户
转向哪个资源。

 

使用Struts ActionForm

Struts框架的ActionForm对象可用来在用户和业务层之间传输客户的输入数据。Struts框架会自动从请求中收集输入数据,再将这些数据交给
一个使用表单bean(form bean)的Action对象,接着表单再交给业务层。为了把表示层和业务层分离开来,你不应该直接把ActionForm对象交
给业务层,而是应该使用由ActionForm对象得到的数据创建适当的DTO。下面的步骤说明了Struts框架如何处理每个请求相应的ActionForm对
象:
 
  1.检查该项动作的相应设置,查看是否已经有某个ActionForm得到配置。
  2.如果对应这个动作配置了某个ActionForm,则使用action元素中的name属性来查找表单bean的配置信息。
  3.查看是否已经创建了一个ActionForm的一个实例。
  4.如果在适当的作用域内已经存在一个ActionForm实例,而且这个实例的类型正是这个请求所需要的类型,则重用这个实例。
  5.否则,创建所需ActionForm的一个新实例,并存储在适当的作用域中(由action元素的scope属性设置)。
  6.调用ActionForm实例的reset()方法。
  7.反复处理请求参数,如果参数名在ActionForm实例中具有对应的设置方法(setter method),就为它填上该请求参数的值。
  8.最后,如果validate属性的值设置为true,则调用ActionForm实例的validate()方法,并返回所出现的任何错误。
对任何HTML页面而言,如果表单数据是以POST方法传输的,就应该使用ActionForm。必要时,相同的ActionForm可以同时给多个页面使用,只
要HTML字段能和ActionForm对象的属性(property)匹配就可以了。
Struts框架所提供的ActionForm类实现了多个方法,但到目前为止,最重要的两个方法就是reset()和validate():
  public void reset(ActionMapping mapping,HttpServletRequest request);
  public ActionErrors validate(ActionMapping mapping,HttpServletRequest request);
在Struts ActionForm类中,这两个方法的默认实现是不完成任何的逻辑。你必须在自己的ActionForm类中覆盖这两个方法。控制器以请求中的
值来填写ActionForm实例之前,会先调用reset()方法。reset()方法给了ActionForm一个机会,可将其属性设置为原来默认的状态。这一点非
常重要,因为表单bean实例可能会由多个请求共享或者由好几个不同的线程所存取。不过,如果你是让好几页共享一个ActionForm实例,可能
不会去想去实现reset()方法,这样一来只要这个实例还在,属性的值就不会被重新设置。另一种做法就是实现你自己的resetFields()方法,
在成功更新业务之后,就从这个Action类来调用此方法。
当请求中所携带的值已经插入到ActionFrom实例之后,控制器就回调用validate()方法。ActionForm应该对输入数据完成必要的验证工作,然
后向控制器返回所检测到的任何错误。业务逻辑验证应该在业务对象中而不是在ActionForm中来完成。在ActionForm中所进行的验证工作,只
是表示的验证而已。
一旦写好ActionForm类后,你必须通知Struts应用程序有这些ActionForm存在,告诉Struts应用程序哪个动作映射应该使用哪个ActionForm。
这是在配置文件中设置的。第一步是为你的应用程序在配置文件中的form-beans段里配置所有的ActionForm。看下面的一个例子:
 <form-beans>
    <form-bean
       name="loginForm"
       type="com.oreilly.struts.banking.form.LoginForm"/>
    <form-bean
       name="accountInformationForm"
       type="org.apache.struts.action.DynaActionForm">
       <form-property name="accounts" type="java.util.ArrayList"/>
    </form-bean>
 </form-beans>
每个表单bean的name属性必须都是独一无二的,而且其type属性必须定义一个Java类(扩展了Struts ActionForm类)的完全限定名。下一步
是在一个或多个action元素中使用在form-benas段里的某个form-bean名。如下:
  <action
    path="/login"
    type='com.oreilly.struts.banking.action.LoginAction"
    scope="request"
    name="loginForm"
    validate="true"
    input="/login.jsp">
    <forward name="Success" path="/action/getaccountinformation" redirect="ture>
    <forward name="Failure" path="/login.jsp" redirect="true"/>
  </action>
注意:登录动作映射的name正好和前面form-beans段里某个name属性相匹配。

 


 

posted @ 2006-07-05 08:07 多力宇扬 阅读(1153) | 评论 (5)编辑 收藏

美国杂志300强及其网址

No  杂志名称                                                          网址                                                    类别
1   People(人物)                             http://people.aol.com/people/index.html                     娱乐
2   TV Guide(电视指南)                 http://www.tvguide.com                                              娱乐
3   Time(时代)                                http://www.time.com                                                   新闻
4   Sports Illustrated(体育画报)   http://sportsillustrated.cnn.com 体育
5   Better Homes & Gardens(美好家园)  http://www.bhg.com 家居
6   Reader’s Digest(读者文摘)  http://www.rd.com/splash.jhtml 综合
7   Parade(旅行)  http://www.parade.com/auth/entry.lasso 旅游
8   Newsweek(新闻周刊)  http://www.msnbc.com/news/NW-front_Front.asp 新闻
9   Business Week(商业周刊)  http://www.businessweek.com 商业
10   Good Housekeeping(好主妇)  http://www.goodhousekeeping.com 家庭
11   Fortune(财富)  http://www.fortune.com/ 商业
12   Cosmopolitan(全球主义者)  http://www.cosmopolitan.com/ 娱乐
13   Woman’s Day(妇女日)  http://www.womansday.com/xp6/WomansDay/home.xml 妇女
14   Forbes(福布斯)  http://www.forbes.com/ 商业
15   Family Circle(家庭圈)  http://www.familycircle.com/home/homepage.jsp 家庭
16   USA Weekend(美国周末)  http://www.usaweekend.com 休闲
17   Instyle(时髦)  http://www.instyle.com/instyle 时尚
18   Entertainment Weekly(娱乐周刊)  http://www.ew.com/ew/ 娱乐
19   Martha Stewart Living(玛萨斯图尔特生活)   http://www.marthastewart.com 生活
20   U.S. News & World Report(美国新闻与世界报道)  http://www.usnews.com 新闻
21   Ladies’ Home Journal(妇女家庭杂志)   http://www.lhj.com 家庭
22   National Geographic(国家地理杂志)   http://www.nationalgeographic.com 地理
23   Southern Living(南方生活)  http://www.southernliving.com/ 生活
24   Vogue(时尚)  http://www.style.com/vogue/index.html 时尚
25   PC Magazine(个人电脑)  http://www.pcmag.com/ IT
26   Money(金钱)  http://money.cnn.com/ 理财
27   Maxim(马克西姆)  http://www.maximonline.com/index.html 娱乐
28   O, The Oprah Magazine   http://www.oprah.com/omagazine 妇女
29   Glamour(魅力)  http://www.glamour.com/ 时尚
30   National Enquirer, The(国家寻问者)  http://www.nationalenquirer.com/ 新闻
31   New York Times Magazine(纽约时报杂志)  http://www.nytimes.com/ 新闻
32   Golf Digest(高尔夫文摘)  http://www.golfdigest.com/ 体育
33   Rolling Stone(滚石)  http://www.rollingstone.com/ 音乐
34   Playboy(花花公子)  http://www.playboy.com/ 男性
35   Vanity Fair(名利场)  http://www.vanityfair.com 娱乐
36   Seventeen(十七岁)  http://www.seventeen.com/ 青年
37   Parents(父母)  http://www.parents.com/ 教育
38   Star Magazine(明星杂志)  http://www.starmagazine.com/ 娱乐
39   ESPN The Magazine(ESPN杂志)  http://espn.go.com/magazine/ 体育
40   Prevention(预防)  http://www.prevention.com/ 健康
41   Redbook(红书)  http://magazines.ivillage.com/redbook/ 妇女
42   Rosie   http://www.rosieo.com/ 生活
43   Golf Magazine(高尔夫杂志)  http://sportsillustrated.cnn.com/golfonline/ 体育
44   Travel & Leisure(旅游和休闲)  http://www.travelandleisure.com/ 休闲
45   Elle   http://www.elle.com/ 时尚
46   New Yorker, The(纽约客)  http://www.newyorker.com/ 文艺
47   W   http://www.style.com/w/ 时尚
48   Woman’s World(妇女世界)  http://www.robertcraig.com/womansworld.html 妇女
49   Parenting(养育)  http://www.parenting.com/parenting/ 家庭
50   Car & Driver(人车志)  http://www.caranddriver.com/xp/Caranddriver/home.xml 机车
51   Endless Vacation(无尽假日)  http://www.endlessvacation.com/ 休闲
52   Bride’s Magazine(新娘杂志)  http://www.brides.com 婚礼
53   InformationWeek(信息周刊)  http://www.informationweek.com/ IT
54   Country Living(乡村生活)  http://magazines.ivillage.com/countryliving/ 生活
55   Us Weekly(美国周刊)  http://usweekly.abc.com/ 新闻
56   Marie Claire(玛丽克莱尔)  http://www.marieclaire.com/ 时尚
57   Sunset(日落)  http://www.sunset.com/ 科学
58   Soap Opera Digest(肥皂剧文摘)  http://www.soapoperadigest.com 娱乐
59   AARP Modern Maturity(现代文明)   http://www.modernmaturity.org/ 公益
60   GQ   http://www.gq.com/ 时尚
61   Architectural Digest(建筑学文摘)  http://www.condenet.com/mags/archdigest/ 建筑
62   Harper’s Bazaar(哈泼氏)  http://www.harpersbazaar.com/ 时尚
63   Travel Agent(旅游代理)  http://www.travelagents.com/ 旅游
64   Smithsonian(史密森尼)  http://www.si.edu/ 博物
65   PC World(PC世界)  http://www.pcworld.com/ IT
66   Modern Bride(现代新娘)  http://www.modernbride.com/ 婚礼
67   Men’s Health(男性健康)  http://www.menshealth.com/ 健康
68   Bon Appetit(好 )  http://www.epicurious.com/b_ba/b00_home/ba.html 烹饪
69   Motor Trend(机车潮流)  http://www.motortrend.com/ 机车
70   Economist, The(经济学人)  http://www.economist.com/ 政经
71   Self(自我)  http://www.self.com/ 妇女
72   Shape(体形)  http://www.shapeonline.com/ 健康
73   Teen People   http://www.teenpeople.com/teenpeople/ 青年
74   YM   http://www.ym.com 时尚
75   Consumer Reports(消费者报告)  http://www.consumerreports.org/main/home.jsp 生活
76   Cooking Light(烹饪之光)  http://www.cookinglight.com/ 烹饪
77   Travel Weekly(旅行周刊)  http://www.travelweekly.co.uk/tw_home/home.asp 旅游
78   House Beautiful(美丽住宅)  http://magazines.ivillage.com/housebeautiful/ 家居
79   Ebony(乌木)  http://www.ebony.com/ 成人
80   Popular Photography(大众摄影)  http://www.popularphotography.com/index.asp 摄影
81   Country Home(乡村家庭)  http://www.countryhome.com/ch/index.html 家庭
82   Barron’s   http://www.barrons.com/ 商业
83   eWeek   http://www.eweek.com 消费
84   Conde Nast Traveler   http://www.concierge.com/cntraveler/ 旅游
85   Town & Country(城镇和乡村)   http://magazines.ivillage.com/townandcountry/ 生活
86   InfoWorld(信息世界)   http://www.infoworld.com/ IT
87   EE Times   http://www.eetimes.com/ 电子
88   Food & Wine(食物和酒)   http://www.foodandwine.com/ 食品
89   New York(纽约)   http://www.newyorkmetro.com/ 城市
90   Essence(本质)   http://www.essence.com/ 黑人
91   Road & Track(公路与轨迹)   http://www.roadandtrack.com/ 机车
92   Health(健康)   http://www.health.com/ 健康
93   Inc(公司)   http://www.inc.com/home/ 商业
94   Allure(吸引)   http://www.allure.com/ 时尚
95   Vibe   http://www.vibe.com/new/home/pointer.html 娱乐
96   Gourmet(美食家)   http://www.gourmet.com/ 烹饪
97   Taste of Home(家的滋味)   http://www.tasteofhome.com/ 烹饪
98   Muscle & Fitness(肌肉和健身)   http://www.muscleandfitness.com/ 健康
99   Popular Mechanics(大众机械)   http://popularmechanics.com/ 机械
100   Home(家)   http://www.homemag.com/ 家居
101   fitness(健身)   http://www.fitnessmagazine.com/home/index.jsp 健康
102   Field & Stream(田园和小溪)   http://www.fieldandstream.com/ 休闲
103   American Baby(美国宝贝)   http://www.americanbaby.com/ab/CDA/homepage/ 家庭
104   FamilyFun(家庭乐趣)   http://familyfun.go.com/ 家庭
105   Sporting News, The(体育新闻)   http://www.sportingnews.com/ 体育
106   Esquire(先生)   http://www.esquire.com/ 男性
107   Penthouse(小棚屋)   http://www.penthouse.com/ 成人
108   Kiplinger’s Personal Finance Magazine(吉朴林的个人金融杂志)   http://www.kiplinger.com/ 理财
109   Globe(环球)   http://www.boston.com/globe/ 环境
110   SmartMoney(精明理财)   http://www.smartmoney.com/ 理财
111   Stuff(素材)   http://www.stuffmagazine.com/ 男性
112   CRN   http://www.crn.com/ IT
113   Men’s Journal(男人)   http://www.mensjournal.com/ 男性
114   House & Garden(家园)   http://www.condenet.com/mags/hg/ 家居
115   Fast Company(快速公司)   http://www.fastcompany.com/homepage/ 商业
116   Computer Shopper(计算机购物者)   http://shopper.cnet.com/ 消费
117   Jet(黑玉)   http://www.jetmag.com/ 黑人
118   First For Women    http://www.ffwmarket.com/ 妇女
119   Traditional Home(传统家庭)   http://www.traditionalhome.com/ 家庭
120   Automobile Magazine(汽车杂志)   http://www.automobilemag.com/ 机车
121   Red Herring(红鲱鱼)   http://www.redherring.com/ 商业
122   Highlights for Children(儿童文粹)   http://www.highlights.com/ 儿童
123   Wired(连线)   http://www.wired.com/ IT
124   Outside(户外)   http://outsidemag.com/index.html 休闲
125   This Old House(这个老屋子)   http://www.thisoldhouse.com/toh/ 家居
126   NetworkWorld(网络世界)   http://www.networkworld.com/ IT
127   Entrepreneur(企业家)   http://www.entrepreneur.com/ 商业
128   Popular Science(大众科学)   http://www.popsci.com/popsci/ 科普
129   Elle Decor    http://www.elledecor.co.th/ 设计
130   Quick Cooking (速煮)   http://www.quickcooking.com/ 烹饪
131   Family Handyman(家庭佣人)   http://www.familyhandyman.com/ 家居
132   Science(科学)   http://www.sciencemag.org/ 科学
133   Bridal Guide(新娘指南)   http://www.bridalguide.com/ 婚礼
134   Child(孩子)   http://www.child.com/index.jsp 家庭
135   Cable Guide(有线电视指南)   http://www.cableguide.co.uk/ 娱乐
136   Midwest Living(中西部生活)   http://www.midwestliving.com/ 生活
137   Metropolitan Home(大城市生活)   http://www.mho.co.uk/ 生活
138   Chronicle of Higher Education, The(高等教育编年史)   http://chronicle.com/ 教育
139   Mutual Funds Magazine(互动基金杂志)  http://www.mutual-funds.com/mfmag/ 商业
140   Travelhost(旅游主人)   http://www.travelhost.com/ 旅游
141   Sound & Vision(声与影)   http://www.soundandvisionmag.com/index.asp 电影
142   CIO(首席信息官)   http://www.cio.com/ IT
143   Hot Rod    http://www.hotrod.com/ 机车
144   Computerworld(计算机世界)   http://www.computerworld.com/ IT
145   Source, The(来源)   http://www.thesource.com/ 黑人
146   Departures(启程)   http://www.departures.com/ 商业
147   Spin(旋转)   http://www.spin.com/ 音乐
148   Travel Holiday(旅行假日)   http://www.travelholiday.com/ 旅游
149   Black Enterprise(黑人企业)   http://www.blackenterprise.com/ 商业
150   BabyTalk(宝贝说话)   http://www.parenting.com/parenting/...s/babytalk.html 家庭
151   New England Journal of Medicine(新英格兰医学期刊)   http://content.nejm.org/ 医学
152   EBN Electronic Buyer’s News(EBN电子买主新闻)   http://www.ebnonline.com/ 电子
153   Jane(简)   http://www.janes.com/ 军事
154   Working Mother(妇女运动者)   http://www.workingwoman.com/ 妇女
155   Men’s Fitness(男性健身)   http://www.mensfitness.com/mens.html 健康
156   Victoria(维多利亚)   http://magazines.ivillage.com/victoria/ 生活
157   CosmoGirl(都市女孩)   http://www.cosmogirl.com/ 时尚
158   Nation’s Restaurant News(国家餐馆新闻)   http://www.nrn.com/ 行业
159   Harvard Business Review(哈佛商业评论)   http://www.hbr.com 商业
160   FHM(男人帮)   http://www.fhm.com/ 男性
161   Sports Illustrated For Kids(儿童体育画报)   http://www.sikids.com/ 儿童
162   Boating(航船)   http://www.boatingmag.com/ 体育
163   Discover(探索)   http://www.discover.com/ 科普
164   Real Simple(反朴归真)   http://www.realsimple.com/realsimple/ 生活
165   Guideposts(路标)   http://www.guideposts.com/ 宗教
166   Cycle World(环形世界)   http://www.cycleworld.com/xp6/CycleWorld/main.xml 机车
167   EDN   http://www.e-insite.net/ednmag/ 电子
168   Tennis Magazine(网球杂志)   http://www.tennis.com 体育
169   Advertising Age(广告时代)   http://www.adage.com/ 行业
170   Hemispheres(半球)   http://www.hemispheresmagazine.com/home.htm 收藏
171   Fortune Small Business(财富小商业)  http://www.fortune.com/smallbusiness/ 商业
172   Meetings & Conventions(会议)   http://www.meetings-conventions.com/ 行业
173   Worth(价值)   http://www.worth.com/magazine/index.cfm 理财
174   Outdoor Life(户外生活)   http://www.outdoorlife.com/outdoor/ 休闲
175   Official U.S. Playstation Magazine(美国官方PS杂志)  http://www.gamers.com/opm/index.jsp 游戏
176   Automotive News(汽车新闻)   http://www.autonews.com/ 机车
177   Scientific American(科学美国人)   http://www.sciam.com/ 科普
178   Nickelodeon    http://www.nick.com 娱乐
179   More(更多)   http://www.more.com 时尚
180   Ski(滑雪)   http://www.skinet.com/skinet/ 体育
181   Lucky(幸运)   http://www.luckymag.com/ 时尚
182   Interior Design(室内装饰设计)   http://www.interiordesign.net 行业
183   Sky (Delta Air Lines)(天空 三角航线)   http://www.delta-sky.com/ 航线
184   Power & Motoryacht(能源和摩托艇)   http://powerandmotoryacht.about.com/mbody.htm 休闲
185   GamePro(专业游戏)   http://www.gamepro.com/ 游戏
186   JAMA(睡衣裤)   http://jama.ama-assn.org/ 健康
187   Furniture Today(今日家具)   http://www.furnituretoday.com/index.shtml 家居
188   My Generation(我们这一代)   http://www.mygeneration.org/ 音乐
189   Successful Meetings(成功会议)   http://www.successmtgs.com/successmtgs/index.jsp 行业
190   Premiere(首映)   http://www.premiere.com 电影
191   Birds & Blooms(鸟语花香)   http://www.birdsandblooms.com/ 家居
192   Aviation Week & Space Technology(航空技术周刊)   http://www.aviationnow.com/ 休闲
193   Electronic Design(电子设计)   http://www.e-insite.net/ednmag/ 电子
194   T & L Golf(T & L高尔夫)   http://www.tlgolf.com/ 休闲
195   Wine Spectator(酒的旁观者)   http://www.winespectator.com/ 休闲
196   National Geographic Traveler(国家地理旅行者)   http://www.nationalgeographic.com/traveler/ 旅游
197   AutoWeek(汽车周刊)   http://www.autoweek.com/ 机车
198   Wood(木工)    http://www.woodmagazine.com/ 工艺
199   Chemical & Engineering News(化工新闻)   http://pubs.acs.org/cen/ 行业
200   Electronic Gaming Monthly(电子游戏月刊)   http://www.gamers.com/egm/index.jsp 游戏
201   Disney Adventures(迪斯尼冒险)   http://disney.go.com/disneyadventures/ 孩子
202   National Examiner(国家主考者)   http://www.nationalexaminer.com/ 教育
203   Soap Opera Weekly(肥皂剧周刊)   http://www.soapoperaweekly.com/ 娱乐
204   Golf World(高尔夫世界)   http://www.worldgolf.com/ 体育
205   Runner’s World(跑步者世界)   http://www.runnersworld.com/ 体育
206   Country Weekly(乡村周刊)   http://www.countryweekly.com/ 音乐
207   American Way(美国道路)   http://www.americanwaymag.com/ 旅游
208   Upside(上面)   http://www.upside.com/ IT
209   Design News (设计新闻)   http://www.manufacturing.net/ 行业
210   Details(详细资料)   http://www.condenet.com/mags/details/ 时尚
211   American Profile(美国外形)   http://www.americanprofile.com/ 健康
212   ENR   http://enr.construction.com/Default.asp 建筑
213   Machine Design(机械设计)   http://www.machinedesign.com/ 行业
214   PC Gamer(PC游戏玩家)   http://www.pcgamer.com/ 游戏
215   Biography(传记)  http://www.biography.com/ 文学
216   Atlantic Monthly(大西洋月刊)   http://www.theatlantic.com/ 文艺
217   Successful Farming(成功农业)   http://www.agriculture.com/sfonline/ 行业
218   Texas Monthly(德克莎斯月刊)   http://www.texasmonthly.com/ 地区
219   Skiing(滑雪运动)   http://www.skiingmag.com/skiing/ 体育
220   Southern Accents(南方口音)   http://www.southernaccents.com/accents/ 家庭
221   American Rifleman(美国步枪射手)   http://www.americanrifleman.org/site/index.asp 枪械
222   Bassmaster   http://www.bassmaster.com/ 休闲
223   SN-Supermarket News(超级市场新闻)   http://www.supermarketnews.com 行业
224   ABA Journal(美国银行家协会期刊)   http://www.abanet.org/journal/redesign/home.html 行业
225   Nature(自然)   http://www.nature.com/ 科学
226   Architectural Record(建筑学档案)   http://www.archrecord.com/ 行业
227   Adweek(广告周刊)   http://www.adweek.com/adweek/index.jsp 行业
228   Petersen’s 4-Wheel & Off Road   http://www.4wheeloffroad.com/ 机车
229   Business 2.0(商业2.0)   http://www.business2.com/ 商业
230   Flying(飞行)   http://www.flyingmag.com/ 休闲
231   Billboard(公告牌)   http://www.billboard.com/billboard/index.jsp 音乐
232   Coastal Living(海岸生活)   http://www.coastalliving.com/coastal/ 生活
233   Country Woman(乡村女人)   http://www.countrywomanmagazine.com/ 家庭
234   Boys’sLife(男孩生活)   http://www.boyslife.org/ 孩子
235   Transworld Skateboarding(环球滑板)  http://www.skateboarding.com/skate/ 体育
236   NFL Insider(美国足球联盟知情者)   http://ww2.nfl.com/insider/ 体育
237   People en Espanol(人物西班牙语版)   http://www.peopleenespanol.com/pespanol/index.html/ 娱乐
238   Journal of Accountancy(会计学期刊)   http://www.aicpa.org/pubs/jofa/joahome.htm 财务
239   Windows 2000 Magazine(视窗2000杂志)   http://www.win2000mag.net/ IT
240   Veranda(阳台)   http://www.veranda.com/ 家居
241   Video Business(视频商业)   http://www.videobusiness.com/ 商业
242   Backpacker(背包)   http://www.backpacker.com/ 休闲
243   Cigar Aficionado(雪茄迷)   http://www.cigaraficionado.com/ 休闲
244   Telephony(技术)   http://www.telephonyonline.com/ IT
245   Flex(弯曲)   http://www.flexonline.com/ 健康
246   Variety (weekly)(品种周刊)   http://www.variety.com/ 商业
247   Cruising World (巡航世界)   http://www.cruisingworld.com/ 休闲
248   American Hunter(美国猎人)   http://www.american-hunter.com/ 休闲
249   Crain’s Chicago Business(克瑞恩芝加哥商业)   http://www.chicagobusiness.com/ 商业
250   Broadcastin &Cable(宽带与有线电视)   http://www.broadcastingcable.com/ 行业
251   Petersen’s Photographic   http://www.photographic.com/ 摄影
252   Golf for Women(女性高尔夫)   http://www.golfdigest.com/gfw/ 体育
253   US Airways Attache Magazine  
254   Progressive Farmer(改进农场主)   http://www.progressivefarmer.com/farmer/ 农业
255   Easyriders   http://www.easyriders.com/Home/Home.asp 机车
256   Crain’s New York Business(克瑞恩纽约商业)   http://www.crainsny.com/ 商业
257   Yachting(游艇)   http://www.yachtingnet.com/yachting/ 休闲
258   Chicago(芝加哥)   http://www.chicagomag.com/ 城市
259   Computer Gaming World(计算机游戏世界)   http://www.gamers.com/cgw/index.jsp 游戏
260   Video Store(视频商店)   http://www.videostoremag.com/ 商业
261   Country(乡村)    http://www.country-magazine.com/ 生活
262   Fine Homebuilding(好家建造者)   http://www.taunton.com/finehomebuilding/index.asp 家居
263   Yankee(美国佬)   http://www.yankeemagazine.com/travel/index.php 旅游
264   Publisher’s Weekly(出版者周刊)   http://www.publishersweekly.com/ 行业
265   Restaurants & Institutions(餐馆与协会)   http://www.rimag.com/ 行业
266   American Medical News(美国医学新闻)   http://www.ama-assn.org/public/journals/amnews/ 行业
267   North American Hunter(北美猎人)   http://visitors.huntingclub.com/magazine.asp 休闲
268   Federal Computer Week(联邦计算机周刊)   http://www.fcw.com/ IT
269   Guns & Ammo(枪与军火)   http://www.gunsandammomag.com/dynamic.asp 枪械
270   Transworld Snowboarding(环球滑雪板)  http://www.snowboarding-online.com/ 体育
271   New Equipment Digest(新设备文摘)   http://www.newequipment.com/ 行业
272   Weekly World News(世界新闻周刊)    http://www.weeklyworldnews.com/ 新闻
273   Chemical Week(化学周刊)   http://www.chemweek.com/ 行业
274   Four Wheeler(四轮车)   http://www.fourwheeler.com/ 机车
275   Gear(齿轮)    http://www.gearmagazine.com/ 家居
276   Pensions & Investments(养老金和投资)   http://www.pionline.com/ 理财
277   Macworld(Mac世界)    http://www.macworld.com/ IT
278   Builder(建筑者)    http://builder.com.com/ IT
279   RB Restaurant Business(餐馆业)    http://www.foodservicetoday.com/rb/index.shtml 行业
280   CFO(首席运营官)    http://www.cfo.com/ IT
281   American Family Physician(美国家庭医生)   http://www.aafp.org/afp.xml 健康
282   Los Angeles Times Magazine(洛杉矶时报杂志)   http://www.latimes.com/ 新闻
283   Saveur    http://www.saveur.com 烹饪
284   Multichannel News(多频道新闻)   http://www.multichannel.com/ 行业
285   Purchasing(购买)    http://www.manufacturing.net/ 消费
286   Laser Focus World(激光焦点世界)   http://lfw.pennnet.com/home.cfm 行业
287   HANDY(手工)   http://visitors.handymanclub.com/handy_mag.asp 家居
288   Medical Economics(医药经济)   http://www.medec.com/ 行业
289   Reminisce(回忆)   http://www.reminisce.com/ 休闲
290   Pillsbury Classic Cookbooks   http://www.pillsbury.com/ 烹饪
291   Skin Diver(滑水)   http://www.skin-diver.com/ 休闲
292   Nursing 2002   http://www.nursinghomesmagazine.com/ 护理
293   Hemmings Motor News   http://cars.hemmings.com/ 机车
294   American Legion Magazine(美国军团杂志)   http://www.legion.org/ 公益
295   Farm Journal(农业期刊)   http://www.farmjournal.com/ 农业
296   Southwest Airlines Spirit(西南航线精灵)   http://www.spiritmag.com/ 航行
297   Dr. Dobb’s Journal   http://www.ddj.com/ IT
298   Chicago Tribune Magazine(芝加哥论坛杂志)   http://www.chicagotribune.com/features/magazine/ 新闻
299   Islands(岛屿)   http://www.islands.com/ 休闲
300   Institutional Investor(金融机构投资者)   http://www.epinions.com 金融

posted @ 2006-07-05 08:05 多力宇扬 阅读(511) | 评论 (0)编辑 收藏

Ant是什么?
Ant是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷。

既然我们已经有了make, gnumake, nmake, jam以及其他的build工具为什么还要要一种新的build工具呢?因为Ant的原作者在多种(硬件)平台上开发软件时,无法忍受这些工具的限制和不便。类似于make的工具本质上是基于shell(语言)的:他们计算依赖关系,然后执行命令(这些命令与你在命令行敲的命令没太大区别)。这就意味着你可以很容易地通过使用OS特有的或编写新的(命令)程序扩展该工具;然而,这也意味着你将自己限制在了特定的OS,或特定的OS类型上,如Unix。

Makefile也很可恶。任何使用过他们的人都碰到过可恶的tab问题。Ant的原作者经常这样问自己:“是否我的命令不执行只是因为在我的tab前有一个空格?!!”。类似于jam的工具很好地处理了这类问题,但是(用户)必须记住和使用一种新的格式。

Ant就不同了。与基于shell命令的扩展模式不同,Ant用Java的类来扩展。(用户)不必编写shell命令,配置文件是基于XML的,通过调用target树,就可执行各种task。每个task由实现了一个实现了特定Task接口的对象来运行。(如果你对Ant一点概念都没有的话,可能看不懂这一节,没有关系,后面会对target,task做详细的介绍。你如果没有太多的时间甚至可以略过这一节,然后再回来浏览一下这里的介绍,那时你就会看懂了。同样,如果你对make之类的工具不熟悉也没关系,下面的介绍根本不会用到make中的概念。)

必须承认,这样做,在构造shell命令时会失去一些特有的表达能力。如`find . -name foo -exec rm {}`,但却给了你跨平台的能力-你可以在任何地方工作。如果你真的需要执行一些shell命令,Ant有一个<exec> task,这个task允许执行特定OS上的命令。

安装Ant
由于Ant是一个Open Source的软件,所以有两种安装Ant的方式,一种是用已编译好的binary 文件安装Ant,另一种是用源代码自己build Ant。

binary 形式的Ant可以从http://jakarta.apache.org/builds/ant/release/v1.4.1/bin下载。如果你希望你能自己编译Ant,则可从 http://jakarta.apache.org/builds/ant/release/v1.4.1/src。注意所列出的连接都是最新发行版的Ant。如果你读到此文时,发现已经有了更新的版本,那么请用新版本。如果你是一个疯狂的技术追求者,你也可以从Ant CVS repository下载最新版本的Ant。

系统需求

要想自己build Ant。你需要一个JAXP兼容的XML解析器(parser)放在你的CLASSPATH系统变量中。

binary 形式的Ant包括最新版的Apache Crimson XML解析器。你可以从http://java.sun.com/xml/ 得到更多的关于JAXP的信息。如果你希望使用其他的JAXP兼容的解析器。你要从Ant的lib目录中删掉jaxp.jar以及crimson.jar。然后你可将你心爱的解析器的jar文件放到Ant的lib目录中或放在你的CLASSPATH系统变量中。

对于当前版本的Ant,需要你的系统中有JDK,1.1版或更高。未来的Ant版本会要求使用JDK 1.2或更高版本。

binary 版的Ant包括三个目录:bin, docs 和lib。只有bin和lib目录是运行Ant所需的。要想安装Ant,选择一个目录并将发行版的文件拷贝到该目录下。这个目录被称作ANT_HOME。

在你运行Ant之前需要做一些配置工作。

将bin目录加入PATH环境变量。
设定ANT_HOME环境变量,指向你安装Ant的目录。在一些OS上,Ant的脚本可以猜测ANT_HOME(Unix和Windos NT/2000)-但最好不要依赖这一特性。
可选地,设定JAVA_HOME环境变量(参考下面的高级小节),该变量应该指向你安装JDK的目录。

注意:不要将Ant的ant.jar文件放到JDK/JRE的lib/ext目录下。Ant是个应用程序,而lib/ext目录是为JDK扩展使用的(如JCE,JSSE扩展)。而且通过扩展装入的类会有安全方面的限制。

可选Task

Ant支持一些可选task。一个可选task一般需要额外的库才能工作。可选task与Ant的内置task分开,单独打包。这个可选包可以从你下载Ant的同一个地方下载。目前包含可选task的jar文件名叫jakarta-ant-1.4.1-optional.jar。这个jar文件应该放到Ant安装目录的lib目录下。

每个可选task所需的外部库可参看依赖库小节。这些外部库可以放到Ant的lib目录下,这样Ant就能自动装入,或者将其放入环境变量中。

Windows

假定Ant安装在c:\ant\目录下。下面是设定环境的命令:

set ANT_HOME=c:\ant
set JAVA_HOME=c:\jdk1.2.2
set PATH=%PATH%;%ANT_HOME%\bin
Unix (bash)

假定Ant安装在/usr/local/ant目录下。下面是设定环境的命令:

export ANT_HOME=/usr/local/ant
export JAVA_HOME=/usr/local/jdk-1.2.2
export PATH=${PATH}:${ANT_HOME}/bin
高级

要想运行Ant必须使用很多的变量。你至少参考需要下面的内容:

Ant的CLASSPATH必须包含ant.jar以及你所选的JAXP兼容的XML解析器的jar文件。
当你需要JDK的功能(如javac或rmic task)时,对于JDK 1.1,JDK的classes.zip文件必须放入CLASSPATH中;对于JDK 1.2或JDK 1.3,则必须加入tools.jar。如果设定了正确的JAVA_HOME环境变量,Ant所带的脚本,在bin目录下,会自动加入所需的JDK类。
当你执行特定平台的程序(如exec task或cvs task)时,必须设定ant.home属性指向Ant的安装目录。同样,Ant所带的脚本利用ANT_HOME环境变量自动设置该属性。
Building Ant

要想从源代码build Ant,你要先安装Ant源代码发行版或从CVS中checkout jakarta-ant模块。

安装好源代码后,进入安装目录。

设定JAVA_HOME环境变量指向JDK的安装目录。要想知道怎么做请参看安装Ant小节。

确保你已下载了任何辅助jar文件,以便build你所感兴趣的task。这些jar文件可以放在CLASSPATH中,也可以放在lib/optional目录下。参看依赖库小节可知不同的task需要那些jar文件。注意这些jar文件只是用作build Ant之用。要想运行Ant,你还要像安装Ant小节中所做的那样设定这些jar文件。

现在你可以build Ant了:

build -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Windows)
build.sh -Ddist.dir=<directory_to_contain_Ant_distribution> dist (Unix)

这样就可你指定的目录中创建一个binary版本。

上面的命令执行下面的动作:

如果有必要可以bootstrap Ant的代码。bootstrap 包括手工编辑一些Ant代码以便运行Ant。bootstrap 用于下面的build步骤。
向build脚本传递参数以调用bootstrap Ant。参数定义了Ant的属性值并指定了Ant自己的build.xml文件的"dist" target。

大多数情况下,你不必直接bootstrap Ant,因为build脚本为你完成这一切。运行bootstrap.bat (Windows) 或 bootstrap.sh (UNIX) 可以build一个新的bootstrap版Ant。


如果你希望将Ant安装到ANT_HOME目录下,你可以使用:

build install (Windows)
build.sh install (Unix)

如果你希望跳过冗长的Javadoc步骤,可以用:

build install-lite (Windows)
build.sh install-lite (Unix)

这样就只会安装bin和lib目录。

注意install和install-lite都会覆盖ANT_HOME中的当前Ant版本。

依赖库

如果你需要执行特定的task,你需要将对应的库放入CLASSPATH或放到Ant安装目录的lib目录下。注意使用mapper时只需要一个regexp库。同时,你也要安装Ant的可选jar包,它包含了task的定义。参考上面的安装Ant小节。

Jar Name Needed For Available At
An XSL transformer like Xalan or XSL:P style task http://xml.apache.org/xalan-j/index.html or http://www.clc-marketing.com/xslp/
jakarta-regexp-1.2.jar regexp type with mappers jakarta.apache.org/regexp/
jakarta-oro-2.0.1.jar regexp type with mappers and the perforce tasks jakarta.apache.org/oro/
junit.jar junit tasks www.junit.org
stylebook.jar stylebook task CVS repository of xml.apache.org
testlet.jar test task java.apache.org/framework
antlr.jar antlr task www.antlr.org
bsf.jar script task oss.software.ibm.com/developerworks/projects/bsf
netrexx.jar netrexx task www2.hursley.ibm.com/netrexx
rhino.jar javascript with script task www.mozilla.org
jpython.jar python with script task www.jpython.org
netcomponents.jar ftp and telnet tasks www.savarese.org/oro/downloads

运行Ant
运行Ant非常简单,当你正确地安装Ant后,只要输入ant就可以了。

没有指定任何参数时,Ant会在当前目录下查询build.xml文件。如果找到了就用该文件作为buildfile。如果你用 -find 选项。Ant就会在上级目录中寻找buildfile,直至到达文件系统的根。要想让Ant使用其他的buildfile,可以用参数 -buildfile file,这里file指定了你想使用的buildfile。

你也可以设定一些属性,以覆盖buildfile中指定的属性值(参看property task)。可以用 -Dproperty=value 选项,这里property是指属性的名称,而value则是指属性的值。也可以用这种办法来指定一些环境变量的值。你也可以用property task来存取环境变量。只要将 -DMYVAR=%MYVAR% (Windows) 或 -DMYVAR=$MYVAR (Unix) 传递给Ant -你就可以在你的buildfile中用${MYVAR}来存取这些环境变量。

还有两个选项 -quite,告诉Ant运行时只输出少量的必要信息。而 -verbose,告诉Ant运行时要输出更多的信息。

可以指定执行一个或多个target。当省略target时,Ant使用标签<project>的default属性所指定的target。

如果有的话,-projecthelp 选项输出项目的描述信息和项目target的列表。先列出那些有描述的,然后是没有描述的target。

命令行选项总结:

ant [options] [target [target2 [target3] ...]]
Options:
-help print this message
-projecthelp print project help information
-version print the version information and exit
-quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
-emacs produce logging information without adornments
-logfile file use given file for log output
-logger classname the class that is to perform logging
-listener classname add an instance of class as a project listener
-buildfile file use specified buildfile
-find file search for buildfile towards the root of the filesystem and use the first one found
-Dproperty=value set property to value
例子

ant

使用当前目录下的build.xml运行Ant,执行缺省的target。

ant -buildfile test.xml

使用当前目录下的test.xml运行Ant,执行缺省的target。

ant -buildfile test.xml dist

使用当前目录下的test.xml运行Ant,执行一个叫做dist的target。

ant -buildfile test.xml -Dbuild=build/classes dist

使用当前目录下的test.xml运行Ant,执行一个叫做dist的target,并设定build属性的值为build/classes。

文件

在Unix上,Ant的执行脚本在做任何事之前都会source(读并计算值)~/.antrc 文件;在Windows上,Ant的批处理文件会在开始时调用%HOME%\antrc_pre.bat,在结束时调用%HOME%\antrc_post.bat。你可以用这些文件配置或取消一些只有在运行Ant时才需要的环境变量。看下面的例子。

环境变量

包裹脚本(wrapper scripts)使用下面的环境变量(如果有的话):

JAVACMD Java可执行文件的绝对路径。用这个值可以指定一个不同于JAVA_HOME/bin/java(.exe)的JVM。
ANT_OPTS 传递给JVM的命令行变量-例如,你可以定义属性或设定Java堆的最大值

手工运行Ant

如果你自己动手安装(DIY)Ant,你可以用下面的命令启动Ant:

java -Dant.home=c:\ant org.apache.tools.ant.Main [options] [target]

这个命令与前面的ant命令一样。选项和target也和用ant命令时一样。这个例子假定你的CLASSPATH包含:

ant.jar

jars/classes for your XML parser

the JDK's required jar/zip files

编写build.xml
Ant的buildfile是用XML写的。每个buildfile含有一个project。

buildfile中每个task元素可以有一个id属性,可以用这个id值引用指定的任务。这个值必须是唯一的。(详情请参考下面的Task小节)

Projects

project有下面的属性:

Attribute Description Required
name 项目名称. No
default 当没有指定target时使用的缺省target Yes
basedir 用于计算所有其他路径的基路径。该属性可以被basedir property覆盖。当覆盖时,该属性被忽略。如果属性和basedir property都没有设定,就使用buildfile文件的父目录。 No

项目的描述以一个顶级的<description>元素的形式出现(参看description小节)。

一个项目可以定义一个或多个target。一个target是一系列你想要执行的。执行Ant时,你可以选择执行那个target。当没有给定target时,使用project的default属性所确定的target。

Targets

一个target可以依赖于其他的target。例如,你可能会有一个target用于编译程序,一个target用于生成可执行文件。你在生成可执行文件之前必须先编译通过,所以生成可执行文件的target依赖于编译target。Ant会处理这种依赖关系。

然而,应当注意到,Ant的depends属性只指定了target应该被执行的顺序-如果被依赖的target无法运行,这种depends对于指定了依赖关系的target就没有影响。

Ant会依照depends属性中target出现的顺序(从左到右)依次执行每个target。然而,要记住的是只要某个target依赖于一个target,后者就会被先执行。

<target name="A"/>
<target name="B" depends="A"/>
<target name="C" depends="B"/>
<target name="D" depends="C,B,A"/>

假定我们要执行target D。从它的依赖属性来看,你可能认为先执行C,然后B,最后A被执行。错了,C依赖于B,B依赖于A,所以先执行A,然后B,然后C,最后D被执行。

一个target只能被执行一次,即时有多个target依赖于它(看上面的例子)。

如果(或如果不)某些属性被设定,才执行某个target。这样,允许根据系统的状态(java version, OS, 命令行属性定义等等)来更好地控制build的过程。要想让一个target这样做,你就应该在target元素中,加入if(或unless)属性,带上target因该有所判断的属性。例如:

<target name="build-module-A" if="module-A-present"/>
<target name="build-own-fake-module-A" unless="module-A-present"/>

如果没有if或unless属性,target总会被执行。

可选的description属性可用来提供关于target的一行描述,这些描述可由-projecthelp命令行选项输出。

将你的tstamp task在一个所谓的初始化target是很好的做法,其他的target依赖这个初始化target。要确保初始化target是出现在其他target依赖表中的第一个target。在本手册中大多数的初始化target的名字是"init"。

target有下面的属性:

Attribute Description Required
name target的名字 Yes
depends 用逗号分隔的target的名字列表,也就是依赖表。 No
if 执行target所需要设定的属性名。 No
unless 执行target需要清除设定的属性名。 No
description 关于target功能的简短描述。 No

Tasks

一个task是一段可执行的代码。

一个task可以有多个属性(如果你愿意的话,可以将其称之为变量)。属性只可能包含对property的引用。这些引用会在task执行前被解析。

下面是Task的一般构造形式:

<name attribute1="value1" attribute2="value2" ... />

这里name是task的名字,attributeN是属性名,valueN是属性值。

有一套内置的(built-in)task,以及一些可选task,但你也可以编写自己的task。

所有的task都有一个task名字属性。Ant用属性值来产生日志信息。

可以给task赋一个id属性:

<taskname id="taskID" ... />

这里taskname是task的名字,而taskID是这个task的唯一标识符。通过这个标识符,你可以在脚本中引用相应的task。例如,在脚本中你可以这样:

<script ... >
task1.setFoo("bar");
</script>

设定某个task实例的foo属性。在另一个task中(用java编写),你可以利用下面的语句存取相应的实例。

project.getReference("task1").

注意1:如果task1还没有运行,就不会被生效(例如:不设定属性),如果你在随后配置它,你所作的一切都会被覆盖。

注意2:未来的Ant版本可能不会兼容这里所提的属性,因为很有可能根本没有task实例,只有proxies。

Properties

一个project可以有很多的properties。可以在buildfile中用property task来设定,或在Ant之外设定。一个property有一个名字和一个值。property可用于task的属性值。这是通过将属性名放在"${"和"}"之间并放在属性值的位置来实现的。例如如果有一个property builddir的值是"build",这个property就可用于属性值:${builddir}/classes。这个值就可被解析为build/classes。

内置属性

如果你使用了<property> task 定义了所有的系统属性,Ant允许你使用这些属性。例如,${os.name}对应操作系统的名字。

要想得到系统属性的列表可参考the Javadoc of System.getProperties。

除了Java的系统属性,Ant还定义了一些自己的内置属性:
basedir project基目录的绝对路径 (与<project>的basedir属性一样)。
ant.file buildfile的绝对路径。
ant.version Ant的版本。
ant.project.name 当前执行的project的名字;由<project>的name属性设定.
ant.java.version Ant检测到的JVM的版本; 目前的值有"1.1", "1.2", "1.3" and "1.4".
例子:
<?xml version="1.0" encoding="GB2312"?>

 <project name="MyApp" default="compile" basedir=".">
 <!--定义你需要的属性-->
  <property environment="env" />
  <property name="src" value="WEB-INF/src" />
  <property name="classes" value="WEB-INF/classes" />
  <property name="lib" value="WEB-INF/lib" />
  <property name="dist" value="dist" />
 
  <path id="task.classpath">
    <pathelement location="${classes}" />
    <pathelement location="${lib}" />
   
    <!-- Tomcat 5.0.16 Servlet 2.4 API -->
    <pathelement location="${lib}/servlet-api.jar" />
   
    <!-- Tomcat 5.0.16 JSP 2.0 API -->
    <pathelement location="${lib}/jsp-api.jar" />
   
  </path>
 
<!--定义操作--> 
  <target name="init" >
    <echo>初始化完成!</echo>
    <echo>ant home = ${ant.home} </echo>
    <echo>java home = ${java.home} </echo>
    <echo>user home = ${user.home} </echo>       
      
  </target>
 
<!--depends定义依赖-->
  <target name="compile" depends="init" >
    <javac classpathref="task.classpath" srcdir="${src}" destdir="${classes}" />
    <echo level="verbose">Seen with -verbose</echo>
    <echo level="debug">Seen with -debug</echo>       
    <echo>编译完成!</echo>
  </target>
 
  <target name="war" >
    <jar jarfile="${dist}/MyApp.war" basedir="."/>
  </target>

</project>

Token Filters
一个project可以有很多tokens,这些tokens在文件拷贝时会被自动扩展,这要求在支持这一行为的task中选择过滤拷贝功能。这一功能可用filter task在buildfile中设定。

既然这很可能是一个有危害的行为,文件中的tokens必须采取@token@的形式,这里token是filter task中设定的token名。这种token语法与其他build系统执行类似filtering的语法相同,而且与大多数的编程和脚本语言以及文档系统并不冲突,

注意:如果在一个文件中发现了一个@token@形式的token,但没有filter与这个token关连,则不会发生任何事;因此,没有转义方法-但只要你为token选择合适的名字,就不会产生问题。

警告:如果你在拷贝binary文件时打开filtering功能,你有可能破坏文件。这个功能只针对文本文件。

Path-like Structures
你可以用":"和";"作为分隔符,指定类似PATH和CLASSPATH的引用。Ant会把分隔符转换为当前系统所用的分隔符。

当需要指定类似路径的值时,可以使用嵌套元素。一般的形式是

<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>
location属性指定了相对于project基目录的一个文件和目录,而path属性接受逗号或分号分隔的一个位置列表。path属性一般用作预定义的路径--其他情况下,应该用多个location属性。

为简洁起见,classpath标签支持自己的path和location属性。所以:

<classpath>
<pathelement path="${classpath}"/>
</classpath>
可以被简写作:

<classpath path="${classpath}"/>
也可通过<fileset>元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的。

<classpath>
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</classpath>
上面的例子构造了一个路径值包括:${classpath}的路径,跟着lib目录下的所有jar文件,接着是classes目录。

如果你想在多个task中使用相同的path-like structure,你可以用<path>元素定义他们(与target同级),然后通过id属性引用--参考Referencs例子。

path-like structure可能包括对另一个path-like structurede的引用(通过嵌套<path>元素):

<path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>
<path id="tests.path">
<path refid="base.path"/>
<pathelement location="testclasses"/>
</path>

前面所提的关于<classpath>的简洁写法对于<path>也是有效的,如:

<path id="tests.path">
  <path refid="base.path"/>
<pathelement location="testclasses"/>
</path>
可写成:

<path id="base.path" path="${classpath}"/>
命令行变量

有些task可接受参数,并将其传递给另一个进程。为了能在变量中包含空格字符,可使用嵌套的arg元素。

Attribute Description Required
value 一个命令行变量;可包含空格字符。 只能用一个
line 空格分隔的命令行变量列表。
file 作为命令行变量的文件名;会被文件的绝对名替代。
path 一个作为单个命令行变量的path-like的字符串;或作为分隔符,Ant会将其转变为特定平台的分隔符。

例子

<arg value="-l -a"/>
是一个含有空格的单个的命令行变量。

<arg line="-l -a"/>
是两个空格分隔的命令行变量。

<arg path="/dir;/dir2:\dir3"/>
是一个命令行变量,其值在DOS系统上为\dir;\dir2;\dir3;在Unix系统上为/dir:/dir2:/dir3 。

References

buildfile元素的id属性可用来引用这些元素。如果你需要一遍遍的复制相同的XML代码块,这一属性就很有用--如多次使用<classpath>结构。

下面的例子:

<project ... >
<target ... >    
<rmic ...>      
<classpath>        
<pathelement location="lib/"/>        
<pathelement path="${java.class.path}/"/>        
<pathelement path="${additional.path}"/>      
</classpath>    
</rmic>  
</target>
<target ... >
<javac ...>
<classpath>
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</classpath>
</javac>
</target>
</project>
可以写成如下形式:

<project ... >
<path id="project.class.path">  
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>  
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
所有使用PatternSets, FileSets 或 path-like structures嵌套元素的task也接受这种类型的引用

posted @ 2006-07-04 14:44 多力宇扬 阅读(327) | 评论 (0)编辑 收藏

JavaServer Pages Standard Tag Libray(1.1),其中文名字为JSP标准标签函数库。JSTL是一个标准的已
制定好的标签库,可以应用于各种领域,如:基本输入输出,流程控制,循环,XML文件剖析,数据库查
询以及国际化和文字格式标准化的应用等。JSTL所提供的标签库分为以下五大类:
 核心标签库(Core tag Liabry)
 I18N格式标签库(I18N-capable formatting tag libary)
 SQL标签库(SQL tag Libary)
 XML标签库(XML tag Libary)
 函数标签库(Functions tag Libary)

核心标签库(Core tag Liabry)主要有:基本输入输出,流程控制,迭代操作和URL操作。
 ----------------------------------------------------------------------------
      分类            功能分类                 标签分类
                                                             out
                                                              set
                          表达式操作                     remove
                                                                   catch
  
     Core                                                      if
                                                                   choose
                           流程控制                            when
                                                                       outherwise

                                                                    forEach
                              迭代操作                      forTokens

                                                                       import
                                                                          param
                                                                       url
                                 URL操作                          param
                                                                     redirect
                                                                           param
------------------------------------------------------------------------------------------
在JSP中使用JSTL中的标签库时,必须使用<%@taglib%>指令,并且设定prefix和uri的值得,通常设定:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
这样就可以使用核心标签库了。

.表达式操作
 表达式操作分类中包含四个标签: <c:out>,<c:set>,<c:remove>和<c:catch>
<c:out>:重要用来显示数据的内容,类似与<%=scripting-language%>。它的语法如下:
语法1: 没有body内容
<c:out value="value" [escapeXml="{true|false}"] [default="defaultValue"]/>

语法2: 有body内容
<c:out value="value"  [escapeXml="{true|false}"]>
  default value
</c:out>

Attribute
-----------------------------------------------------------------------------------------------------------------------
 名称                      说明                                                               EL     类型     必须       默认值
value                  需要显示的值                                                     Y      Object    是          无
default               如果value值为null,则显示default的值                  Y      Object    否          无
escapeXml        是否转换特殊字符,如: <转换为&It                 Y      Object    否          true
----------------------------------------------------------------------------------------------------------------------
Null和错误说明
假若value为null,会显示default的值;假若没有设定default的值,则会显示一个空的字符串。

<c:set>:主要用来把变量存储至JSP范围或是JavaBean的属性中。
语法1: 没有body
将value的值存储至范围为scope的varName变量之中
<c:set value="value" var="varName" [scope="{page|request|session|application}"]/>

语法2: 有body
将body内容存储至范围为scope的varName变量之中
<c:set value="value" [scope="{page|request|session|application}"]>
  body.....
</c:set>

语法3: 将value的值存储至target对象属性中
<c:set value="value" target="target" property="propertyNmae"/>

语法4: 将body内容的数据存储至target对象属性中
<c:set target="target" property="propertyNmae">
 body....
</c:set>

Attribute
----------------------------------------------------------------------------------------
 名称                    说明                                              EL     类型      必须      默认值
value             要被存储的值                                      Y      Object      否          无
var                欲存入的变量名                                  N      String        否          无
scope            var变量的JSP范围                               N      String        否         page
target            为一JavaBean或java.util.Map对象        Y      Object       否          无
property        指定target对象属性                              Y      String        否          无
------------------------------------------------------------------------------------------
Null 和 错误处理:
语法3和语法4会产生异常错误,有以下两种情况:
 .target 为null
 .target 不是java.util.Map或JavaBean对象
假若value为null时:将由存储变量改为移除变量
 .语法1: 由var和scope所定义的变量,将被移除
    .若scope已指定时,则PageContext.removeAttribute(varName,scope);
    .若scope未指定时,则PageContext.removeAttribute(varName);
 .语法3:
    .假若target为Map时,则Map.remove(property);
    .假若target为JavaBean时,propertye指定的属性为null
注意: var和scope这两个属性不能使用表达式来表示,我们不能写成 scope="${ourScope}"或var="${a}"

<c:remove>:主要用来移除变量。
语法:
<c:remove var="varName" [scope="{page|request|session|application}"]/>

Attribute
----------------------------------------------------------------------------------------
 名称                 说明                                     EL     类型     必须       默认值
 var             欲移除变量的名称                     N      String     是              无
 scope           var变量的JSP范围                    N      String     否             page
----------------------------------------------------------------------------------------
说明:
<c:remove>必须要有var属性,即要被移除的属性名称,scope则可有可无,如:
<c:remove var="username" scope="session"/>
将username变量从session范围移除。若我们不设定scope,则<c:remove>会移除所有范围名称为username
的数据。

<c:catch>:主要用来处理产生错误的异常情况,并且将信息保存起来。
语法:
<c:catch [var="varName"]>
 ...欲抓取错误的部分...
</c:catch>

Attribute
----------------------------------------------------------------------------------------
 名称                 说明                                           EL     类型     必须       默认值
 var           用来存储错误信息的变量                 N      String       否          无
-----------------------------------------------------------------------------------------
说明:
<c:catch>主要将可能发生错误的部分放在<c:catch>和</c:catch>之间。如果真的发生错误,可将错误
信息保存至变量varName标量中,如:
<c:catch var="message">
    //可能发生错误的部分
</catch>
另外,当错误发生<c:catch>和</c:catch>之间时,只有<c:catch>和</c:catch>之间的程序会被中止忽
略,但整个网页不会被中止。

流程控制
流程控制分类中包含四个标签:<c:if>,<c:choose>,<c:when>和<c:otherwise>。

<c:if>:的用途和我们在一般程序中写的if一样。
语法:
语法1:没有body
<c:if test="testCondition" var="varName" [scope="{page|request|session|application}"]/>

语法2: 有body
<c:if test="testCondition" [var="varName"] [scope="{page|request|session|appliation}"]>
  ...body....
</c:if>

Attribute
------------------------------------------------------------------------------------------------------------------------
 名称                           说明                                                                           EL     类型        必须       默认值
test                   如果表达式的结果为true则执行body,false则相反              Y      boolean       是           无
var                   用来存储test运算后的结果,即true或false                           N     String          否           无
scope               var变量的JSP范围                                                                  N     String          否          page
------------------------------------------------------------------------------------------------------------------------
说明:
<c:if>标签必须要有test属性,body里除了能是静态文本之外可以是任何JSP代码,标签或HTML代码。

<c:choose>:本身只当作<c:when>和<c:otherwise>的父标签。
语法:
<c:choose>
  body(<when>和<otherwise>)
</c:choose>
限制:
<c:choose>的本地内容只能有:
 .空白
 .1或多个<c:when>
 .0或多个<c:otherwise>
如:
<c:choose>

 <c:when test="${condition1}">
   condition1 为 true
 </c:when>

 <c:when test="${condition2}">
   condition2 为 true
 </c:when>

 <c:otherwise>
   condition1和conditon2都为false
 </<c:otherwise >
 
</c:choose>
说明:
在同一个<c:choose>中,假如所有的<c:when>的test都不为true时,则执行<c:otherwise>的本体内容。
在同一个<c:choose>中,假若有好几个<c:when>都会true时,只能有一个<c:when>成立。

迭代操作
迭代(Iterator)操作主要包含两个标签: <c:forEach>和<c:forTokens>。

<c:forEach>为循环控制,它可以将集合(Collection)中的成员循序浏览一遍。运做方式为当条件符合
时,就会持续重复执行<c:forEach>的body内容。
语法:
语法1: 迭代一集合对象之所有成员
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
           [begin="begin"] [end="end"] [step="step"]>
 ...body内容.....
<c:forEach>

语法2: 迭代指定的次数
<c:forEach [var="varName"] [varStatus="varStatusName"]
           begin="begin" end="end" [step="step"]>
 ...body内容.....
<c:forEach>

Attribute
--------------------------------------------------------------------------------------------------------------------------
 名称                 说明                                                   EL     类型             必须       默认值
 var          用来存放现在指到的成员                          N      String               否           无

                                                                                               Arrays
                                                                                              Collection
                                                                                               Iterator             否           无
items         被迭代的集合对象                                    Y        Enumeration            
                                                                                               Map
                                                                                                String

varStatus     用来存放到指到的相关成员信息          N        String               否           无
begin           开始的位置                                             Y          int                    否           0
end              结束的位置                                             Y          int                   否           最后一个成员
setp             每次迭代的间隔数                                 Y          int                   否            1
-------------------------------------------------------------------------------------------------------------------------
Null 和 错误处理
.假若items为null时,则表示为一空的集合对象
.假若begin大于或等于items时,则迭代不运算
注意:
varName的范围只存在<c:forEach>的本体中,如果超出了本题,则不能取得varName的值。如:
<c:forEach items="${atts}" var="item">
</c:forEach>
${item}</br>
${item}则不会显示item的内容。<c:forEach>除了支持数组之外,还有标准的J2SE的结合类型,例如:
ArrayList,List,LinkedList,Vector,Stack和Set等等;另外包括java.util.Map类的对象,例如:
HashMap,Hashtable,Properties,Provider和Attributes。

另外<c:forEach>还提供了varStatus属性,主要用来存放现在指到成员的相关信息。例如:我们写成
varStatus="s",那么就会把信息存放到名称为s的属性当中。varStatus属性还提供另外四个属性:index,
count,fist和last,它们个自的意义如下:
------------------------------------------------------------------------------------------
   属性                    类型                                   意义
   index                   number                      现在指到成员的索引
   count                   number                      总共指到成员的总和
   first                     boolean                     现在指到成员是否为第一个
   last                     boolean                     现在指到成员是否为最后一个
-------------------------------------------------------------------------------------------
如下例子:
<%@page contentType="text/html;charset=gb2312"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
 String atts[] = new String[5];
 atts[0]="hello";
 atts[1]="this";
 atts[2]="is";
 atts[3]="a";
 atts[4]="girl";
 request.setAttritue("atts",atts);
%>
<c:forEach items="${atts}" var="item" varStatus="s">
<h2><c:out value="${item}"/>的四种属性></h2>
 index: ${s.index}</br>
 count: ${s.count}</br>
 first: ${s.first}</br>
 last:  ${s.last}</br>
</c:forEach>

<c:forTokens>
<c:forTokens>:用来浏览一字符串中所有的成员,起成员是由定义符号(delimiters)所分隔的。
语法:
<c:forTokens items="stringFoTokens" delims="delimmmmiters" [var="varName"]
             [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]>
 ...body内容....
</c:forTokens>

Attribute
--------------------------------------------------------------------------------------------------------------------
 名称                                    说明                                               EL     类型      必须       默认值
 var                   用来存放现在指到的成员                                Y      String       否          无
 items                被迭代的字符串                                                Y      String       是          无
 delims              定义用来分割字符串的字符                            N      String       是          无
 varStatus          用来存放现在指到的相关成员信息                N      String       否          无
 begin               开始的位置                                                         Y       int           否           0
 end                 结束的位置                                                          Y       int          否           最后一个成员
 step                每次迭代间隔数                                                  Y       int           否           1
---------------------------------------------------------------------------------------------------------------------
限制:
.假若有begin属性时,begin必须大于等于0
.假若有end属性时,必须大于begin
.假若有step属性时,step必须大于等于1

Null 和 错误处理
.假如itmes为null时,则表示为有空的集合对象
.假若begin大于等于items的大小时,则迭代不运算

例子:
<c:forToken items="A,B,C,D,E,F,G" delims="," var="item>
${item}
</c:forToken>
items属性也可以用EL,例如:
<%
 String phonenumber="123-456-7899";
 request.setAttribute("userPhone",phonenumber);
%>
<c:forTokens items="${userPhone}" delims="-" var="item">
${item}
</c:forTokens>

URL操作
JSTL包含三个URL操作有关的标签,分别是: <c:import>,<c:redirect>和<c:url>。它们的主要功能是:
用来将其他文件的内容包含起来,网页的向导,还有url的产生。

posted @ 2006-07-04 13:47 多力宇扬 阅读(579) | 评论 (0)编辑 收藏

应聘Java笔试时可能出现问题
Java基础方面:
1、作用域public,private,protected,以及不写时的区别
Public、Protected、Private是成员访问修饰符;
final、abstract、transient、synchronized、native、strictfp是非访问成员修饰符。
可见性PublicProtectedDefaultPrivate
同一个类是是是是
同一个包中的类是是是否
同一个包中的子类是是是否
同一包外的子类是是否否
同一包外的非子类是否否否

Java的基本包
java.lang 其中包含有:
接口:Comparable、Cloneable、Runable等
类:八个基本数据类型封装类、Math、Runtime、Object、String、StringBuffer、Thread、Exception等

集合框架
集合是将多个元素组成一个单元的对象。集合用于存储、检索和操纵数据。
集合框架提供管理对象集合的接口和类。它包含几个组件,接口是表示集合的抽象数据类型,用于操纵集合;类是用于存储集合的实际数据对象;算法是用于操纵集合的。

2、ArrayList和Vector的区别,HashMap和Hashtable的区别
答:就ArrayList与Vector主要从二方面来说.
一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半

ArrayList,Vector, LinkedList的存储性能和特性
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

就HashMap与HashTable主要从三方面来说.
一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一实现
二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:只有HashMap允许在一个集合中有一个null键和在一个集合中有多个null值

Hashtable是HashMap的同步版本;HashMap允许有null值和一个null键,但是,Hashtable不允许有任何内容为null

Hashtable类的对象必须覆盖Object类的hashCode()和equals()方法

关于其他集合类型:
一.ArrayList 提供快速遍历和快速访问。现在设计了新的 RandomAccess 接口,它指出这种列表支持快速随机访问。Vector也实现了RandomAccess 接口。
二.遍历HashSet与HashMap时,其顺序是未知的(但添加删除快)。LinkedHashSet和LinkedHashSet是按照元素的插入的顺序遍历的(遍历快)。
三.TreeSet和TreeMap将保证元素按照元素的自然顺序进行排列。也可以使用一个用户自己实现的比较规则。
四、HashSet有一个散列表支持它。它为基本操作提供固定时间性能。TreeSet它确保了排序集将按元素升序,根据自然顺序排序。

Dictionary类
主要用于将关键字转换成值,该类接收一个关键字并返回一个值。Dictionary是一个抽象类,它是H
Hashtable的超类。
Properties类
扩展了Hashtable类,但Properties对象的关键字和值必须是String类型,并能将对象写入一个输出流并保存在一个文件中,然后可以把它读回一个输入流。


如果需要维护和搜索一个部件列表,它们由唯一的字母数字序列号标示,其中的部件是Part类型,这时应该使用哪种集合?如果我们改变需求,你也需要能够按顺序、按它们的序列号打印出部件?
1、应该选择HashMap
2、应该选择TreeMap

3、char型变量中能不能存贮一个中文汉字?为什么?
答:是能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的

4、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify

GC是什么? 为什么要有GC?
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

7、垃圾回收机制,如何优化程序?
当一个对象失去引用或者离开了作用域后,就成为垃圾而被Java运行环境自动清除,清除垃圾就是清除这些对象。
Java垃圾回收机制的特点是:
1、垃圾回收机制自动运行。系统提供一个低优先级的线程来跟踪内存的分配情况。如果发现某个内存单元不再使用,就清除它。
2、何时清除垃圾是不可预期的。
3、垃圾回收机制随JVM的不同而不同。

Java的垃圾搜索器为内存管理器提供一种自动解决方案。缺点是不能完全控制它什么时候执行以及什么时候不执行。
当垃圾搜集器运行时,其目的是查找和删除不能被访问的对象。
垃圾搜集器受JVM控制,JVM决定什么时候运行垃圾搜集器。从Java程序内可以请求JVM运行垃圾搜集器,但是,在任何情况下都无法保证JVM会答应你的请求。JVM通常会在它感到内存减少时运行垃圾搜集器。
垃圾收集器运行时,当它发现一个对象不能被任何活线程访问时,它将认为该对象符合删除条件,它可能在某时删除该对象。
垃圾收集器不能保证有足够的内存,它只能保证可以使用的内存将尽可能被有效的管理。
使对象符合垃圾搜集器搜索条件的情况有:出现空引用、重新为引用变量赋值、隔离引用。

强制执行垃圾搜集:
Runtime对象为直接与虚拟机通信提供一种机制。System类可以调用与其相同的方法。
请求垃圾收集器的最简单的方法是:System.gc();

Javac编译选项?
G产生调试信息
g:none不产生调试信息
verbose输出编译器消息,可以知道程序编译时用到了哪些Java类
Noware编译时不产生警告信息
encoding指出原文件的编码方式
D指定类文件产生的目录
classPath指出用户class文件的路径
sourcePath指出用户源文件路径

9、介绍JAVA中的Collection FrameWork(包括如何写自己的数据结构)?
答:Collection FrameWork如下:
核心接口有:
CollectionSetSorted Set
ListMapSorted Map

Set接口:不允许重复的元素。它对add、equals、hashCode方法增加了限制
SortedSet接口:扩展了Set接口,此接口的元素按升序排序。
List接口:一些集合具有顺序,即在一个项目后添加另一个项目。列表可以有重复元素。提供了ListIterator,允许向前或向后移动元素。
Map接口:将键映射到值得对象。Map不能包含重复键,但可以包含重复值。每个键最多都只能映射到一个值。

核心设计类:
Map 设计Set 设计List 设计
HashMapHashSetArrayList
HashtableLinkedHashSetVector
TreeMapTreeSetLinkedLisk
LinkedHasMap

散列表是最快的数据存储结构,它是一个数组。数据存储在数组中散列函数指定的特定下标。散列函数是一组输入数据和一组整数之间的映射。

集合类和接口层次

Collections是一个类,带有用于处理集合的静态实用方法
Collection是一个接口,带有多数集合常用的方法声明,包括add、remove、contains、size、iterator

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)
Map提供key到value的映射

集合框架的优点:
提供一组可用的集合接口,可以方便地扩展或改写集合;
接口和算法的可重用性提高了软件的可重用性;
提供了有效的数据结构和算法,减少了编程工作。

10、Java中异常处理机制,事件机制?
事件代表了组件之间的交互。是一种在源对象和监听对象之间,某种状态发生变化的传递机制。
通过事件处理机制,可以让一些组件作为事件源,发出可被组件环境或其它组件接收的事件。这样,不同的组件就可以组合在一起,组件之间通过事件传递进行通信,构成一个应用。
在java中实现事件机制的事件模型由三个部分构成:一个事件对象用于描述事件源的状态变化;一个事件源将会产生事件,提供注册的事件监听器的方法,把事件发送到监听器;事件监听器接收事件通知,实现该事件的监听器接口。

异常实际上是程序中错误导致中断了正常的指令流的一种事件.
Java异常处理用于在方法中能检查出错误但不能处理错误的情况,在这样的方法中将抛出一个异常。如果一个异常与某个catch程序块中的参数匹配,那么就执行该catch块中的代码。指出try catch finally的工作顺序。

运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

事件有哪些?

什么是断言机制?
断言从JDK1.4版开始引入,它让开发期间测试假设,而没有付出为异常编写异常处理程序方面的代价,一旦程序完成开发,并全部部署,假设将从不会发生。
主要作用:因为在开发时对自己的假设非常肯定,所以不想花费时间来编写异常处理代码。断言让在开发期间测试你的假设。
private void method(int num){
assert(num>=0);//这里假定参数num是正数,如果不是真的将抛出一个AssertionError错误
useNum(num+x);
}
断言有两种形式:简单和非常简单。
非常简单:
private void doStuff(){
assert(y>x);
//其他代码
}
简单:
将通过表达式的值向错误跟踪栈中添加更多信息,提供了更多调式帮助信息。
private void doStuff(){
assert(y>x):”y is ”+y+” x is”+x;
//其他代码
}
运行时启用断言:
java –ea com.geeksanonymous.TestClass

运行时禁用断言:
java –da com.geeksanonymous.TestClass

11、JAVA中的多形与继承?
希望大家补上,谢谢

对象是定义了边界的、与要解决的问题有关的概念或事物。它们用于帮助理解现实世界。
类是拥有相同特性、共同的行为和共同的关系的一组对象。
封装是让开发者有选择地隐藏类中的特性和方法的过程
继承是允许通过重用现有类来构建新类的特性。]
多态性使用同一函数在不同的类上具有不同的行为。Java中的多态性是通过方法的动态绑定实现的。

12、抽象类与接口?
答:抽象类与接口都用于抽象,但是抽象类(JAVA中)可以有自己的部分实现,而接口则完全是一个标识(同时有多重继承的功能)。

abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 都不能

接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类必须有明确的构造函数。

Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
可以继承其他类或完成其他接口,在swing编程中常用此方式。

IO流
字节流:数据在存储时与传输时都是以字节为单位进行的。通常用于读写二进制数据,如图像和声音文件。
字符流:数据在存储与传输时都是以字符为单位进行的。

流:对数据源的一种抽象,其目的是想用统一的方式访问各种不同的数据源(文件、网络、内存的缓冲区)

文件读写的基本类:File类提供定位本地文件系统,描述文件和目录的功能。

管道流用于在线程之间通信:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
线程1àPipedOutputStreamàPipedInputStreamà线程2

键盘输入:
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s=br.readLine();
System.out.println(s);
}catch(Exception e){
}

文件输入输出:
try{
File f=new File("test.txt");
FileOutputStream fout=new FileOutputStream(f);
fout.write(System.in.read());
fout.close();
FileInputStream fin=new FileInputStream(f);
int size=fin.available();
for(int i=0;i<size;i++){
System.out.print((char)fin.read());
}
fin.close();
}catch(Exception e){
}

通过网络传输文件:
客户端:
File f=new File("bk.exe");
FileInputStream fin=new FileInputStream(f);
Socket st=new Socket("localhost",6000);
BufferedOutputStream bout=new BufferedOutputStream(st.getOutputStream());
int size=fin.available();
for(int i=0;i<size;i++){
bout.write(fin.read());
}
服务器端:
ServerSocket server=new ServerSocket(6000);
Socket st=server.accept();
File f=new File("kk.exe");
BufferedInputStream bin=new BufferedInputStream(st.getInputStream());
FileOutputStream fout=new FileOutputStream(f);
int i=0;
while(i!=-1){
i=bin.read();
fout.write(i);
}

串行化的注意事项以及如何实现串行化
对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化(Serialization)。
序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机。
一:对象序列化可以实现分布式对象。
二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。
// 序列化 today's date 到一个文件中.
   FileOutputStream f = new FileOutputStream("tmp");
   ObjectOutputStream s = new ObjectOutputStream(f);
   s.writeObject("Today");
   s.writeObject(new Date());
   s.flush();
//从文件中反序列化 string 对象和 date 对象
   FileInputStream in = new FileInputStream("tmp");
   ObjectInputStream s = new ObjectInputStream(in);
   String today = (String)s.readObject();
   Date date = (Date)s.readObject();
记住,对象流不序列化static或transient。
序列化通常可以自动完成,但有时可能要对这个过程进行控制。java可以将类声明为serializable,但仍可手工控制声明为static或transient的数据成员。
如果一个类要完全负责自己的序列化,则实现Externalizable接口而不是Serializable接口。Externalizable接口定义包括两个方法writeExternal()与readExternal()。利用这些方法可以控制对象数据成员如何写入字节流

NIO的特征
l旧的I/O是以字节为单位进行读写的,而新的I/O是以块为单位进行读写的
l以新的Channel抽象类来配合节点类
l使用Buffer的概念来进行基本数据类型的存取
l增加更多字节编码的支持
l内存映像及数据锁定的支持
l提供非阻塞的存取机制
l提供正则表达式式的验证机制


import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.*;
import java.net.*;
import java.util.*;

class NBTest {
NBTest(){}
public void startServer() throws Exception{
int channels = 0;
int nKeys = 0;
int currentSelector = 0;
Selector selector = Selector.open();

//建立Channel 并绑定到9000端口
ServerSocketChannel ssc = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(),9000);
ssc.socket().bind(address);

//使设定non-blocking的方式。
ssc.configureBlocking(false);

//向Selector注册Channel及我们有兴趣的事件
SelectionKey s = ssc.register(selector, SelectionKey.OP_ACCEPT);
printKeyInfo(s);

while(true) //不断的轮询
{
debug("NBTest: Starting select");
//Selector通过select方法通知我们我们感兴趣的事件发生了。
nKeys = selector.select();
//如果有我们注册的事情发生了,它的传回值就会大于0
if(nKeys > 0){
debug("NBTest: Number of keys after select operation: " +nKeys);
//Selector传回一组SelectionKeys
//我们从这些key中的channel()方法中取得我们刚刚注册的channel。
Set selectedKeys = selector.selectedKeys();
Iterator i = selectedKeys.iterator();
while(i.hasNext()){
s = (SelectionKey) i.next();
printKeyInfo(s);
debug("NBTest: Nr Keys in selector: " +selector.keys().size());

//一个key被处理完成后,就都被从就绪关键字(ready keys)列表中除去
i.remove();
if(s.isAcceptable()){
// 从channel()中取得我们刚刚注册的channel。
Socket socket = ((ServerSocketChannel)s.channel()).accept().socket();
SocketChannel sc = socket.getChannel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE);
System.out.println(++channels);
}else{
debug("NBTest: Channel not acceptable");
}
}
}else{
debug("NBTest: Select finished without any keys.");
}
}
}

private static void debug(String s){
System.out.println(s);
}

private static void printKeyInfo(SelectionKey sk)
{
String s = new String();
s = "Att: " + (sk.attachment() == null ? "no" : "yes");
s += ", Read: " + sk.isReadable();
s += ", Acpt: " + sk.isAcceptable();
s += ", Cnct: " + sk.isConnectable();
s += ", Wrt: " + sk.isWritable();
s += ", Valid: " + sk.isValid();
s += ", Ops: " + sk.interestOps();
debug(s);
}

public static void main (String args[])
{
NBTest nbTest = new NBTest();
try{
nbTest.startServer();
}catch(Exception e){
e.printStackTrace();
}
}
}

Socket通信(TCP、UDP区别及Java实现方式)
套接字是一种进程间的数据交换机制。客户端和服务器通过套接字建立连接和进行通信。套接字是由IP地址、传输协议和一个端口号三部分组成的。
TCP/IP协议:其中TCP 为传输控制协议是传输层协议,
功能TCPUDP
数据传输连续的有序数据流消息传输
多路功能接收主机根据端口号决定数据流向那个应用相同
可靠传输使用TCP头部的序列与确认字段进行数据确认无
流量控制使用窗口机制的流量控制无
连接使用3次握手建立连接;连接后一直保持连接直到终止连接无连接

URL的组件:协议、IP地址或主机名、端口号和实际文件路径

import java.net.*;
import java.io.*;

public class DatagramServer{
public static DatagramSocket ds;
public static int clientport=1089,serverport=1090;
public static void main(String args[]) throws Exception{
byte buffer[]=new byte[1024];
ds=new DatagramSocket(serverport);
BufferedReader dis=new BufferedReader(new InputStreamReader(System.in));
System.out.println("服务器正等待输入");
InetAddress ia=InetAddress.getByName("localhost");
while(true){
String str=dis.readLine();
if(str==null||str.equals("end")){
break;
}
buffer=str.getBytes();
ds.send(new DatagramPacket(buffer,str.length(),ia,clientport));
}
}
}

import java.net.*;
import java.io.*;

public class DatagramClient{
public static DatagramSocket ds;
public static byte buffer[]=new byte[1024];
public static int clientport=1089,serverport=1090;
public static void main(String args[]) throws Exception{
ds=new DatagramSocket(clientport);
System.out.println("客户端正在等待服务器发送数据");
while(true){
DatagramPacket p=new DatagramPacket(buffer,buffer.length);
ds.receive(p);
String psx=new String(p.getData(),0,p.getLength());
System.out.println(psx);
}
}
}

13、Java 的通信编程,编程题(或问答),用JAVA SOCKET编程,读服务器几个字符,再写入本地显示?
答:Server端程序:
package test;
import java.net.*;
import java.io.*;

public class Server {
private ServerSocket ss;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Server() {
try {
ss=new ServerSocket(10000);
while(true) {
socket = ss.accept();
String RemoteIP = socket.getInetAddress().getHostAddress();
String RemotePort = ":"+socket.getLocalPort();
System.out.println("A client come in!IP:"+RemoteIP+RemotePort);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = in.readLine();
System.out.println("Cleint send is :" + line);
out = new PrintWriter(socket.getOutputStream(),true);
out.println("Your Message Received!");
out.close();
in.close();
socket.close();
}
}catch (IOException e) {
out.println("wrong");
}
}
public static void main(String[] args) {
new Server();
}
};

Client端程序:
package test;
import java.io.*;
import java.net.*;

public class Client {
Socket socket;
BufferedReader in;
PrintWriter out;
public Client() {
try {
System.out.println("Try to Connect to 127.0.0.1:10000");
socket = new Socket("127.0.0.1",10000);
System.out.println("The Server Connected!");
System.out.println("Please enter some Character:");
BufferedReader line = new BufferedReader(new

InputStreamReader(System.in));
out = new PrintWriter(socket.getOutputStream(),true);
out.println(line.readLine());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(in.readLine());
out.close();
in.close();
socket.close();
}catch(IOException e) {
out.println("Wrong");
}
}
public static void main(String[] args) {
new Client();
}
};

常见排序法:
public class Sort{
public static int count=0;
public boolean LT(int num1,int num2){
return num1<num2;
}
public void output(int[] array){
System.out.print("第"+count+"次排序:");
for(int i=0;i<array.length;i++)
System.out.print(array[i]+"    ");
System.out.println();
}

//冒泡排序法
public void BubbleSort(int[] array){
boolean swap=true;
int index=0;

int i=0;
while(i<array.length-1){
int temp=array[i];
for(int j=i;j<array.length;j++){
if(!LT(array[i],array[j])){
int temp2=array[i];
array[i]=array[j];
array[j]=temp2;
swap=true;
index=j;
}else{
swap=false;
}
}
i++;
if(swap){
array[i]=array[index];
array[index]=temp;
i++;
}
output(array);
}
}

//直接插入排序法
public void InsertSort(int[] array){
for(int i=1;i<array.length;++i){
if (LT(array[i],array[i-1])){
int temp=array[i];
array[i]=array[i-1];
array[i-1]=temp;
for(int j=i-1;j>0;--j){
if(LT(array[j],array[j-1])){
array[j]=array[j-1];
array[j-1]=temp;
}else{
break;
}
}
output(array);
}
}
}

//快速排序法
private int Partition(int array[],int low,int high){
int temp=array[low];
int pivotkey=array[low];
while(low<high){
while(low<high&&array[high]>pivotkey)--high;
array[low]=array[high];
while(low<high&&array[low]<=pivotkey)++low;
array[high]=array[low];
}
array[low]=temp;
output(array);
return low;
}

public void QSort(int array[],int low,int high){
if(low<high){
int pivotloc=Partition(array,low,high);
QSort(array,low,pivotloc-1);
QSort(array,pivotloc+1,high);
}
}

void QuickSort(int array[]){
QSort(array,0,array.length-1);
}
public static void main(String args[]){
int array[]={49,38,65,97,76,13,27,49};
Sort sort=new Sort();

System.out.println("===================================");
sort.output(array);
System.out.println("优化冒泡排序法");
sort.BubbleSort(array);

System.out.println();
System.out.println("===================================");
array=new int[]{49,38,65,97,76,13,27,49};
sort.output(array);
System.out.println("直接插入排序法");
sort.InsertSort(array);

System.out.println();
System.out.println("===================================");
array=new int[]{49,38,65,97,76,13,27,49};
sort.output(array);
System.out.println("快速排序法");
sort.QuickSort(array);
}
}

14、如在COLLECTION框架中,实现比较要实现什么样的接口?
Collection框架中实现比较要实现Comparable 接口和 Comparator 接口

什么是线程?
线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,正因如此,线程被称为轻负荷进程(light-weight process)。一个进程中可以包含多个线程。

  一个线程是一个程序内部的顺序控制流。
  1. 进程:每个进程都有独立的代码和数据空间(进程上下文) ,进程切换的开销大。
  2. 线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
  3. 多进程:在操作系统中,能同时运行多个任务程序。
4. 多线程:在同一应用程序中,有多个顺序流同时执行。

同步和异步有和异同,在什么情况下分别使用他们?
临界资源问题
线程都是独立的,而且异步执行,也就是说每个线程都包含了运行时所需要的数据或方法,而不需要外部的资源或方法,也不必关心其它线程的状态或行为。但是经常有一些同时运行的线程需要共享数据,此时就需考虑其他线程的状态和行为,否则就不能保证程序的运行结果的正确性。
我们需要做的是允许一个线程彻底完成其任务后,再允许下一个线程执行。必须保证一个共享的资源一次只能被一个线程使用。实现此目的的过程称为同步。
同步是用于确保资源一次只能被一个线程使用的过程。
同步对于单线程程序没有任何好处。使用同步比非同步的性能差三到四倍。

线程方法介绍:
构造函数:
Thread()
Thread(Runable target)
Thread(Runable target,String name)
Thread(ThreadGroup group,Runable target)
Thread(ThreadGroup group,Runable target,String name)
Thread(ThreadGroup group,String name)

用于完成一个线程“实际功能”的代码放在run方法中。Run方法可以在Thread的子类中重写,也可以在Runable对象中重写。

一旦线程死去,它就永远不能再重新启动,否则会抛出异常。用start方法启动一个已经启动的线程也会抛出异常。

isAlive、interrupt、Thread.currentThread、suspend、resume、stop

Sleep方法可以使低优先级的线程得到执行的机会,Yield方法只能使同优先级的线程有执行的机会。Join方法能够使调用该方法的线程在此之前执行完毕,在该方法之后,调用join方法的线程不会产生输出了,


Wait与notify使用时,需要注意的事项?
它们只能用于synchronized同步块中;
它们需要配对使用;
Wait一般出现在一个while循环中,while语句使用一个boolean标志控制。

死锁
当被锁定的A对象试图访问另一个被锁定的B对象,B对象同时又要访问已被锁定的A对象。这样导致两个线程都在等待另一个线程释放资源,这样就出现了死锁。

16、JAVA多线程编程。 用JAVA写一个多线程程序,如写四个线程,二个加1,二个对一个变量减一,输出。
希望大家补上,谢谢

17、STRING与STRINGBUFFER的区别。
答:STRING的长度是不可变的,STRINGBUFFER的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法

String s = new String("xyz");创建了几个String Object? 两个

JDBC调用数据库的基本步骤

Weblogic Server中的JDBC配置
1、建立到指定数据库的连接池Connection Pool
2、建立基于该连接池的数据源DataSource
3、访问数据库时通过数据源的JNDI名字查找到该数据源,然后通过数据源获得数据库连接对象。得到该对象后就可以依次生成数据库语句对象和结果集对象,进行相应的数据库操作。

import java.sql.*;
import javax.naming.*;
import javax.sql.*;
import java.util.*;
import javax.rmi.*;

public class DataSourceTest{
private static Context getInitialContext() throws Exception{
String url="t3://localhost:7001";
String user="system";
String password="11111111";
Properties properties=null;

try{
properties=new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL,url);

if(user!=null){
properties.put(Context.SECURITY_PRINCIPAL,user);
properties.put(Context.SECURITY_CREDENTIALS,
password==null?"":password);
}

return new InitialContext(properties);
}catch(Exception e){
throw e;
}
}

public static void main(String args[]){
UserTransaction tx=null;
DataSource ds=null;
Context ctx=null;
Connection myConn=null;

try{
ctx=getInitialContext();

tx=(UserTranscation)ctx.lookup("javax.transcation.UserTranscation");
tx.begin();

ds=(DataSource)ctx.lookup("myTxDataSource");
}catch(Exception e){
e.printStackTrace();
}

Statement myStatement=null;
ResultSet myResultSet=null;

try{
myConn=ds.getConnection();
myStatement=myConn.createStatement();
myResultSet=myStatement.executeQuery(
"select fullname from employee");

while(myResultSet.next()){
System.out.println(myResultSet.getString("fullname"));
}

tx.commit();
}catch(Exception e){
try{
tx.rollback();
}catch(Exception e){
}
}finally{
myStatement.close();
myConn.close();
}
}
}

JavaMail发邮件的步骤:
Properties props=System.getProperties();
props.put(“mail.smtp.host”,”*******”); //设置相关的属性
try{
    //创建一个会话对象
    Session session=Session.getDefaultInstance(props,null);
    //创建一个消息对象
    MimeMessage message=new MimeMessage(session);
    message.setText(“*****”); //发送文本格式的邮件
    message.setSubject(“*****”);
    message.setFrom(“*****”);
    message.addRecipient(Message.RecipientType.To,
                        new InternetAddress(“******”));
   //使用传送类的send方法发送消息
   Transport.send(message);
}catch(MessagingException me){
          me.printStackTrace();}

解析XML文件的几种方式和区别
XML解析器使用的两种基本API是:
文档对象模型DOM,一种基于树结构的API。它定义了一组java接口,用于创建、访问和操纵XML文档的内部结构。它是基于对象。整个XML文档被作为对象体系结构排列进行解析和存储,应用程序可以随机访问这些对象。
DOM主要用于:在结构上修改XML文档时;在内存中与其他应用程序共享文档时。

SAX提供一种用于解析XML文档的事件驱动模型,使用SAX接口的XML处理器并不创建数据结构,而是扫描输入的XML文档,并生成元素开始、元素结束等事件,在发生事件时,解析器会通知应用程序。
SAX优点:在解析大型文档时,不必将整个文件加载到内存中,因此占有的内存比DOM少。在只需要一个信息子集时,SAX忽略不需要的数据,而DOM无法做到这点。
SAX的缺点是:必须按到达顺序处理数据,不能对文档进行随即访问。SAX是只读的,它是设计来读取XML文档而不是写入的。文档只能遍历一次。

使用DOM API查找XML文档中的元素和属性
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
import java.net.URL;

public class BookDetails{
public BookDetails(String filename){
Document doc=null;
try{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
doc=db.parse(new File(filename));

String nm="http://www.123books.com/booktitles";
String local="a";
String ob="http://www.onlinebooks.com";

System.out.println(nm+"名字空间中的元素");
NodeList nl=doc.getElementsByTagNameNS(nm,"*");
for(int i=0;i<nl.getLength();i++){
Node n=nl.item(i);
System.out.println(n.getNodeName());
}

System.out.println("\n 名称为 "+local+" 的元素");
nl=doc.getElementsByTagNameNS("*",local);
for(int i=0;i<nl.getLength();i++){
Node n=nl.item(i);
System.out.println(n.getNodeName());
}

System.out.println("\n名字空间 "+ob+" 中的属性");
nl=doc.getElementsByTagName("*");
for(int i=0;i<nl.getLength();i++){
if(nl.item(i) instanceof Element){
Text t=(Text)nl.item(i).getFirstChild();
Element e=(Element)nl.item(i);
Attr a=e.getAttributeNodeNS(ob,"class");
if(a!=null){
String val=a.getNodeValue();
System.out.println("<"+val+">"+t.getNodeValue()+"</"+val+">");
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}

public static void main(String args[]){
BookDetails nsd=null;
if(args.length>=1){
nsd=new BookDetails(args[0]);
}else{
System.out.println("Books.xml");
}
}
}
使用SAX API解析XML文档
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class SAXParserHandler extends DefaultHanlder{
public void startDocument() throws SAXException{
System.out.println("起始文档");
}

public void endDocument() throws SAXException{
System.out.println("结束文档");
}

//在遇到字符数据时激发
public void characters(char[] ch,int start,int lenght) throws SAXException){
String charString=new String(ch,start,lenght);
System.out.println("字符:"+charString);
}

public void startElement(String namespaceURI,String localName,String qName,
Attributes atts)throws SAXException{
System.out.println("起始元素"+qName);
for(int i=0;i<atts.getLength();i++){
System.out.println("属性值:"+atts.getvalue(i));
}
}

public void endElement(String namespaceURI,String localName,String qName)
throws SAXException{
System.out.println("结束元素"+qName);
}

public static void main(String args[]) throws Exception{
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=factory.newSAXParser();
parser.parse("book.xml",new SAXParserHanlder());
}
}
使用DOM API写XML文档
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

import java.io.*;

public class Student{
public static void main(String args[]){
Document doc;
Element students;
Element stud;
Element fName;
Element sName;
try{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
doc=db.newDocument();

stud=doc.createElement("Student");

fName=doc.createElement("FirstName");;
fName.appendChild(doc.createTextNode("John"));
stud.appendChild(fName);

sName=doc.createElement("Surname");
sName.appendChild(doc.createTextNode("David"));
stud.appendChild(sName);

students=doc.createElement("Students");
students.setAttribute("Department","Mathematics");
students.appendChild(stud);

doc.appendChild(students);

TransformerFactory tf=TransformerFactory.newInstance();
Transformer transformer=tf.newTransformer();
transformer.transform(new DOMSource(doc),new StreamResult(System.out));

}catch(Exception e){
e.printStackTrace();
}
}
}
使用DOM API显示现有XML文档内容

使用DOM API将XML文档数据插入数据库

使用DOM API根据数据库创建XML文档

Java的国际化
国际化是为了将应用程序发布在多个地区(locale)而进行准备的过程。不同地区标识了各个特定的国家在信息表现上所广泛使用的语言、流通货币、字符集、日期格式及其他要素。

支持国际化的应用程序具有以下特点:
1、不用改变代码就可以支持另外的语言。
2、文本元素、消息和图片保存在源代码之外。
3、将于文化背景有关的数据,比如日期和时间、十进制数值以及流通货币,根据用户所用的语言和所在地理位置进行正确格式化。
4、支持非标准字符集。
5、应用程序可以快速适应新的语言区域。

为了使一个应用程序国际化,:
1、必须将用户所见到的硬编码字符(如标签、工具提示和错误信息等)替换成包含在资源包ResourceBundle中的字符。它是一个java属性文件,它将关键字映射为字符值。并且可以使用多个不同语言版本的ResourceBundle,这样将可以对于不同语言提供不同的字符串。
2、使用Locale对象,可以使数据格式化为与地区相关的数据。
3、国际化的应用程序还必须使用统一的字符编码标准字符集。

应用服务器有那些?

Servlet方面
什么是Servlet?
Servlet是J2EE应用框架中部署于Web层的Web组件,运行在支持Servlet的Web服务器或应用服务器上。Servlet为客户端和服务器端的信息处理提供了一种“请求/响应”机制。
客户程序将请求发送到服务器;服务器将请求发送到Servlet;依据客户程序的请求,Servlet动态地构造回答信息并返回给服务器;服务器将回答返回给客户程序。

什么是JSP?
JSP是J2EE应用框架中部署于Web层的Web组件,是对Servlet技术的扩展。它使在静态的页面中加入动态的内容变得非常容易。并且通过使用标签库可以大大节省开发时间;将JavaBean与JSP一起使用可以将数据表示和程序实现分离。

在MVC架构模式中:
使用Servlet作为控制器,而JSP作为数据视图。

CGI与Servlet的区别?
CGI(公共网关接口)是一项标准,使WEB服务器可以与外部应用程序交互。但是该技术存在一些严重的限制:
1、CGI应用程序占用资源很多。当系统要处理来自一个用户的请求时,就会创建一个新的进程来处理该请求,一旦CGI脚本停止执行,系统就必须收回该进程。这种重量级进程的经常启动和停止非常低效。
2、CGI很难链接于请求进程的其他阶段,因为在WEB服务器上它们运行于不同的进程。这就很难处理授权、工作流和日志记录工作。

Java Servlet技术提供了一个基于组件、与平台无关的方法来构建WEB应用程序。Servlet没有标准CGI应用程序所遇到的性能局限。
Servlet比CGI更高效是因为:
Servlet应用中将只创建一个单一个重量级进程,并对每个用户请求使用更轻量级的线程来完成请求处理,并且这些线程是由JVM自动维护。每个客户端请求对应一个线程,每个Servlet类在Servlet容器中只存在一个唯一的对象(实例)。Servlet类首次加载后将常驻内存。

1、说一说Servlet的生命周期?
答:在第一次请求Servlet时将创建Servlet实例,容器调用实例的init方法,如果容器有请求要传送给servlet,它就会调用servlet实例的Service方法。一个请求将作为一个线程。如果服务器要销毁servlet实例就会调用servlet实例的destory方法,否则该实例将会常驻内存。

2、Servlet版本间(忘了问的是哪两个版本了)的不同?
希望大家补上,谢谢

会话根中技术
用户认证:使用用户名和口令进行验证来让客户端访问某些资源。
隐藏表单字段:用于保存一个浏览器在服务器中的相关信息。
URL重写:在URL后面添加附加信息
持久Cookie:在请求和响应头信息中添加和编辑信息

什么是会话对象?
会话对象用于在用户访问一个Web站点的多个页面时共享信息。任何时候用户第一次访问某个网页,系统都将创建一个会话。如果以后用户访问此网页,JSP将检索有关此会话的信息。只要服务器收到此用户的请求,则会话就会持续,如果经过一段时间没有收到此用户的新请求,会话就会终止。

3、JAVA SERVLET API中forward() 与redirect()的区别?
使用重定向:当调用sendRedirect方法时,Web容器就会向浏览器返回响应,指示需要新的URL。因为浏览器发出了完全崭新的请求,所以在重定向之前存储为请求属性的任何对象都会消失。
使用转发:当为一个请求调用转发时,请求就发送给服务器上另一个资源,而无需通知客户机由不同的资源处理请求。这个过程完全在Web容器内部进行,客户机绝不知晓。与重定向不同,转发过程中,对象可以存储在请求中,并发送给下一个资源使用。
因为转发过程完全在服务器上进行,与客户机没用通信,因此转发的性能优于重定向。
但是如果在JSP页面上使用图形的相对路径和其他资源,转发机制就会带来问题。因为浏览器无从得知发生了转发,所以相对路径只是相对初始的Servlet,而不是所转发到的JSP页面。使用JSP自定义标签可以解决这个问题。

如何现实servlet的单线程模式

servlet的配置

4、Servlet的基本架构
public class ServletName extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
}
}

 

Jsp方面
1、jsp有哪些内置对象?作用分别是什么?
JSP的隐式对象
RequestJavax.servlet.ServletRequest它包含了有关浏览器请求的信息.通过该对象可以获得请求中的头信息、Cookie和请求参数。
Enumeration getHeaderNames()String getHeader(name)Cookie[] getCookies()Enumeration GetParameterNames()String getParameter(name)String[] GetParametervalues(name)HttpSession getSession(flag)
responseJavax.servlet.ServletResponse作为JSP页面处理结果返回给用户的响应存储在该对象中。并提供了设置响应内容、响应头以及重定向的方法(如cookies,头信息等)
Void setContentType(type)String getCharacterEncoding()Void addCookie(cookie)Void sendRedirect(url)
outJavax.servlet.jsp.JspWriter用于将内容写入JSP页面实例的输出流中,提供了几个方法使你能用于向浏览器回送输出结果。
pageContextJavax.servlet.jsp.PageContext描述了当前JSP页面的运行环境。可以返回JSP页面的其他隐式对象及其属性的访问,另外,它还实现将控制权从当前页面传输至其他页面的方法。
Void forward(path)PAGE_SCOPEREQUEST_SCOPESESSION_SCOPEAPPLICATION_SCOPEVoid setAtrribute(key,value,scope)Enumeration getAttributeNamesInScope(scope)Object getAttribute(key,scope)Void RemoveAttribute(key,scope)Object findAttribute(name)Int getAttributeScope(name)
sessionjavax.servlet.http.HttpSession会话对象存储有关此会话的信息,也可以将属性赋给一个会话,每个属性都有名称和值。会话对象主要用于存储和检索属性值。
Void setAttribute(name,data)Object getAttribute(name)
applicationjavax.servle.ServletContext存储了运行JSP页面的servlet以及在同一应用程序中的任何Web组件的上下文信息。
pageJava.lang.Object表示当前JSP页面的servlet实例
configjavax.servlet.ServletConfig该对象用于存取servlet实例的初始化参数。
Enumeration getInitParameterNames()String getInitParameter(name)
ExceptionJavax.lang.Throwable在某个页面抛出异常时,将转发至JSP错误页面,提供此对象是为了在JSP中处理错误。
String getMessage()Void printStackTrace(out)<%@ page errorPage=”error.jsp”%><%@ page isErrorPage=”true” %>


2、jsp有哪些动作?作用分别是什么?
答:JSP共有以下6种基本动作
ljsp:include:在页面被请求的时候引入一个文件。
ljsp:useBean:寻找或者实例化一个JavaBean。
ljsp:setProperty:设置JavaBean的属性。
ljsp:getProperty:输出某个JavaBean的属性。
ljsp:forward:把请求转到一个新的页面。
ljsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记

3、JSP中动态INCLUDE与静态INCLUDE的区别?
答:动态INCLUDE用jsp:include动作实现
<jsp:include page="included.jsp" flush="true" />它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数
静态INCLUDE用include伪码实现,定不会检查所含文件的变化,适用于包含静态页面
<%@ include file="included.htm" %>

4、两种跳转方式分别是什么?有什么区别?
答:有两种,分别为:
<jsp:include page="included.jsp" flush="true">
<jsp:forward page= "nextpage.jsp"/>
前者页面不会转向include所指的页面,只是显示该页的结果,主页面还是原来的页面。执行完后还会回来,相当于函数调用。并且可以带参数.后者完全转向新页面,不会再回来。相当于go to 语句。

JSP的常用指令
<%@ include file=”localURL” %>
<%@ page attribute=”value1” %>
属性值缺省值示例
contentTypeMIME类型和字符集“text/hmt”contentType=“text/html;charset=ISO-8859-1“contentType=“text/xml“
Extends类名无Extends=“com.taglib.wdjsp.MyJspPage“
Import 类名或包名无
Session布尔值TrueSession=“true”
isThreadSafe布尔值True
ErrorPage
isErrorPage


<%@ taglib uri=”tagLibraryURL” prefix=”tagPrefix” %>

Jdbc
说出数据连接池的工作机制是什么?


1、可能会让你写一段Jdbc连Oracle的程序,并实现数据查询.
答:程序如下:
package hello.ant;
import java.sql.*;
public class jdbc {
String dbUrl="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
String theUser="admin";
String thePw="manager";
Connection c=null;
Statement conn;
ResultSet rs=null;
public jdbc() {
try{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
c = DriverManager.getConnection(dbUrl,theUser,thePw);
conn=c.createStatement();
}catch(Exception e){
e.printStackTrace();
}
}
public boolean executeUpdate(String sql) {
try {
conn.executeUpdate(sql);
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public ResultSet executeQuery(String sql) {
rs=null;
try {
rs=conn.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
public void close(){
try {
conn.close();
c.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ResultSet rs;
jdbc conn = new jdbc();
rs=conn.executeQuery("select * from test");
try{
while (rs.next()) {
System.out.println(rs.getString("id"));
System.out.println(rs.getString("name"));
}
}catch(Exception e) {
e.printStackTrace();
}
}
}

2、Class.forName的作用?为什么要用?
答:调用该访问返回一个以字符串指定类名的类的对象。

说出在JSP页面里是怎么分页的?
页面需要保存以下参数:
总行数:根据sql语句得到总行数
每页显示行数:设定值
当前页数:请求参数
页面根据当前页数和每页行数计算出当前页第一行行数,定位结果集到此行,对结果集取出每页显示行数的行即可。

4、在ORACLE大数据量下的分页解决方法。一般用截取ID方法,还有是三层嵌套方法。
答:一种分页方法
<%
int i=1;
int numPages=14;

//获取当前页面
String pages = request.getParameter("page") ;
int currentPage = 1;
currentPage=(pages==null)?(1):{Integer.parseInt(pages)};

//获得记录总数
sql = "select count(*) from tables";
ResultSet rs = DBLink.executeQuery(sql) ;
while(rs.next()) i = rs.getInt(1) ;

//获取总页数
int intPageCount=1;
intPageCount=(i%numPages==0)?(i/numPages):(i/numPages+1);

//设置上下页
int nextPage ;
int upPage;
nextPage = currentPage+1;
if (nextPage>=intPageCount) nextPage=intPageCount;
upPage = currentPage-1;
if (upPage<=1) upPage=1;

//获取数据内容并显示
rs.close();
sql="select * from tables";
rs=DBLink.executeQuery(sql);
i=0;
while((i<numPages*(currentPage-1))&&rs.next()){i++;}
%>
//输出内容
//输出翻页连接
合计:<%=currentPage%>/<%=intPageCount%>
<a href="List.jsp?page=1">第一页</a>
<a href="List.jsp?page=<%=upPage%>">上一页</a>

<%
for(int j=1;j<=intPageCount;j++){
if(currentPage!=j){
%>
//显示所有页面的连接
<a href="list.jsp?page=<%=j%>">[<%=j%>]</a>

<%
}else{
out.println(j);
} //end of if
} //end of for
%>

<a href="List.jsp?page=<%=nextPage%>">下一页</a>
<a href="List.jsp?page=<%=intPageCount%>">最后页 </a>


Xml方面
2、你在项目中用到了xml技术的哪些方面?如何实现的?
答:用到了数据存贮,信息配置两方面。在做数据交换平台时,将不能数据源的数据组装成XML文件,然后将XML文件压缩打包加密后通过网络传送给接收者,接收解密与解压缩后再同XML文件中还原相关信息进行处理。在做软件配置时,利用XML可以很方便的进行,软件的各种配置参数都存贮在XML文件中。

3、用jdom解析xml文件时如何解决中文问题?如何解析?
答:看如下代码,用编码方式加以解决
package test;
import java.io.*;
public class DOMTest {
private String inFile = "c:\\people.xml";
private String outFile = "c:\\people.xml";
public static void main(String args[]){
new DOMTest();
}
public DOMTest() {
try {
javax.xml.parsers.DocumentBuilder builder =
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
org.w3c.dom.Document doc = builder.newDocument();
org.w3c.dom.Element root = doc.createElement("老师");
org.w3c.dom.Element wang = doc.createElement("王");
org.w3c.dom.Element liu = doc.createElement("刘");
wang.appendChild(doc.createTextNode("我是王老师"));
root.appendChild(wang);
doc.appendChild(root);
javax.xml.transform.Transformer transformer =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();

transformer.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
transformer.transform(new javax.xml.transform.dom.DOMSource(doc),
new javax.xml.transform.stream.StreamResult(outFile));
} catch (Exception e) {
System.out.println (e.getMessage());
}
}
}

4、编程用JAVA解析XML的方式.
答:用SAX方式解析XML,XML文件如下:
<?xml version="1.0" encoding="gb2312"?>
<person>
<name>王小明</name>
<college>信息学院</college>
<telephone>6258113</telephone>
<notes>男,1955年生,博士,95年调入海南大学</notes>
</person>
事件回调类SAXHandler.java
import java.io.*;
import java.util.Hashtable;
import org.xml.sax.*;
public class SAXHandler extends HandlerBase {
private Hashtable table = new Hashtable();
private String currentElement = null;
private String currentvalue = null;
public void setTable(Hashtable table) {
this.table = table;
}
public Hashtable getTable(){
return table;
}
public void startElement(String tag, AttributeList attrs) throws SAXException {
currentElement = tag;
}
public void characters(char[] ch, int start, int length) throws SAXException {
currentvalue = new String(ch, start, length);
}
public void endElement(String name) throws SAXException {
if (currentElement.equals(name)) table.put(currentElement, currentvalue);
}
}

JSP内容显示源码,SaxXml.jsp:
<HTML>
<HEAD>
<title>剖析XML文件people.xml</title>
</HEAD>
<BODY>
<%@ page errorPage="ErrPage.jsp" contentType="text/html;charset=GB2312" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.Hashtable" %>
<%@ page import="org.w3c.dom.*" %>
<%@ page import="org.xml.sax.*" %>
<%@ page import="javax.xml.parsers.SAXParserFactory" %>
<%@ page import="javax.xml.parsers.SAXParser" %>
<%@ page import="SAXHandler" %>
<%
File file = new File("c:\\people.xml");
FileReader reader = new FileReader(file);
Parser parser;
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
SAXHandler handler = new SAXHandler();
sp.parse(new InputSource(reader), handler);
Hashtable hashTable = handler.getTable();
out.println("<TABLE BORDER=2><CAPTION>教师信息表</CAPTION>");
out.println("<TR><TD>姓名</TD>" + "<TD>" +
(String)hashTable.get(new String("name")) + "</TD></TR>");
out.println("<TR><TD>学院</TD>" + "<TD>" +
(String)hashTable.get(new String("college"))+"</TD></TR>");
out.println("<TR><TD>电话</TD>" + "<TD>" +
(String)hashTable.get(new String("telephone")) + "</TD></TR>");
out.println("<TR><TD>备注</TD>" + "<TD>" +
(String)hashTable.get(new String("notes")) + "</TD></TR>");
out.println("</TABLE>");
%>
</BODY>
</HTML>

EJB方面
1、EJB2.0有哪些内容?分别用在什么场合? EJB2.0和EJB1.1的区别?
答:规范内容包括Bean提供者,应用程序装配者,EJB容器,EJB配置工具,EJB服务提供者,系统管理员。这里面,EJB容器是EJB之所以能够运行的核心。EJB容器管理着EJB的创建,撤消,激活,去活,与数据库的连接等等重要的核心工作。JSP,Servlet,EJB,JNDI,JDBC,JMS.....

2、EJB与JAVA BEAN的区别?
JavaBean是可复用的平台独立的软件组件,开发者可以在软件构造器工具中对其直接进行可视化操作。

Enterprise Java Bean 相当于DCOM,即分布式组件。它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是EJB组件的代理,EJB组件由容器所创建和管理。客户通过容器来访问真正的EJB组件。

3、EJB的基本架构
答:一个EJB包括三个部分:
Remote Interface 接口的代码
package Beans;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Add extends EJBObject {
//some method declare
}

Home Interface 接口的代码
package Beans;
import java.rmi.RemoteException;
import jaax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface AddHome extends EJBHome {
//some method declare
}

EJB类的代码
package Beans;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javx.ejb.SessionContext;
public class AddBean Implements SessionBean {
//some method declare
}

J2EE,MVC方面
1、MVC的各个部分都有那些技术来实现?如何实现?
答:MVC是Model-View-Controller的简写。设计的基本原理是将复杂性分解为三个组件,即模型、视图、控制器。
模型表示数据和处理数据的业务逻辑或应用程序对象。
试图是用户要查看或存取的数据的表示。
控制器定义了用户与模型和试图交互的方式。


2、应用服务器与WEB SERVER的区别?
Web Service 是一种新的分布式技术。一个Web服务本质上是一个应用组件,可以通过Web协议和数据编码机制,例如HTTP和XML,对这个组件进行访问。

Soap简单对象访问协议:
是一种基于XML的通信协议。它包括3个部分。
Soap封装结构:定义消息的XML格式,包括其整体框架、消息内容、由谁处理这些内容等。
Soap编程规则:定义如何将程序数据表示为XML。
Soap RPC表示:定义如何使用scap进行远程过程调用。

WSDL Web服务描述语言:
WSDL文件是一个XML文档,用于说明一组soap消息以及如何交换这些消息。还定义了服务的位置以及使用服务的通信协议等。

Uddi统一描述、发现和集成标准
是wed服务的黄页。它提供了用于服务注册的目录技术,并用它来建立Web服务的目录信息。UDDI的核心组件是UDDI商业注册,它使用一个XML文档来描述企业及所提供的Web服务。它包括3个部分:
白页:介绍提供服务的公司,包括名称、地址和联系方式等;
黄页:包括按照标准分类法进行分类的行业类别;
绿页:详细介绍,访问服务接口等技术信息。

Web服务是构建在soap(简单对象访问协议)、wsdl(web服务描述语言)、uddi(统一描述、发现和集成标准)3个开放的核心标准之上的。Soap用来进行Web服务通信的协议,WSDL用来进行说明和描述Web服务
由于Web服务完全基于XML的,使Web服务成为一个跨语言、跨平台、跨网络的可互操作的分布式应用软件的新平台。
3、J2EE是什么?
J2EE是sun公司推出的一个高层次的全方位、多功能的企业应用开发环境。它包括了当今软件工业界许多最新、最重要的软件技术。J2EE平台包含一整套的服务、应用程序接口和协议,是java技术企业级应用的整体解决方案。J2EE平台通过基于组件的应用程序模型大大简化了开发过程,同时还支持任何分布式体系和多层次的应用开发。随着越来越多的第三方对J2EE的支持和标准认证,J2EE已被广泛用来开发企业级应用软件、中间件和组件软件。
J2EE Java2平台企业版:
1、提供了基于组件的方式来设计、开发、组装和部署企业应用。
2、提供了一个多层次分布式的应用模型,包括了可复用的组件、基于XML数据交换、统一的安全模式以及灵活的事务控制。基于这些技术,可开发出满足市场要求的,基于平台无关的J2EE组件的解决方案。
3、J2EE平台使用的多层分布式应用模型中应用程序主要分为:客户层(Applet)、Web层(Servlet和JSP)、业务层(EJB)、企业信息系统层。


使用类库开发与使用框架包进行开发的区别?
框架包简单的可以认为是一组类和接口,它们相互协作以解决特定类型的软件问题。
类库包含的是应用程序可以调用的函数或例程。而框架包提供通用的、相互协作的组件,应用程序通过扩展这些组件提供特定函数组。应用程序将在这些扩展点进行扩展,运行时这些扩展将被框架系统反调用。这正与使用类库开发的应用程序,运行时的函数调用时颠倒的。

5、BS与CS的联系与区别。
传统的分布式应用程序都是基于Client/Server结构的,而近年来人们发现基于Client/Server结构的应用程序有很多缺点,比如:如果客户端的代码需要改变,那么所有机器上的客户端程序都要重新安装;如果某台机器有了不可修复的损坏,那么得去别的机器上重新安装客户端软件才能够使用。而基于Browser/Server结构的应用程序就没有以上的缺点了,我们可以使用任何一台有浏览器的机器来工作,而因为所有的程序逻辑都在服务器端,所以服务器端的代码变动不需要作为客户端的浏览器再做任何工作。

6、STRUTS的应用(如STRUTS架构)
答:Struts是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。 采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。 Struts有如下的主要功能:
一.包含一个controller servlet,能将用户的请求发送到相应的Action对象。
二.JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。
三.提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。

设计模式方面
1、开发中都用到了那些设计模式?用在什么场合?
答:人们在自己的环境中不断发现问题和寻找问题的解决方案的时候,发现有一些问题及其解决方案不断变换面孔重复出现,但在这些不同的面孔后面有着共同的本质,这些共同的本质就是模式。设计模式就是用来描述解决这些问题的解决方案的核心的。

工厂模式
专门负责将大量有共同接口的类实例化。工厂模式可以动态确定将那一个类实例化,不必事先知道每次要实例化那一个类。

简单工厂模式
或称静态工厂方法模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式就是由一个工厂类根据传入的参数决定创建那一种产品类的实例。
简单工厂模式涉及到工厂角色、抽象产品角色以及具体产品角色:l工厂类角色:含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象。l抽象产品角色:担任这个角色的类是由工厂方法模式所创建的对象的父类,或它们共同拥有的接口。l具体产品角色:工厂方法模式所创建的任何对象都是这个角色的实例。
优点是:允许客户端相对独立于产品创建的过程,并且在系统引入新产品的时候无需修改客户端。缺点是:如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。
工厂方法模式
或称多态性工厂模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。它仅负责给出具体工厂子类必须实现的接口。这样可以用来允许系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式涉及到的角色:l抽象工厂角色:它不包含应用逻辑。任何在模式中创建对象的工厂类必须实现这个接口。l具体工厂角色:含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。l抽象产品角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。l具体产品角色:这个角色实现了抽象产品角色所声明的接口。
单例模式
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
特点:单例类只能有一个实例;单例类必须自己创建自己的惟一的实例;单例类必须给所有其他对象提供这一实例。
多例模式
多例类可以有多个实例,并且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
在系统中可以用于数据库连接池、键值缓存等。
代理模式
给某个对象提供一个代理对象,并由代理对象控制对原对象的引用。
代理模式所涉及的角色:抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以使用代理主题角色。

名称

 

2、UML方面
UML包括的图有:案例图、类图、序列图、合作图、状态图、活动图、构件图、部署图。

类图中的关系有:
一般关系(类于类的继承关系、接口与接口的继承关系、类对接口的实现关系);
关联关系:它使一个类知道另一个类的属性和方法。在java中,使用实例变量实现。
聚合关系:是整体与个体之间的关系。也是使用实例变量实现。
合成关系:是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
依赖关系:总是单向的。表示一个类依赖于另一个类的定义。

3、软件的可维护性与可复用性
一个好的系统设计应该有如下性质:
可扩展性:新的性能可以很容易地加入到系统中。
灵活性:可以允许代码修改平稳地发生、而不会波及到很多其他的模块。
可插入性:可以很容易地将一个类抽出去,同时将另一个有同样接口的类加入进来。

在java中可以给出一个或多个抽象java类或java接口,规定出所有的具体类必须提供的方法特征作为系统设计的抽象层。这个抽象层预见了所有的可能扩展,因此,在任何扩展情况下都不会改变。

接口是实现构件的可插入性的关键。一个java接口是一些方法特征的集合,这些方法一般都是在系统经常出现的方法。一个接口只有方法的特征,没有方法的实现,因此在不同地方的该方法实现,可以具有不同的行为。
接口是对可插入性的保证:
因为在类的关联中,如果一个关联不是针对一个具体类的,而是针对一个接口的,那么任何实现这个接口的类就都可以满足要求。当前对象并不在意所关联的是哪个具体类,而仅仅关心这个类是否实现了某个接口。这样一来,就可以动态地将这个关联从一个具体类转换到另一个具体类,而这样做的唯一条件是它们都实现某个接口。

抽象类仅提供一个类型的部分实现。抽象类通常代表一个抽象概念,它提供一个继承的出发点。
javascript方面
1、如何校验数字型?
var re=/^\d{1,8}$|\.\d{1,2}$/;
var str=document.form1.all(i).value;
var r=str.match(re);
if (r==null) {
sign=-4;
break;
} else{
document.form1.all(i).value=parseFloat(str);
}

CORBA方面
什么是RMI?
Java RMI(Remote Method Invocation)--Java的远程方法调用是Java所特有的分布式计算技术,它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算。面向对象设计要求每个任务由最适合该任务的对象执行,RMI将这个概念更深入了一步,使任务可以在最适合该任务的机器上完成。
RMI定义了一组远程接口,可以用于生成远程对象。客户机可以象调用本地对象的方法一样用相同的语法调用远程对象。RMI API提供的类和方法可以处理所有访问远程方法的基础通信和参数引用要求的串行化。
使用RMI开发步骤:
1、定义一个远程接口(远程接口必须继承接口,每个方法必须抛出远程异常,方法参数和方法返回值都必须是可序列化的)
2、实现远程接口
3、定义使用远程对象的客户程序
4、产生远程访问对象的桩和框
5、注册远程对象
6、运行服务器和客户程序

RMI和CORBA的区别?
远程方法调用(RMI)和CORBA都是分布式计算技术,在进行分布式时各有其优缺点,CORBA和RMI的区别。
  CORBA(Common Object Request Broker Architecture)是OMG的Object Management Architecture(对象管理结构),它是面向对象的分布式系统建立所依据的标准。CORBA被设计成一个能供所有编程语言使用的一个开放性说明,就是说一个机器上的Java客户可以要求另一个用SmallTalk或C++的机器服务。正是由于这种语言的独立性使得CORBA这么灵活和吸引人。为了适应语言独立性,CORBA采用了非常通用的标准作为其接口。在不同的语言中,远程调用、签名和对象的引入有各自不同的定义,所以CORBA必须尽可能的中立和开放。正是这种通用性是CORBA的一个弱点。当开发人员都采用CORBA时,他们要用一种新的标准定义语言接口,它要求开发者学习新的编程接口,从而减小了远程模型的透明性。
  RMI是为仅在Java对Java的分布式计算中而开发的。远程调用的标准是为了Java和应用Java的自然Java签名和调用而开发的,这使得RMI对Java的开发者相当透明而且易于实现。RMI用Java语言紧密集成从而同CORBA相比能够提供非常好的容错能力及对异常的处理。尽管Java的RMI标准不像CORBA那样语言独立,但Java本身是一个独立的平台,这就使RMI在跨平台的分布软件开发中是一个很好的选择。
  RMI是Java语言在分布式计算上的基本模型,很多Java的分布式系统,包括我们本章要涉及的EJB,都是建立在RMI的思想上的。

基于IIOP协议的远程方法调用(RMI-IIOP)
RMI是一个分布对象系统,允许java对象与运行在其他虚拟机上的java对象进行交互。使得可以象访问本地对象一样访问远程对象;只要获得一个远程对象的引用,就可以把这个对象看作如同运行在同一虚拟机上那样来调用它的方法。但RMI是一个仅限于Java的分布式对象系统,这个系统使用了一个java特有的传输协议,即java远程方法协议(JRMP),在客户端和服务器之间进行信息传输。然而,这也意味着使用这种协议只能访问其他java对象,而无法访问非java对象。
远程方法调用的实际处理过程与CORBA的过程相似,即RMI使用客户端桩和服务器端框。要调用远程方法,客户端首先在桩上生成一个请求,然后将此请求传递给服务器,在服务器的框将请求转换成对远程对象的实际方法调用。客户端桩将远程方法的所有参数序列化后传递给服务器框,框将对参数反序列化。
但是由于这种协议不支持EJB需要的企业级交互,因为在这种类型的交互中必须通过远程方法调用来传递事务和安全环境。为此sun公司创建了RMI-IIOP即基于因特网内部对象请求代理协议之上的远程方法调用。IIOP是一个用在CORBA对象请求代理间进行通信的协议,在IIOP之上的RMI同时具有RMI和CORBA技术的特点。

LINUX方面
1、LINUX下线程,GDI类的解释。
答:LINUX实现的就是基于核心轻量级进程的"一对一"线程模型,一个线程实体对应一个核心轻量级进程,而线程之间的管理在核外函数库中实现。
GDI类为图像设备编程接口类库。

posted @ 2006-07-04 08:02 多力宇扬 阅读(1065) | 评论 (0)编辑 收藏

                                                控制器组件 -- ActionServlet

我们知道 Struts 的入口是 ActionServlet. org.apache.struts.ActionServlet 类在 Struts 应用程序中负责拦截工作。所有来自客户层的请求,在交给应用程序处理之前,都会先经过 ActionServlet ActionServlet 的一个实例接受到一个 HttpRequest 对象时,无论这是通过 doGet() 方法还是 doPost() 方法受到的 , 都会调用 process() 方法来处理该请求。 ActionServlet process() 方法如下所示 :

Protected void process(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletExcepion

{

RequestUtils.selectModule(request,getServletContext());

getRequestProcessor(getModuleConfig(request)).process(request,response);

}

尽管 process() 方法看起来并不复杂,但是它调用的方法却很复杂。首先,它会调用 org.apache.struts.util.RequestUtils 类的静态方法 selectModule(), 并把当前的请求和这个 Web 应用程序的 ServletContext 都传入该方法。 selectModule() 方法的工作是将 request.getServletContext() 返回的路径与每个配置应用模块的前缀相匹配,从而选出处理当前请求的应用模块。

: 如果你只用到了一个 Struts 配置文件 , 那么你就只会有一个应用程序,也就是默认的应用程序。为了让默认的应用程序和应用模块能够简单而一致的处理请求,默认应用程序可视为一个应用模块。因此 , 任何请求只要不含应用程序的后缀 (suffix), 都会被传送给默认的应用程序 , 由其处理。

扩展 ActionServlet

尽管 Struts 框架仍然允许你扩展 ActionServlet 类,但是这么做的好处已大不入前,因为它的大部分功能都已经放到新的 RequestProcessor 类里了。如果你仍然想扩展自己的 ActionSerlvet 类,那么只要创建一个扩展了 ActionServlet 的类并配置 Struts 框架让它使用你的类就可以了。看以下一个覆盖了 init() 方法的类。

 

Package dory.doo.framework;

import javax.servlet.ServeltException;

import javax.sertlvet.UnaviableException;

import org.apache.struts.action.ActionServlet;

import dory.doo.strutus.service.IStorefrontService;

import dory.doo.strutus.service.StorefrontServiceImpl;

import dory.doo.strutus.framework.util.IConstants;

import dory.doo.strutus.framework.exceptions.DatastoreException;

/**

* 扩展了 Struts ActionServlet, 以此来完成你自己特殊的初始化工作

*/

public class ExtendedActionServlet extends ActionServlet

 {

   public void init() throws ServletException

{

  // 确定你先调用了超类

  super.init();

  // 初始化持久存储服务

  try

   {

     // 创建服务接口的一个实例

     IStorefrontService serviceImpl=new StorefrontServiceImpl();

     // 把服务对象存储到应用作用域类

     getServletContext().setAttribute(IConstants.SERVICE_INTERPACE_KEY,serviceImpl);

   }

  catch(DatastoreException ex)

   {

     // 如果服务对象的初始化工作出了问题,就关闭 web 应用程序

     ex.printStackTrace();

     throw new UnavailableException(ex.getMessage());

   }

    }

 }

覆盖 init() 方法只是一个例子 , 你可以覆盖任何你想覆盖的方法 , 如果真的需要覆盖 init() 方法 , 请确定你先调用了 super.init() 方法 , 这样才会完成默认的初始化工作。

要使用自己的 ActionServlet 子类,那么必须将 web.xml 修改如下 :

 <servlet>

   <servlet-name>MyActionServlet</servlt-name>

   <servlet-class>dory.doo.framework. ExtendedActionServlet</servlet-class>

 </servlet>

Struts 初始化过程

web.xml 文件中配置的初始化参数而定, servlet 容器首次启动时 , 或者第一个对比 servlet 的请求来到时 ,servlet 容器就会加载 Stuts ActionServlet. 无论是哪种情况 ( 也不管是什么样的 Java Servlet) ,都一定要保证 inint() 得到调用,而且必须在 servlet 处理任何请求之前完成。 Struts 框架在 init() 被调用时 , 会做好所有的初始化工作。看看如下就知道了它到底干了些什么 :

1.       Struts 框架内部的消息资源包进行初始化。这些消息资源包是用来向日志文件传输信息性,警示和错误消息的 . org.apache.struts.action.ActionResources 资源包 ( /org/acache/struts/action/ActionResources.properties 文件 ) 则用来取得这些内部消息。

2.       web.xml 文件加载控制 ActionServlet 类各项行为的初始化参数。这些参数包括 config,debug,detail 以及 convertNull

3.       web.xml 文件加载 servlet 名和 servlet 映射信息,并进行初始化。这些值可供整个 Struts 框架使用 ( 几乎都是给 JSP 标记库使用 ), 以便在 HTML 表单提交时,输出正确的 URL 目标。在此初始化期间, Struts 框架给所有使用 DTD 也会得到注册。 DTD 接下来可以用于严正配置文件。

4.       加载默认应用程序的 Struts 配置数据,并进行初始化,这些配置数据由 config 初始化参数来指定。默认的 Struts 配置文件得到解析后,会创建一个 ApplicationConfig 对象,并存储在 ServletContext 对象中。默认应用程序的 ApplicationConfig 对象会以 org.apache.struts.action.APPLICATION 这个键值存储在 ServeltContext 对象中。

5.       Struts 配置文件中为默认应用程序指定的每个消息资源都会被加载,初始化,并存储在 ServletContext 对象中适当位置 ( 依每个 message-resources 元素中指定的 key 属性而定 ) 。如果没有指定 key 属性,那么相应的消息资源会键值 org.apache.struts.action.MESSAGE 来存储。只有一个消息资源可作为默认消息资源存储,因为每个键都必须是唯一的。

6.       Struts 配置文件中所声明的每个数据源都被会被加载并初始化。如果没有指定任何 data-sources 元素,则会跳过这个步骤。

7.       Struts 配置文件中所指定的每个 plug-in( 插件 ) 元素都会被加载和初始化。对于每个 plug-in 元素所指定的类,其 itit() 方法都将被调用。

8.       一旦默认应用程序正确地完成了初始化之后, servlet init() 方法会确定是否指定了任何其他的应用模块,如果有的话,对于每个应用模块都要重复步骤 4-7

: 为了达到更好的性能,你可能会尝试为一个应用程序建立多个 Struts 控制器 servlet 。这么做几乎得不到更好的性能或扩展性, Struts 设计者也不认为这是一个好注意。 Servlet 是多线程的,因此可以让多个客户同时执行。一个 servlet 就能同时为多个客户提供服务。

 

posted @ 2006-06-30 10:14 多力宇扬 阅读(960) | 评论 (0)编辑 收藏

在web应用中实施过滤是我们常用的技术,通过过滤,可以对请求进行统一编码,对请求进行认证等.每个Fillter可能只担任很少的任务,多个Filter可以互相协作,通过这种协作,可以完成一个复杂的功能.

Fileter
声明: public interface Filter
它是Filter必须实现的接口,它包含一下的方法
. init(FilterConfig config): 这个方法初始化Filter.
. doFilter(ServletRequest request,ServletResponse,FilterChain chain): Filter的业务方法就在这里实现.
. destory(): 释放Filter占用的资源.

FilterChain
声明: public interface FilterChain
它是代码的过滤链,通过这个接口把过滤的任务在不同的Filter之间转移.它包含一个方法:
doFilter(ServletRequest,request,ServletResponse response)
通过这个方法来调用下一下Filter,如果没有吓一个Filter,那么将调用目标资源.

FilterConfig
声明: public interface FilterConfig
代表了Filter的配置,和Servlet一样,Servlet也有一些配置信息,比如名字和初始化参数等.
它包含以下的方法.
.getFilterName(): 返回Filter的名字.
.getInitParameter(String name): 获得名称为name的初始化参数
.getServletContext(): 返回这个Filter所在Servlet上下文对象.
.getInitParameterNames(): 获得Filter配置中的所有初始化参数的名字.

过滤器主要对客户端的请求和客户端的响应进行统一处理.最常见的web过滤器有权限认证过滤器,字符编码过滤器,图象处理过滤器等.

字符编码过滤器(EncodingFillter.java)
package dorydoo.util;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.FilterConfig;
/**
 *
 * @author Dory Doo
 */
public class EncodingFillter implements Filter
{
    protected FilterConfig filterConfig;
    private String targetEncoding="gb2312";
    /**
     *初始化过滤器像一般的Servlet一样,它也可以获得初始化参数
    */
    public void init(FilterConfig config)throws ServletException
    {
        this.filterConfig=config;
        this.targetEncoding=config.getInitParameter("encoding");
    }
    /**
     *进行过滤处理,最最要的地方就是这里了
    */
    public void doFilter(ServletRequest srequest,ServletResponse sresponse,FilterChain chain)
    throws IOException,ServletException
    {
        System.out.println("使用以下方法进行编码:encoding="+targetEncoding);
       
        HttpServletRequest request=(HttpServletRequest)srequest;
        request.setCharacterEncoding(targetEncoding);
        //把处理权发送到下一个
        chain.doFilter(srequest,sresponse);
    }
   
    public void setFilterConfig(final FilterConfig filterConfig)
    {
        this.filterConfig=filterConfig;
    }
    //销毁过滤器
    public void destroy()
    {
        this.filterConfig=null;
    }
}
然后在web.xml中配置我们的应用.
 <web-app>
      .................
        <!--Filter Config-->
       <filter>
            <filter-name>cncoding</filter-name>
            <filter-class>dorydoo.util.EncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>gb2312</param-value>
            </init-param>
        </filter>  
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <servlet-name>action</servlet-name>
        </filter-mapping> 
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
      ........
 </web-app>


在来看一用户认证的过滤器(SignonFilter)
package dorydoo.util;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpSession;
/**
 *
 * @author DuYang
 */
public class SignonFilter implements Filter
{
    protected FilterConfig filterConfig;
    String LOGIN_PAGE="login.jsp";
    /**
     *初始化过滤器像一般的Servlet一样,它也可以获得初始化参数
    */
    public void init(FilterConfig config)throws ServletException
    {
        this.filterConfig=config;
    }
    /**
     *进行过滤处理,最最要的地方就是这里了
    */
    public void doFilter(final ServletRequest req,final ServletResponse res,FilterChain chain)
    throws IOException,ServletException
    {    
        HttpServletRequest hreq=(HttpServletRequest)req;
        HttpServletResponse hres=(HttpServletResponse)res;
        HttpSession session=hreq.getSession();
        String isLogin="";
        try
        {
            isLogin=(String)session.getAttribute("isLogin");
            if(isLogin.equals("true"))
            {
                System.out.println("在SignonFilter中验证通过");
                //验证通过继续处理
                chain.doFilter(req,res);
            }
            else
            {
                //验证不成功重新登录
                hres.sendRedirect(LOGIN_PAGE);
                System.out.println("被SignonFilter拦截一个为认证的请求");
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
   
    public void setFilterConfig(final FilterConfig filterConfig)
    {
        this.filterConfig=filterConfig;
    }
    //销毁过滤器
    public void destroy()
    {
        this.filterConfig=null;
    }
}
在SignonFilter的doFilter()方法中,首先通过isLogin=(String)session.getAttribute("isLogin");判断是否登录用户,如果不是则返回到login页面.配置web.xml文件就和上面的基本上没什么差别.

posted @ 2006-06-29 11:23 多力宇扬 阅读(293) | 评论 (0)编辑 收藏