??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV综合色区无码一区,亚洲精品中文字幕无乱码,久久久久亚洲AV片无码下载蜜桃http://www.tkk7.com/xpsir/articles/325188.htmlPPSun, 04 Jul 2010 04:12:00 GMThttp://www.tkk7.com/xpsir/articles/325188.htmlhttp://www.tkk7.com/xpsir/comments/325188.htmlhttp://www.tkk7.com/xpsir/articles/325188.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/325188.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/325188.html

P 2010-07-04 12:12 发表评论
]]>
目理pȝ模块http://www.tkk7.com/xpsir/articles/271247.htmlPPMon, 18 May 2009 02:16:00 GMThttp://www.tkk7.com/xpsir/articles/271247.htmlhttp://www.tkk7.com/xpsir/comments/271247.htmlhttp://www.tkk7.com/xpsir/articles/271247.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/271247.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/271247.html

信息交流

  • 信息交流用来发布各种信息文gQ企业可以根据自q实际需要自行进行栏目的分讄?/li>
  • 可设定各栏目相关的发布、管理权限,实现内部新闻、公告、规章制度等公用信息的统一上传理?/li>
  • 可以Ҏ实际情况定义信息栏目名称Q如新闻、公告、规章制度、通报...Q,pȝ支持多层ơ目录结构,同时支持按目录授权访问?/li>
  • 文的授权可以按人员、部门、职务、分l、角艌Ӏ项目组{多U方式指定,更方便企业管理?/li>
  • 内部消息Q与内部成员的沟通交、文件传递,也用于系l的事务消息发送,如工作跟t督办?/li>
  • 常用链接Q可以将单位l常使用的各cȝ关站点进行设|?/li>
  • 企业论坛Q可以随时发表相关的意见或针Ҏ一问题q行讨论?/li>

Shenzhen Hiblue Software

事g日程

  • 事g日程以成员、部门、或团队为单位,按时间顺序,相关的工作d、工作计划、待办事务、流E事务以图表方式昄出来?/li>
  • 成员通过事g日程可明自q工作目标Q经理也可以使用事g日程工具对员工的工作做出合理l筹的安排?/li>
  • 此外Q事件日E功能也支持创徏日程安排Q如创徏U会、会议计划或其他日程计划?/li>
  • 可根据时间、日、周、月查询日程信息Qƈ在日E中d备忘?/li>
  • 事g日程q具有冲H检查功能,以及到期提醒功能?/li>

hiQblue.co?/span>

目理

  • 目理理目的整个生命周期,包括目的启动、计划、执行、控制和l束?/li>
  • 企业可以Ҏ实际情况实现合理的项目运作,寚w目的d、成员、胦务、资源进行恰当的分配和管理,pȝ可自动启动相关的工作?/li>
  • 通过目理Q项目经理可以掌控所有的目信息Q计划,资金Q物质,人员Q进E)Q跟t整个项目的生命周期Q全E监控项目的q展Q管理与目相关的活动,q从矩阵视图观察l织的效能?/li>
  • 目理pȝ适用于:市场工程、Y件工E、开发过E、项目实施、以及各U特定的目工程?/li>
  • 目理可针Ҏ个组l机构、部门或具体的工E项目进行管理。项目的发布人员可以使用本功能制订整个机构的目工作计划Q同时将q些计划分配到具 体的执行人员Q?掌握目的执行情况及其相关的工作q度、项目文、工作Q务、项目进度信息,q行目l计、Q务统计、工时统计等分析查看?/li>
  • 机构成员Ҏ参于的项目工作,可以定期上传相应的工作报告ƈ可上传多个相应的附g?/li>
  • 目理制定工作程是:首先讄、徏立相应的目cd和Q务类别,目cd建立时将指定相应的工作流E?/li>
  • 可制订相应的目q可针对需要进行指定相应的负责人及执行人,Ҏ目cd的选定Q就会拥有项目类别事先定义好的工作流E。根据工作流E可一步一步实施执行到l束?/li>
  • 目理模块里还提供了对目文的管理、知识共享、工作交办等功能?/li>

H i b l u e S o f t w a r e

工作d

  • 工作d是企业日常工作Q务或目的工作计划Q务,pȝ通过工作d程Q实现工作流E自动化?/li>
  • 工作d可设定分cR优先、重要性、紧急程度等属性,可按目、部门、成员等对象q行d分配?/li>
  • 通过工作程的自动化Q实现更好、更快的q行d的过E?/li>
  • 工作d的计划安排:计划安排实现Ҏ常工作计划的安排、下达、负责h员的指定Q同时支持进行计划的再分解操作。实现工作由上到下,由d分的l一安排理?/li>
  • 工作d的跟t检查:pȝ对已l安排的工作d自动跟踪查,对于提交完成的工作申误行核准,从而实现对于工作Q务时间进度、工时进度、Q务进度的多种跟踪查?/li>
  • 工作d的报告日志:pȝ提供的报告日志可以工作d负责人方便的q行相关报告的提交,为将来的工作考评提供了准、翔实的数据?/li>
  • 工作d的费用管理:通过与费用报销模块的连接,方便理者对于相兛_作Q务的费用投入情况q行直接理?/li>
  • 工作d的查询功能:可以使管理者对于Q务进展情况进行直接、准的监控理?/li>

???????开 ?????/span>

审批程

  • 审批程是Ҏ审批的规则集Q利用信息技术以及现代化的管理手D,实现一个审ҎE的自动化,在这个过E中文档、信息在参与者之间传递?/li>
  • 程审批用于企业用户之间q行的各U办公申诗公文流转、合同会{、立审扏V事务审批的q程自动化处理,通常由发赯(如文件v草hQ发hE,l过本部门以及其他部门的处理Q如{v、会{)Q最l到达流E的l点Q如发出文g、归、批准)?/li>
  • 企业可以Ҏ单位的实际情况定义审ҎE,从简单流E(如请假申P到复杂流E(如立审批)均可以PMSpȝ中定义和实施?/li>
  • PMSpȝ的审ҎE具备三U应用流E模式:自定义流E、预定义程、固定流E,满企业的不同流E处理的需要?/li>
  • PMSpȝ的审ҎE可以用用程模板制定Q可方便扚w地快速布|和实施工作程?/li>
  • PMSpȝ的审ҎE支持多U方式指定对象,可用绝对对象和相对对象Q在定义和实施中h非常方便高效的意义?/li>
  • PMSpȝ的审ҎE支持会{֊能,支持多节点和多线E,在流E中支持使用子程序?/li>

S h e n z h e n H i b l u e

文理

  • 文理是存储企业电子数据的基础Q它可以让所有的知识文在同一个^Cq作Q在一个中央数据库中统一存储和管理各U信息和现有业务?/li>
  • 在文管理模块中Q可以轻村ֈ建,存储Q搜索你需要的文Q合同,Ҏ书,产品说明书等M可以以文字表达下来的信息Q,q组l创Z业整个的知识理库?/li>
  • 文理q可以管理公司的内部|站和外部网站,q可设计灉|多样的信息门戗?/li>
  • 文理q提供多U知识管理工具以提升企业对知识的分n、积累、创新和利用?/li>
  • 文档理是对l织机构中的各类电子文实现l一存储和管理,支持加密、权限定义、分cd义?/li>
  • 全文索功能查找文g更加方便快捷Q工作效率明显提高?/li>
  • 文g的流通流转更加便P员工间文的协作更加方便?/li>
  • 降低U质文档的依赖,节省文理的成本?/li>
  • 重复利用历史的文,发挥知识财富的h倹{?/li>

??????所 ?/span>

公文{

  • 公文{以用于处理工作中的单位内外部的各U电子公?审批公文/通知公文Q应用审ҎE控制的原理实现准确、及时的公文的处理?/li>
  • 公文程的特点:
  • 公文{可自动控制公文的拟定、审核、阅诅R办理、完成等公文程的全q程工作?/li>
  • 公文理模块相对传统公文处理而言Q在很大E度上提高了公文处理效率和准性?/li>
  • 公文理使用软g自主开发的W合XPDL标准的工作流E控制模块,支持多线E、多条g的工作和审批程?/li>
  • 公文程支持会签功能Q可适用于复杂的重大合同或文件的审批?/li>
  • 公文程支持预定义流E、自定义程、固定流E?/li>
  • 公文程的主要作业:
  • 发文收文Q发文v草、发布来文登记的功能Q通过pȝ提供的在U编辑、附件上传功能可以与其它文档~辑工具q行l合?/li>
  • 公文办理Q根据预先设|的公文办理程Q实现公文的q程的流E控Ӟ支持多种程模型Q支持会{、退{、修改后l流E等操作Q可满了各U复杂的公文办理程的要求?/li>
  • 催办跌{Q对于超q办理期限或需Ҏ办理的公文,可以q行发送催办通知、邮Ӟ跌{操作{功能实玎ͼ对于办理程的跟t检查、特D流转的要求。提高公文流转办理的工作效率?/li>
  • 归销毁:通过与系l文管理的q接Q对于已完成{办理的公文,可以q行相应的归、销毁操作?/li>

Q??Q?Q????Q?Q???/span>

知识理

  • 知识仓库利用其广泛的数据知识资源Q经q严密、科学的分析整理Q根据条件的不同Q可利用于各行各业,指导各行各业的单位实体或个h能够沿正的发展方向发展Q能够将最先进的理论、最新的技术运用到最实际的生产生zM厅R?/li>
  • 知识理模块Q帮助企业构造适合自n的知识库Q指出重要的知识对象Q设计出知识理的基设施Q评估ƈ导入最适合企业的技术^収ͼ发挥知识价值的功能?/li>
  • 提供知识库的索功能:用户可以按照知识树或知识目的名U、知识项目中包含得内容进行检索?/li>
  • 应用pȝ的整合:它可以同企业门户q行完美的整合,帮助企业减少pȝ理l护的工作量?/li>
  • 提供分析报表Q方便优化管理:囑Ş化的报表分析Q提供各个部门、h员一D|间内的发布文章的状况Qƈ且各文章的点击率?能ؓ某个部门或用h荐相关的知识

Z理

  • 人力资源是对l织中的Z工作q行理Q括人员的基本信息、历信息管理、h员的调动分配、h员信息查询统计、W效考核、培训等Q?/li>
  • 人力资源理除了传统的h力资源管理的功能外,更ؓ重要的是通过与其他模块的协同工作Q实Ch力资源管理的全方位化和个性化?/li>
  • 集中的工作信息:在PMS 目理pȝ中,如果扑ֈ某一个员工,那么q个员工在公司内的所有痕qw能被提取出来Q例如有关的文Q客P资Q品,服务Q项目,工作d以及有关 的胦务信息在相关权限控制下展现在你的面前QؓU学的分析h员的情况Q制订h力资源策略提供强大的工具?/li>
<!-- r.t-->

客户理

  • 客户关系理自动化ƈ改善与销售、市销、客h务和支持{领域的客户关系有关的商业流E?/li>
  • 客户理的核心是客户价值管理,它将客户价值分为既成h倹{潜在h值和模型价|通过一对一营销原则Q满不同h值客L个性化需求,提高客户忠诚度和保有率,实现客户价值持lA献,从而全面提升企业盈利能力?/li>
  • 扑ֈq成交一位新客户需要投入很大的努力Q企?0%的利润来?0%的老客P完善的客L理是企业利润的源泉?/li>
  • 客户理是ؓ企业在激烈市场竞争中Q提供一套方便有力的理工具Q可以帮助企业ؓ客户提供更加完备周到的服务,通过有效地进行客戯源管理,使企业的产品和服务更加满_L实际需要,从而给企业带来更加丰厚的效益?/li>
  • PMS 目理pȝ的客户关pȝ理模块,以数据仓库、商业智能、知识发现等技术方法,使得攉、整理、加工和利用客户信息的质量大大提高?/li>
  • PMS 目理pȝq支持数据挖掘技术,Ҏ企业客户档案的特点徏立合理的数据挖掘分析模型和挖掘方法,从大量客h案原始资料中通过数据选择和检,揭示出隐含的h潜在价值的信息?/li>
<!-- r.t-->

销售管?/h4>
  • 销售管理系l主要用来处理与企业的销售活动相关的业务内容Q比如与客户{订销售订单、发货、办理出库、退货、收取销售货ƄQ而且q可以处理应收款、预收款以及现收Ƅ往来款业务?/li>
  • 通过销售订单录入与变更Q跟t管理销售情况;
  • Ҏ货品报h和销售数量开出销售发,Ҏ发货单生结凭证和收货单;
  • 提供实际销售商品金额与帐面金额核对功能Q?/li>
  • 提供了客户信用额度控制功能,可以辑ֈ降低销售风险,减少应收呆̎的目的,q可以实C务员销售业l、销售指标完成情늚考核功能?/li>
  • 销售计划:销售计划的制定、额度管理、销售力量管理和地域理?/li>
  • 销售管理:为现场销售h员设计,主要功能包括联系人和客户理、机会管理、日E安排、䄦金预、报仗报告和分析?/li>
  • 销售䄦金:允许销售经理创建和理销售队伍的奖励和䄦金计划,q帮助销售代表Ş象地了解各自的销售业l?/li>
<!-- r.t-->

订单理

  • 订单理是处理订单从录入到结清的整个q程的业务流E,主要包括Q?/li>
  • 订单的情늚记录、跟t和控制Q包括针寚w售合同的执行Q?/li>
  • 控制订货h、数量和客户、业务员信用理Q?/li>
  • 随时对订单完成情늚跟踪、控制订单的实际执行Q?/li>
  • Ҏ实际补货情况实现q加执行订单Q?/li>
  • q行比较q显C单执行差异,q过业务和分析报表进行订单执行情늚反映?/li>
  • 通过订单理的工作流E程序,订单理控制整个交易q程Qƈ形成记录和报告?/li>
<!-- r.t-->

合同理

  • 合同理是指企业对以自n为当事h的合同依法进行订立、行、变更、解除、{让、终止以及审查、监督、控制等一pd行ؓ的ȝ?/li>
  • 合同理的订立、行、变更、解除、{让、终止是合同理的内容;审查、监督、控制是合同理的手Dc?/li>
  • 合同理是全q程的、系l性的、动态性的?/li>
  • 合同理的全q程是由洽谈、草拟、签订、生效开始,直至合同失效为止Q不仅要理{订前的理Q更要进行签订后的管理?/li>
  • 合同理的系l性就是凡涉及合同条款内容的各部门都要一h理?/li>
  • 合同理的动态性就是注重U全q程的情况变化,特别要掌握对我方不利的变化,及时对合同进行修攏V变更、补充或中止和终止?/li>
<!-- r.t-->

财务理

  • 用款理Q对于单位内部的各种用款q行在线提交、审扏V借出登记、归q登记的理Q降低日常用Ƅ理工作的工作强度Q提高工作效率?/li>
  • 报销理Q对于单位内部的各种用款q行在线提交、审扏V报销登记的管理,降低日常报销理工作的工作强度,提高工作效率?/li>
  • 应收Ƅ理:对订单的应收ƾ进行统计和查询Qƈ自动提醒l办人员跟踪回款?/li>
  • 应付Ƅ理:对费用生的应付ƾ进行统计和查询Qƈ自动提醒l办人员及时跟踪付款?/li>
  • l计查询Q支持用h部门、款类别、相兌划进行相应的l计查询?/li>
  • 与胦务Y件的接口Q本pȝ可与财务理pȝq行数据交换Q实现胦务管理扩展功能?/li>
<!-- r.t-->

自定义表?/h4>
  • 自定义表单很象我们^时用的印刷好的表格Q可以用来:1.填写表格Q?.通过表格执行办理或审ҎE。例如:
  • 《请假条》表|q请h填表Q主批准,Z部备案,q是一U审ҎE表单,包含甌、流E、审批三U应用?/li>
  • 《质量问题报告》表|由客服填写,技术部/品质部调查,仓库补货Q胦务核销费用Q包含填表、流E两U应用(没有审批Q?/li>
  • 《出库单》等各种数据表和电子表格?/li>
  • 自定义表单主要有两种使用场合Q?/li>
  • 数据自定义表单:q种表单的条目可以Q意制定,q可讄权限Q没有流E控Ӟ
  • 程自定义表单:可以灉|实现各种程功能Q流E又分ؓQ?.工作程Q?.审批程两种应用方式Q?/li>
  • 自定义表单特点:
  • 具备完整的流E控制和权限理功能Q可以直接应用在审批程或工作流E控制上Q?/li>
  • 支持使用明细表,在一记录中带有多项子记录时Q可以用明l表Q?/li>
  • 字段可用系l中的数据表记录建立关系Q相当于数据库外键)Q如产品、客戗成员、项目、订单、采购单{;
  • 可创建流E类型的自定义表单(如生产流E表Q,或用于数据类型的自定义表单(如销售计划表Q?/li>
  • 目理pȝ对自定义表单的定义和讄可用模板来定义Q避免管理员p大量的时间在pȝ讄工作上?/li>
  • 自定义表单提供直观的自定义表单设计器Q用户可以创建无限数量的表单Q实现扩充系l初期未设计的各U功能,以适应企业未来的发展需求?/li>
  • 自定义表单极大的扩展了PMS 目理pȝ的应用,通过各U纸质表g用PMSpȝ的表单进行登记、管理,实现规范的表格的填写和存储,通过表单的流E对相关作业q行理控制Q通过报表q行l计、查询?/li>
  • 客户在当前的开发的基础上,可以自己使用自定义表单、自定义字段q行功能的扩充,q速升U系l的功能Q而无重写代码,也无M解原来系l的设计l节?/li>
<!-- r.t-->

个h工具

  • 个h办公提供个性化的工作界面,方便用户处理日常的工作事务?/li>
  • 个h讄Q?/li>
  • 修改pȝd密码Q?/li>
  • 用户桌面讄、常用菜单设|、风格选择和设|;
  • 个性化定义Q包括讨论区늧、头像、签名文件等的设|;
  • ~辑用户的个料,其他用户可以查询用户公开信息Q不公开敏感资料Q;
  • 个h工作q_Q?/li>
  • 用户桌面Q集中显C成员工作相关的主要信息摘要Q员工及时了解需要办理的各项事务Q进行自q工作日程安排?/li>
  • 邮g收发Q通过邮g和短信功能、实C内部或外部联pMh的工作交。具备的POP3邮g理功能Q可以实现对外部邮箱的管理功能?/li>
  • 个h通讯录:通过个h通讯录可以方ѝ快L实现对于常用联系人的分类理、综合查询等功能?/li>
  • 内部消息理Q实时短消息功能可以实现员工之间在线实时交流Q也可以使用短消息进行提醒闹钟设|功能?/li>
  • 个h日程理Q显CZ人日E相关的事g条目Q便于用户对日常工作计划q行安排理?/li>
  • 程操作Q可执行程甌提交、填写表单、上传附件、流E审扏V协办、委办等操作Qƈ可查看流E图?/li>
  • 个h知识库:用来攉和管理个人关心的知识文?/li>
<!-- r.t-->

邮gpȝ

  • 邮gpȝ实现内部、外部邮件收发功能?/li>
  • 与日怋用普通Outlook、Foxmail或Gmail、MSN{常见的邮g收发方式有显著的不同Q本pȝ除了实现内、外邮g的收发外Q关键是实现邮g信息的与内部pȝ的事务相兌Qƈ实现邮g信息的共享?/li>
  • 使用数据库统一存储邮gQ收发的邮g自动与客L录、联pMh目录、订单、采购单、项目等pȝ内部表记录关联v来?/li>
  • 邮gpȝ的信息共享:避免因某个成员请假或其他原因造成客户邮g丢失或工作停的风险?/li>
  • 邮gpȝ的工作协同:与外部的邮g通常是一事务(如报仗服务、咨询等事务Q,l一的邮件系l可以实C务过E的跟踪、记录和协调?/li>
  • 邮gpȝ支持使用邮g模板和群发,模板可实现邮件内容和格式的规范,发可方便向客户或指定的内部、外部对象组发送单一或批量的邮g?/li>
  • 内部邮g可用于内部信息传递,以及pȝ工作通知的手D,适合企业用户上传、互传文件或信息?/li>
  • Q提C:׃协作׃nQ因此不能对邮g的私密内Ҏ供保障)
<!-- r.t-->

业务程重组

  • PMS 目理pȝ采用工作组Ӟ用户只需填写有关表单Q系l会按照定义好的程自动往下跑Q下一U审批者将会收到相兌料,q可以根据需要修攏V跟t、管理、查询、统计、打印等Q大大提高了效率Q提升了公司的核心竞争力?/li>
  • 工作管理系l是一个真正的“h-机”系l,用户是系l中的基本角Ԍ是直接的d分派对象Q他可以直接看到电脑针对自己列出的“Q务清单”,跟踪每一Q务的状态,或l一Q务,而不必从一个模块退出,q入另一个模块,搜烦相应d的线索?/li>
  • 工作管理是直接面向用户的。这P用户的Q务分z֒d的完成状态,可以被最大程度地受到优化?/li>
  • 工作的定义借助于图形化工具Q依照业务过E实例的情况定义相应工作的安排?/li>
<!-- r.t-->

全文?/h4>
  • 全文索是从数据库的v量无序的内容中,发现有意义的文章或知识?/li>
  • 企业文U类J多Q如果没有功能强大的全文索引擎,q些文没有利用的h倹{?/li>
  • 通过数据挖掘技术,Ҏ和数据q行量化、整理,从而实现基于知识的决策?/li>
  • 在信息时代,获取信息Q或文档Q是一仉常容易的事,获得有效的信息才是关键中的关键。全文检索技术的目标是帮助用户实现获取有用的信息?/li>
  • 全文索技术,可实CGoogle相同的搜索引擎功能,不仅仅具有搜索功能,更能Ҏ输入的关键字Q找到最佛_配的文?/li>
  • 全文索技术,通过数据向量化分析,可对文本信息q行度量Q在信息度量基础上徏立的搜烦引擎Q不是简单文字的搜烦Q而是l过优化的与主题相关度的搜烦引擎?/li>
  • 全文索技术,能根据不同的知识特征q行分类Q采用多U类型的数据库进行分布式存储Q能对各U结构的知识q行l一集成?/li>
  • 全文索技术,能以各种手段为普通用h供便L知识查询Q返回有用的l果Q同时能在查询中起到D作用?/li>
<!-- r.t-->

报表图表

  • PMS 目理pȝ分析和报告工PZ业管理者进行各U商业知识分析决{支持?/li>
  • 在一个充分集成的信息化环境中Q信息管理相Ҏ较容易理解,q样公司内的每个人都可以更快地制定或执行更合理的决策?/li>
  • pȝ的报表采用Microsoft Reporting Services高报表技术,可以方便产生各种报表Q报表可以在U浏览报表,或输ZؓWord、Excel{常见的文g格式?/li>
  • 报表的内容可以系l中的Q何记录都可以产生报表Q也可以是各处室每月固定上报的月工作动态,报表的格式可以在具体实施时根据内容定制?/li>
  • 报表可以以图表的形式对系l中的数据进行统计分析,图表模式的报表可以更直观在表现数据分析的l果?/li>
<!-- r.t-->

pȝ后台

  • pȝ理员通过通过pȝ后台q行pȝ的设|和理?/li>
  • pȝ理员可查看pȝ日志、系l资源情늭信息?/li>
  • pȝ理员可q行密码恢复或加密文的解密操作?/li>
<!-- r.t-->

机构成员

  • 建立单位的组l机构体p,为单位的成员指定所属的部门、职位?/li>
  • l织机构是PMS 目理pȝ的基架构之一Q系l的d分配、审ҎE等均需要依赖于l织机构的信息?/li>
  • 首次安装pȝ后,通过机构成员中的功能Q徏立vl织机构的结构?/li>
  • PMS 目理pȝ支持动态绘制组l机构图?/li>
<!-- r.t-->

pȝ讄

  • pȝ讄包括Q机构、角艌Ӏ权限、成员、字典、属性、分cR流E、表单、菜单、语a、界面、配艌Ӏ模板等pȝ需要的基础属性数据?/li>
  • pȝ讄l护为管理员提供一个方便的工具q行基础数据的录入和l护?/li>
  • 理员可以用批处理工具一ơ编辑大量的数据Q提高工作效率?/li>


P 2009-05-18 10:16 发表评论
]]>
用AcegiZ的Spring应用加把锁!http://www.tkk7.com/xpsir/articles/271245.htmlPPMon, 18 May 2009 02:09:00 GMThttp://www.tkk7.com/xpsir/articles/271245.htmlhttp://www.tkk7.com/xpsir/comments/271245.htmlhttp://www.tkk7.com/xpsir/articles/271245.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/271245.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/271245.html
 

?/strong>

对于一个典型的Web应用Q完善的认证和授权机制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStorel了一些这斚w的介l,但还q远不够QAcegi是一个专门ؓSpringFramework提供安全机制的项目,全称为Acegi Security System for SpringQ当前版本ؓ0.5.1Q就其目前提供的功能Q应该可以满绝大多数应用的需求?/p>

本文的主要目的是希望能够说明如何在基于Spring构架的Web应用中用AcegiQ而不是详l介l其中的每个接口、每个类。注意,即对已l存在的Spring应用Q通过下面介绍的步骤,也可以马上n受到Acegi提供的认证和授权?/p>

基础工作

在你的Web应用的lib中添加Acegi下蝲包中的acegi-security.jar

web.xml

实现认证和授权的最常用的方法是通过filterQAcegi亦是如此Q通常Acegi需要在web.xmld以下5个filterQ?/p>

																						

<filter>
  <filter-name>Acegi Channel Processing Filter</filter-name>
  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
  <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
  </init-param>
</filter>
<filter>
  <filter-name>Acegi Authentication Processing Filter</filter-name>
  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
  <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
  </init-param>
</filter>
<filter>
  <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
  <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
  </init-param>
</filter>
<filter>
  <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
  <filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class>
</filter>
<filter>
  <filter-name>Acegi HTTP Request Security Filter</filter-name>
  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
  <init-param>
    <param-name>targetClass</param-name>
    <param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
  </init-param>
</filter>

最先引赯惑的是net.sf.acegisecurity.util.FilterToBeanProxyQAcegi自己的文上解释是:“What  FilterToBeanProxy does is delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility.”,如希望深I的话,ȝ看源代码应该不难理解?/p>

再下来就是添加filter-mapping了:

																						

<filter-mapping>
  <filter-name>Acegi Channel Processing Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>Acegi Authentication Processing Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>Acegi HTTP Request Security Filter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

 
q里Q需要注意以下三点: 
1) q几个filter的顺序是不能更改的,序不对无法正常工作; 
2) 如果你的应用不需要安全传输,如httpsQ则?Acegi Channel Processing Filter"相关内容注释掉即可; 
3) 如果你的应用不需要Spring提供的远E访问机Ӟ如Hessian and BurlapQ将"Acegi HTTP BASIC Authorization Filter"相关内容注释掉即可?p>#p#

applicationContext.xml

接下来就是要dapplicationContext.xml中的内容了,从刚才FilterToBeanFactory的解释可以看出,真正的filter都在Spring的applicationContext中管理:

1)首先Q你的数据库中必d有保存用户名和密码的tableQAcegi要求table的schema必须如下Q?/p>

CREATE TABLE users (
    username VARCHAR(50) NOT NULL PRIMARY KEY,
    password VARCHAR(50) NOT NULL,
    enabled BIT NOT NULL
);
CREATE TABLE authorities (
    username VARCHAR(50) NOT NULL,
    authority VARCHAR(50) NOT NULL
);
CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username)

REFERENCES users
(username);

2)d讉K你的数据库的datasource和Acegi的jdbcDaoQ如下:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
  <property name="url"><value>${jdbc.url}</value></property>
  <property name="username"><value>${jdbc.username}</value></property>
  <property name="password"><value>${jdbc.password}</value></property>
</bean>
<bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
  <property name="dataSource"><ref bean="dataSource"/></property>
</bean>

3)dDaoAuthenticationProviderQ?/p>

<bean id="daoAuthenticationProvider"

class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
  <property name="authenticationDao"><ref bean="authenticationDao"/></property>
  <property name="userCache"><ref bean="userCache"/></property>
</bean>

<bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
  <property name="minutesToIdle"><value>5</value></property>
</bean>

如果你需要对密码加密Q则在daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref bean="passwordEncoder"/></property>QAcegi提供了几U加密方法,详细情况可看包net.sf.acegisecurity.providers.encoding

4)dauthenticationManagerQ?/p>

<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
  <property name="providers">
    <list>
      <ref bean="daoAuthenticationProvider"/>
    </list>
   </property>
</bean>

5)daccessDecisionManagerQ?/p>

 <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
  <property name="allowIfAllAbstainDecisions">
    <value>false</value>
  </property>
  <property name="decisionVoters">
    <list><ref bean="roleVoter"/></list>
  </property>
</bean>
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>

6)dauthenticationProcessingFilterEntryPointQ?/p>

<bean id="authenticationProcessingFilterEntryPoint"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
  <property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
  <property name="forceHttps"><value>false</value></property>
</bean>

其中acegilogin.jsp是登陆页面,一个最单的d面如下Q?/p>

<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
<%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %>
<%@ page import="net.sf.acegisecurity.AuthenticationException" %>
<html>
  <head>
    <title>Login</title>
  </head>

  <body>
    <h1>Login</h1>
    <form action="<c:url value='j_acegi_security_check'/>" method="POST">
      <table>
        <tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
        <tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
        <tr><td colspan='2'><input name="submit" type="submit"></td></tr>
        <tr><td colspan='2'><input name="reset" type="reset"></td></tr>
      </table>
    </form>
  </body>
</html>

7)dfilterInvocationInterceptorQ?/p>

<bean id="filterInvocationInterceptor"
class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
  <property name="authenticationManager">
    <ref bean="authenticationManager"/>
  </property>
  <property name="accessDecisionManager">
    <ref bean="accessDecisionManager"/>
  </property>
  <property name="objectDefinitionSource">
    <value>
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      \A/sec/administrator.*\Z=ROLE_SUPERVISOR
      \A/sec/user.*\Z=ROLE_TELLER
    </value>
  </property>
</bean>

q里h意,要objectDefinitionSource中定义哪些页面需要权限访问,需要根据自q应用需求进行修改,我上面给出的定义的意思是q样的:

#p#

a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比较请求\径时全部转换为小?span class="Apple-converted-space"> 
b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有权限为ROLE_SUPERVISOR才能讉K/sec/administrator*的页?span class="Apple-converted-space"> 
c. \A/sec/user.*\Z=ROLE_TELLER意思是只有权限为ROLE_TELLER的用h能访?sec/user*的页?/p>

8)dsecurityEnforcementFilterQ?/p>

<bean id="securityEnforcementFilter"

class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
  <property name="filterSecurityInterceptor">
    <ref bean="filterInvocationInterceptor"/>
  </property>
  <property name="authenticationEntryPoint">
    <ref bean="authenticationProcessingFilterEntryPoint"/>
  </property>
</bean>

9)dauthenticationProcessingFilterQ?/p>

<bean id="authenticationProcessingFilter"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
  <property name="authenticationManager">
    <ref bean="authenticationManager"/>
  </property>
  <property name="authenticationFailureUrl">
    <value>/loginerror.jsp</value>
  </property>
  <property name="defaultTargetUrl">
    <value>/</value>
  </property>
  <property name="filterProcessesUrl">
    <value>/j_acegi_security_check</value>
  </property>
</bean>

其中authenticationFailureUrl是认证失败的面?/p>

10)如果需要一些页面通过安全通道的话Q添加下面的配置Q?/p>

<bean id="channelProcessingFilter"

class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
  <property name="channelDecisionManager">
    <ref bean="channelDecisionManager"/>
  </property>
  <property name="filterInvocationDefinitionSource">
    <value>
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      \A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL
      \A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
      \A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
      \A.*\Z=REQUIRES_INSECURE_CHANNEL
    </value>
  </property>
</bean>

<bean id="channelDecisionManager"

class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
  <property name="channelProcessors">
    <list>
      <ref bean="secureChannelProcessor"/>
      <ref bean="insecureChannelProcessor"/>
    </list>
  </property>
</bean>
<bean id="secureChannelProcessor"

class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor"

class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>

~少了什么?

Acegi目前提供了两U“secure object”,分别寚w面和Ҏq行安全认证理Q我q里介绍的只是利用FilterSecurityInterceptor对访问页面的权限控制Q除此之外,Acegiq提供了另外一个Interceptor——MethodSecurityInterceptorQ它l合runAsManager可实现对对象中的Ҏ的权限控Ӟ使用Ҏ可参看Acegi自带的文和contact范例?/p>

最后要说的

本来以ؓ只是说明如何使用Acegi而已Q应该非常简单,但真正写h才发现想要条理清楚的理顺所有需要的beanq是很困隄Q但愿我没有遗漏太多东西Q如果我的文章有什么遗漏或错误的话Q还请参看Acegi自带的quick-start范例Q但h意,q个范例是不能直接拿来用的?/p>



P 2009-05-18 10:09 发表评论
]]>
prototype.js常用函数及其用法http://www.tkk7.com/xpsir/articles/132012.htmlPPTue, 24 Jul 2007 03:26:00 GMThttp://www.tkk7.com/xpsir/articles/132012.htmlhttp://www.tkk7.com/xpsir/comments/132012.htmlhttp://www.tkk7.com/xpsir/articles/132012.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/132012.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/132012.html
prototype.js常用函数及其用法
 
prototype.js常用函数:
函数?/td>  解释  举例
 Element.toggle  交替隐藏或显C?/td>  Element.toggle(''div1'',''div2'')
 Element.hide  隐藏  Element.hide(''div1'',''div2'')
 Element.show  Element.show(''div1'',''div2'')
 Element.remove  删除  Element.remove(''div1'',''div2'')
 Element.getHeight  取得高度  Element.getHeight(''div1'')
 Toggle.display  和Element.toggle相同  Toggle.display(''div1'',''div2'')
 Insertion.Before  在DIV前插入文?/td>  Insertion.Before(''div1'',''my content'')
 Insertion.After  在DIV后插入文?/td>  Insertion.After(''div1'',''my content'')
 Insertion.Top  在DIV里最前插入文?/td>  Insertion.Top(''div1'',''this is a text'')
 Insertion.Bottom  在DIV里最后插入文?/td>  Insertion.Bottom(''div1'',''this is a text'')
 PeriodicalExecuter  以给定频率调用一DJavaScript  PeridicalExecutor(test, 1)"q里test是Javascript的函?1是频?1U?.
 $  取得一个DIV, 相当于getElementById()  $(''div1'')
 Field.clear  清空一个输入框  Field.clear(''textfield1'')
 Field.focus ?nbsp;焦点集中在输入框?/td>  Field.focus(''select1'')
 Field.present  判断内容是否为空  alert(Field.present(''textfield1''))"
 Field.select  选择输入框的内容  Field.select(''textfield1'')"
 Field.activate  ?nbsp;焦点集中在输入框上ƈ选择输入框的内容  Field.activate(''textfield1'')"
 Form.serialize  把表格内容{化成string  
 Form.getElements  取得表格内容为数lŞ?/td>  
 Form.disable  disable表格所有内?/td>  Form.disable(''form1'') (q个好象不work)
 Form.focusFirstElement  把焦炚w中在表格W一个元素上  Form.focusFirstElement(''form1'')
 Form.reset  Reset表格 Form.reset(''form1'')
 Form.Element.getValue  取得表格输入框的?/td>  Form.Element.getValue(''text1'')
 Form.Element.serialize   把表g输入框内容{化成string  Form.Element.serialize(''text1'')
 $F  {同于Form.Element.getValue()  $F(''text1'')
 Effect.Highlight  高亮Ҏ.  Effect.Highlight(''text1'')
 Effect.Fade  褪色Ҏ  
 Effect.Scale  攑֤~小(癑ֈ比)

Effect.Scale(''text1'', 200)
q里200 = 200%, 即两?/p>

 Effect.Squish  消失ҎQ文字羃后消失  Effect.Squish(''text1'')
 Effect.Puff  消失ҎQ文字放大后消失  Effect.Puff(''text1'')
 Effect.Appear  出现Ҏ  
 Effect.ContentZoom  ZOOMҎQ?/td>  
 Ajax.Request  传送Ajaxhl服务器  Ajax.Request(''http://server/s.php'')
 Ajax.Updater  传送Ajaxhl服务器q用{复的结果更新指定的Container  Ajax.Updater(''text1'',''http://server/s.php'')

      基本用法:prototype.jsl每个主要的c都分了一个Class,使用h很方?要生特定的效果,只要用new Class.function(<argument>)可以了.例如:

<DIV id="div1"><a href="#" onclick="new Element.toggle('div2')">Click Me</a></DIV>
<DIV id="div2">Hello!</DIV>

      当点击Click Me的时?div2׃交替隐藏或显C?注意,你可以给toggle加上无限个parameter,比如Element.toggle(''div2'',''div3'',''div4'',...)

 


P 2007-07-24 11:26 发表评论
]]>
_Nejbhttp://www.tkk7.com/xpsir/articles/131600.htmlPPSat, 21 Jul 2007 03:20:00 GMThttp://www.tkk7.com/xpsir/articles/131600.htmlhttp://www.tkk7.com/xpsir/comments/131600.htmlhttp://www.tkk7.com/xpsir/articles/131600.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/131600.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/131600.html阅读全文

P 2007-07-21 11:20 发表评论
]]>
使用Java实现|络传输数据的压~?/title><link>http://www.tkk7.com/xpsir/articles/28882.html</link><dc:creator>P</dc:creator><author>P</author><pubDate>Sat, 21 Jan 2006 08:07:00 GMT</pubDate><guid>http://www.tkk7.com/xpsir/articles/28882.html</guid><wfw:comment>http://www.tkk7.com/xpsir/comments/28882.html</wfw:comment><comments>http://www.tkk7.com/xpsir/articles/28882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/xpsir/comments/commentRss/28882.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/xpsir/services/trackbacks/28882.html</trackback:ping><description><![CDATA[<TABLE class=border cellSpacing=0 cellPadding=2 width="100%" align=center border=0> <TBODY> <TR vAlign=center align=middle> <TD colSpan=2 height=40><FONT size=4><STRONG>使用Java实现|络传输数据的压~?/STRONG></FONT> </TD></TR> <TR class=tdbg_rightall align=middle> <TD colSpan=2>Q?作者:liudong    转脓自:Matrix    点击敎ͼ150    更新旉Q?005-6-1    文章录入Q?A >sailing</A> Q? <HR width="80%" color=#ff3333 noShade SIZE=2> </TD></TR> <TR> <TD colSpan=2> <TABLE style="WORD-BREAK: break-all" cellSpacing=5 cellPadding=0 width="100%" border=0> <TBODY> <TR> <TD vAlign=top width="98%" height=200><FONT face=宋体 size=3>本周,我回{了两个使用Javaq行数据压羃的问?<BR><BR>W一个问题是: 我怎样才能压羃那些不在文g中的数据.<BR><BR>W二个问题是: 我以极大的热情阅MTodd Sundsted?压羃你的数据,从而提高你的网l应用程序的性能",但是d后我却有点失?当我d文章标题时我很高?我想我ȝ扑ֈ了解决问题的办法?<BR><BR>在我们的公司,我们试图提高一个组l数据的RMI应用E序的性能.服务器端q行了绝大部分的处理和优?我们׃一q半的时间去提高性能,但是现在看来瓉在于数据的传输上.在一天的M旉?我们都有可能在客户和服务器之间传送成千上万的数据.<BR><BR>一U可能的解决办法,我徏议我们能够在把数据返回给客户端时先压~这些数?q在Todd的文章中已经说得很清楚了.但是,文章中的例子却是压羃文g,而不是我们所需要的----Ҏ据进行压~?<BR><BR>在RMI中的实现?我们先从数据库取得数?再把数据攑օ一个列表中,接着把这个列表返回给客户?最后再把它们插入JTable?我想在把数据q回l客h,首先把列表中的数据压~?然后在客L解压~?最后把数据插入到表g.<BR><BR>q样的想法可行吗?<BR><BR>A:最q我收到了一些关于Todd的文章的疑问.很多读者看hҎ章中的D例很疑惑.因ؓ文章中的例子是以文g压羃为核心的.<BR><BR>首先回答W一个问?当你使用ZipInputStream ?nbsp;ZipOutputStream q没有强制你必须使用文g.唯一要注意的是你必须把数据{换ؓ字节数组的Ş?<BR><BR>W二个问题比较棘?在网l中,以RMI方式通信需要作一些调整了.Z在传送数据之前就让RMIq行数据压羃,你必dZ个能够压~数据的新的套接?然后,当你创徏了一个套接字?你得告诉RMI使用q一套接?<BR><BR>以下是创Z个RMI形式的套接字的简要步?<BR><BR>1:选择或者创Z个新的套接字.(可以参看SUN'S?创徏一个典型的套接?).<BR><BR>2:创徏一个服务器端的套接?<BR><BR>3:创徏一个RMIClientSocketFactory<BR><BR>4:创徏一个RMIServerSocketFactory<BR><BR>5:创徏一个承了UnicastRemoteObjec的远E对?从而用新的factories.<BR><BR>Ҏq一大致的想?我们来看每一步如何具体的实现.<BR><BR>步骤1: 创徏ZipSocket <BR><BR>׃要进行Zip压羃,我们重新创徏q样的套接字<BR><BR>mport java.io.InputStream;<BR><BR>import java.io.OutputStream;<BR><BR>import java.util.zip.ZipInputStream;<BR><BR>import java.util.zip.ZipOutputStream;<BR><BR>import java.net.Socket;<BR><BR>public class ZipSocket extends Socket {<BR><BR><BR><BR>private InputStream in;<BR><BR>private OutputStream out;<BR><BR><BR><BR>public ZipSocket() { super(); }<BR><BR><BR><BR>public ZipSocket(String host, int port) <BR><BR>throws IOException {<BR><BR>super(host, port);<BR><BR>}<BR><BR><BR><BR>public InputStream getInputStream() <BR><BR>throws IOException {<BR><BR>if (in == null) {<BR><BR>in = new ZipInputStream(super.getInputStream());<BR><BR>}<BR><BR>return in;<BR><BR>}<BR><BR><BR><BR>public OutputStream getOutputStream() <BR><BR>throws IOException {<BR><BR>if (out == null) {<BR><BR>out = new ZipOutputStream(super.getOutputStream());<BR><BR>}<BR><BR>return out;<BR><BR>}<BR><BR><BR><BR>public synchronized void close() throws IOException {<BR><BR>OutputStream o = getOutputStream();<BR><BR>o.flush();<BR><BR>super.close();<BR><BR>}<BR><BR>}<BR><BR><BR><BR><BR><BR>步骤2: 创徏ZipServerSocket <BR><BR><BR><BR>import java.net.ServerSocket;<BR><BR>import java.net.Socket;<BR><BR>import java.io.IOException;<BR><BR><BR><BR>public class ZipServerSocket extends ServerSocket<BR><BR>{<BR><BR>public ZipServerSocket(int port) throws IOException { <BR><BR>super(port);<BR><BR>}<BR><BR><BR><BR>public Socket accept() throws IOException { <BR><BR>Socket socket = new ZipSocket();<BR><BR>implAccept(socket);<BR><BR>return socket;<BR><BR>}<BR><BR>}<BR><BR><BR><BR><BR><BR>步骤3:创徏ZipClientSocketFactory <BR><BR>客户端的factory的创建必遵循以下的形式: <BR><BR><BR><BR>import java.io.IOException; <BR><BR>import java.io.Serializable; <BR><BR>import java.net.Socket; <BR><BR>import java.rmi.server.RMIClientSocketFactory;<BR><BR><BR><BR>public class ZipClientSocketFactory <BR><BR>implements RMIClientSocketFactory, Serializable { <BR><BR>public Socket createSocket(String host, int port) <BR><BR>throws IOException { <BR><BR>ZipSocket socket = new ZipSocket(host, port); <BR><BR>return socket; <BR><BR>} <BR><BR>}<BR><BR><BR><BR>步骤4:创徏ZipServerSocketFactory <BR><BR><BR><BR>import java.io.IOException; <BR><BR>import java.io.Serializable; <BR><BR>import java.net.ServerSocket; <BR><BR>import java.rmi.server.RMIServerSocketFactory; <BR><BR><BR><BR>public class ZipServerSocketFactory <BR><BR>implements RMIServerSocketFactory, Serializable { <BR><BR><BR><BR>public ServerSocket createServerSocket(int port) <BR><BR>throws IOException { <BR><BR>ZipServerSocket server = new ZipServerSocket(port); <BR><BR>return server; <BR><BR>} <BR><BR>}<BR><BR><BR><BR>步骤5: 创徏一个承了UnicastRemoteObjec的远E对?从而用新的factories. <BR><BR>public class YourRMIObject extends UnicastRemoteObject {<BR><BR><BR><BR>public YourRemoteObject( int port ) {<BR><BR>super( port, new ZipClientSocketFactory(), new ZipServerSocketFactory() );<BR><BR>}<BR><BR><BR><BR>// 剩下的是你自qE序实现<BR><BR><BR><BR>}<BR><BR><BR><BR>现在你的通信数据得到了压~?<BR><BR><BR><BR><BR><BR>关于作?<BR><BR>Tony Sintes 是一个独立咨询h,同时也是First Class Consulting, Inc. 的创始h.q一咨询公司主要致力与对各个不同的企业系l进行量w定制和培训 . 业余旉,Tony 是一个积极的自由作家,同时也是Sams出版?lt;<21天学通面向对象编E?gt;>的作?nbsp;(Sams, 2001; ISBN: 0672321092). <BR></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.tkk7.com/xpsir/aggbug/28882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xpsir/" target="_blank">P</a> 2006-01-21 16:07 <a href="http://www.tkk7.com/xpsir/articles/28882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>qqhttp://www.tkk7.com/xpsir/articles/28022.htmlPPSat, 14 Jan 2006 06:22:00 GMThttp://www.tkk7.com/xpsir/articles/28022.htmlhttp://www.tkk7.com/xpsir/comments/28022.htmlhttp://www.tkk7.com/xpsir/articles/28022.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/28022.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/28022.html
与我聊天?INPUT id=hiden type=hidden value=ok name=hiden>


P 2006-01-14 14:22 发表评论
]]>
oracle+jsp中blobcd存储大文本问题解x?/title><link>http://www.tkk7.com/xpsir/articles/23186.html</link><dc:creator>P</dc:creator><author>P</author><pubDate>Fri, 09 Dec 2005 10:06:00 GMT</pubDate><guid>http://www.tkk7.com/xpsir/articles/23186.html</guid><wfw:comment>http://www.tkk7.com/xpsir/comments/23186.html</wfw:comment><comments>http://www.tkk7.com/xpsir/articles/23186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/xpsir/comments/commentRss/23186.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/xpsir/services/trackbacks/23186.html</trackback:ping><description><![CDATA[oracle+jsp中blobcd存储大文本问题解x?BR>oracle 存储大文本一直是一个棘手的问题?BR>一、存数据库:<BR><%@page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %><BR><%<BR>//定义变量<BR>java.sql.Connection conn; //数据库连接对?BR>String sql;<BR>long id;<BR>ResultSet rs;<BR>Statement stmt,stmt1; <P>java.sql.DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //装蝲JDBC驱动E序<BR>conn = java.sql.DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.2:1521:lqxm","lqxm","lqxm"); //q接数据?/P> <P>request.setCharacterEncoding("GBK");<BR>String title = request.getParameter("title");<BR>String content = request.getParameter("content");<BR>String sort = request.getParameter("sort");<BR>String type = request.getParameter("type");<BR>String rq = request.getParameter("rq");<BR>String qy = request.getParameter("qy");<BR>//插入数据,此时blob字段中插入的是空?BR>sql="insert into t_flfg (xlh,title,content,rq,sort,type,qy) ";<BR>sql=sql+"Values(FLFG_SEQ.NEXTVAL,'" + title + "',empty_clob(),'" + rq + "','" + sort + "','" + type + "','" + qy + "')";<BR>stmt=conn.createStatement();<BR>stmt.executeUpdate(sql);<BR>conn.commit();</P> <P>conn.setAutoCommit(false);<BR>stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENS99vIVE,ResultSet.CONCUR_UPDATABLE);<BR>//取得刚才插入的ID<BR>sql="select max(xlh) as xlh from t_flfg ";<BR>rs=stmt.executeQuery(sql);<BR>if(rs.next()) {<BR>id=rs.getInt("xlh");<BR>}<BR>rs.close();</P> <P>sql = "select content from t_flfg where xlh="+id+" for update";<BR>rs = stmt.executeQuery(sql);<BR>if (rs.next()) {<BR>oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob(1);<BR>clob.putString(1, content);<BR>sql = "update t_flfg set content=? where xlh=" + id + ""; //大文本更新q去Q呵?BR>PreparedStatement pstmt = conn.prepareStatement(sql);<BR>pstmt.setClob(1, clob);<BR>pstmt.executeUpdate();<BR>}</P> <P>conn.commit();<BR>stmt.close();<BR>conn.close();<BR>%></P> <P>二、检索显C数据:<BR><%<BR>ResultSet rs = flfgSave.searchOneInfo(request.getParameter("xlh")); //查询数据库获取记录集<BR>rs.next();</P> <P>int y;<BR>String content = "";<BR>oracle.sql.CLOB clob1;<BR>char ac[] = new char[299];</P> <P>String title = rs.getString("title");</P> <P>clob1 = (oracle.sql.CLOB)rs.getObject("content");<BR>Reader reader = clob1.getCharacterStream();<BR>while((y = reader.read(ac, 0, 299)) != -1)<BR>content += new String(ac, 0, y); //q就是取出来的大文本<BR>%> </P><img src ="http://www.tkk7.com/xpsir/aggbug/23186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/xpsir/" target="_blank">P</a> 2005-12-09 18:06 <a href="http://www.tkk7.com/xpsir/articles/23186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应用Java技术开发WAP应用E序http://www.tkk7.com/xpsir/articles/21931.htmlPPWed, 30 Nov 2005 03:42:00 GMThttp://www.tkk7.com/xpsir/articles/21931.htmlhttp://www.tkk7.com/xpsir/comments/21931.htmlhttp://www.tkk7.com/xpsir/articles/21931.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/21931.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/21931.html序言Q?/B>
  
  ׃前些旉Q一些matrixer帔R关于j2me中用Pak文g的问题。本学艺不深Q但满怀热心的做了一番探索,现将制作Pak文g的看法和Ҏ公布出来Q大家多多提意见?BR>  
  一、什么是Pak文gQ?BR>  
  Pak文g是多个文件打包ؓ一个单独文Ӟ在这个文件中保存着多个文g的数据,当然q有一些描q文件结构的数据。所以将“Pak”作为文件的后缀是一U常规的用法Q大家可以自定义其它的文件后~?BR>  
  二、ؓ什么用Pak文gQ?/B>
  
  ׃MIDP对发布安装的j2meE序大小q行了限Ӟ所以羃发布程序就意味着能够提供更多的程序或者内容(如图片、音乐)l用戗而通过研究发现zip/jar法对大文g的压~率高于对等量的多个文件的压羃率?BR>  
  当然q有其它ҎQ这里简单做一下讨论比如用؜淆器ProGuard的?overloadaggressively”选项使jar文g~小Q但也会D一些错误,因ؓq种Ҏ生成jar中的classW合java byte code标准Q但是与java语法相悖Q严重的可能造成一些jre对Object的序列化错误?BR>  
  所以用PakҎ程序中要用到的资源Q图片、音乐、文本)l合为单一文g是一个安全有效的Ҏ。而且对于一些商用程序,完全可以在pak文g中对文g数据q行加密Q很好的保护了作者和公司的权益。本人的sample中用了单的“加减法”加密,对于手机q类讑֤来讲是一个效率较高的选择?BR>  
  三、Pak文g的结构:
  
  大家可以自己设计Pak文gl构Q本里只是抛砖引玉的作个sample。下面就是本计的Pak文gl构Q?BR>  
  PAK File HeaderQPak文g的头?BR>  
  * {֐Q?字节char数组 * 版本P32位float * 文gtable数量Q?2位整?* 密码行ؓQ?位字?* 密码Q?位字?* 文g唯一IDQ?0字节char数组 * 保留位:32位整?4字节)
  
  File TableQPak文g中包含文件的列表Q在一个Pak文g中一个被包含的文件对应一个File Table?BR>  
  * 文g名:30字节char数组 * 文g大小Q?2位整?* 文g在pak文g中的位移Q?2位整?BR>  
  Concatenated File DataQ按File Table的顺序连接在一L文g数据?BR>  * 文g数据
  
  四、程序框Ӟ
  
  说明Q由于Pak文g的制作和使用分别要用两个java应用领域Qj2se和j2meQ所以本人将PakUtilcd作了2个版本(j2se和j2meQ?BR>  
  E序框架如下Q?BR>  1。PakHeaderc,定义了Pak文g头?BR>  2。PakFileTablec,定义Pak文gtable?BR>  3。PakUtilc(j2se版)Q具备两个功能:多个png囄合成一个Pak文gQƈ使用单的加减加密法对其进行加密;从Pak文g中取出png囄Q构造byte数组Q可以用来构造Image对象Q或者写为文件?BR>  PakUtilc(j2me版)Q具备的功能Q从Pak文g中取出png囄Q构造byte数组Q可以用来构造Image对象Q?BR>  
  五、PakHeader和PakFileTablec?/B>Q?BR>  
  PakHeader.javaQ?BR>  package cn.org.matrix.gmatrix.gameLab.util.pak;/** * Pak文g_ * l构Q?*
  {֐Q?字节char数组 *  版本P32位float *
  文gtable数量Q?2位整?*
  密码行ؓQ?位字?*  密码Q?位字?*
  文g唯一IDQ?0字节char数组 *
  保留位:32位整?4字节) * @author cleverpig * */class PakHeader {
  //定义文g唯一ID长度
  public static final int UNIQUEID_LENGTH=10;
  //定义文g{֐长度
  public static final int SIGNATURE_LENGTH=6;
  //定义加法q算
  public static final int ADDITION_CIPHERACTION=0;
  //定义减法q算
  public static final int SUBTRACT_CIHOERACTION=1;
  //文g{֐
  private char[] signature=new char[SIGNATURE_LENGTH];
  //版本?BR>  private float version=0f;
  //文gtable数量
  private long numFileTableEntries=0;
  //密码使用ҎQ在原数据上q行加法q是减法
  private byte cipherAction=ADDITION_CIPHERACTION;
  //密码?BR>  private byte cipherValue=0x00;
  //唯一ID
  private char[] uniqueID=new char[UNIQUEID_LENGTH];
  //保留?字节
  private long reserved=0;
  public PakHeader(){
  }
  /**
  * 构造方?BR>  * @param signature {֐
  * @param version 版本
  * @param numFileTableEntries 文gtable数量
  * @param cipherAction 密码使用Ҏ
  * @param cipherValue 密码?BR>  * @param uniqueID 唯一ID
  * @param reserved 保留?字节
  */
  public PakHeader(char[] signature,float version,
  long numFileTableEntries,byte cipherAction,
  byte cipherValue,char[] uniqueID,long reserved){
  for(int i=0;i<SIGNATURE_LENGTH;this.signature[i]=signature[i],i++)
  ;
  this.version=version;
  this.cipherAction=cipherAction;
  this.numFileTableEntries=numFileTableEntries;
  this.cipherValue=cipherValue;
  for(int i=0;i<UNIQUEID_LENGTH;this.uniqueID[i]=uniqueID[i],i++);
  this.reserved=reserved;
  }        
  public byte getCipherValue() {
  return cipherValue;    
  }
  public void setCipherValue(byte cipherValue) {
  this.cipherValue = cipherValue;
  }
  public long getNumFileTableEntries() {
  return numFileTableEntries;
  }
  public void setNumFileTableEntries(long numFileTableEntries) {
  this.numFileTableEntries = numFileTableEntries;
  }
  public long getReserved() {
  return reserved;
  }
  public void setReserved(long reserved) {
  this.reserved = reserved;
  }
  public char[] getUniqueID() {
  return uniqueID;
  }
  public void setUniqueID(char[] uniqueID) {
  for(int i=0;i<UNIQUEID_LENGTH;this.uniqueID[i]=uniqueID[i],i++)
  ;    
  }    
  public float getVersion() {
  return version;
  }    
  public void setVersion(float version) {
  this.version = version;
  }
  public byte getCipherAction() {
  return cipherAction;
  }
  public void setCipherAction(byte cipherAction) {
  this.cipherAction = cipherAction;
  }
  public char[] getSignature() {
  return signature;
  }
  public void setSignature(char[] signature) {
  for(int i=0;i<SIGNATURE_LENGTH;this.signature[i] = signature[i],i++)
  ;    
  }
  /**
  * q回PakHeader的大?BR>  * @return q回PakHeader的大?BR>  */    
  public static int size(){
  return SIGNATURE_LENGTH+4+4+1+1+UNIQUEID_LENGTH+4;
  }
  public String toString(){
  String result="";
  result+="\t{֐:"+new String(this.signature).trim()
  +"\t版本?"+this.version
  +"\t文gtable数量:"+this.numFileTableEntries
  +"\t密码行ؓ:" +this.cipherAction
  +"\t密码:"+this.cipherValue            
  +"\t文g唯一ID:"+new String(this.uniqueID).trim()            +"\t保留?"+this.reserved;        
  return result;    
  }}
  
  PakFileTable.java
  package cn.org.matrix.gmatrix.gameLab.util.pak;/** * Pak文gtablec?* 文gtablel构Q?*
  文g名:30字节char数组 *
  文g大小Q?2位整?*
  文g在pak文g中的位移Q?2位整?* @author cleverpig * */class PakFileTable {
  public static final int FILENAME_LENGTH=30;
  //文g?BR>  private char[] fileName=new char[FILENAME_LENGTH];
  //文g大小
  private long fileSize=0L;
  //文g在pak文g中的位移
  private long offSet=0L;
  public PakFileTable(){
  }
  /**
  * 构造方?BR>  * @param fileName 文g?BR>  * @param fileSize 文g大小
  * @param offSet 文g在Pak文g中的位移
  */
  public PakFileTable(char[] fileName,
  long fileSize,long offSet){
  for(int i=0;i<FILENAME_LENGTH;this.fileName[i]=fileName[i],i++)
  ;        this.fileSize=fileSize;
  this.offSet=offSet;
  }
  public char[] getFileName() {
  return fileName;
  }
  public void setFileName(char[] fileName) {
  for(int i=0;i<fileName.length;this.fileName[i]=fileName[i],i++)
  ;    
  }
  public long getFileSize() {
  return fileSize;
  }
  public void setFileSize(long fileSize) {
  this.fileSize = fileSize;
  }
  public long getOffSet() {
  return offSet;
  }
  public void setOffSet(long offSet) {
  this.offSet = offSet;
  }
  /**
  * q回文gTable的大?BR>  * @return q回文gTable的大?BR>  */    
  public static int size(){
  return FILENAME_LENGTH+4+4;
  }
  public String toString(){
  return "\t文g?"+new String(this.fileName).trim()
  +"\t文g大小:"+this.fileSize
  +"\t文g位移:"+this.offSet;
  }}
  
  六、PakUtilc(j2se版)Q?/B>
  
  PakUtil.java
  package cn.org.matrix.gmatrix.gameLab.util.pak;import java.io.*;
  import java.util.Vector;
  /** * Pak工具c?* 功能Q?BR>  *1.多个png囄合成一个Pak文gQƈ使用单的加减加密法对其进行加密;
  * 2.从Pak文g中取出png囄Q构造byte数组Q可以用来构造Image对象Q或者写为文?* @author cleverpig * */public class PakUtil {
  public PakUtil(){
  }
  /**
  * q回文g长度
  * @param filePath 文g路径
  * @return 文g长度
  */
  private long getFileSize(String filePath){
  File file=new File(filePath);
  return file.length();
  }
  /**
  * q回文g?BR>  * @param filePath 文g路径
  * @return 文g?BR>  */
  
  private String getFileName(String filePath){
  File file=new File(filePath);
  return file.getName();
  }
  /**
  * 计算文g位移的v始点
  * @return 文g位移的v始点
  */
  private long workOutOffsetStart(PakHeader header){
  //计算出文件头+文gtable的长?BR>  return PakHeader.size()+header.getNumFileTableEntries()*PakFileTable.size();
  }
  /**
  * 计算文g位移
  * @param fileIndex 文g序号
  * @param lastFileOffset 上一个文件位U?BR>  * @return 文g在pak文g中的位移
  */
  private long workOutNextOffset(long sourceFileSize,long lastFileOffset){
  return lastFileOffset+sourceFileSize;    
  }
  /**
  * 生成文gtable
  * @param sourceFileName 源文件名
  * @param sourceFileSize 源文仉?BR>  * @param currentFileOffset 当前文g位移
  * @return 生成的PakFileTable对象
  */    
  private PakFileTable generateFileTable(String sourceFileName,
  long sourceFileSize,long currentFileOffset){
  PakFileTable ft=new PakFileTable();
  ft.setFileName(sourceFileName.toCharArray());
  ft.setFileSize(sourceFileSize);
  ft.setOffSet(currentFileOffset);
  return ft;
  }
  /**
  * char字符数组写入到DataOutputStream?BR>  * @param toWriteCharArray 被写入的char数组
  * @param dos DataOutputStream
  * @throws Exception
  */    
  private void writeCharArray(char[] toWriteCharArray,DataOutputStream dos) throws Exception{
  for(int i=0;i<toWriteCharArray.length;dos.writeChar(toWriteCharArray[i]),i++);
  }        
  /**
  * 使用文g头中的密码对数据q行加密
  * @param buff 被加密的数据
  * @param buffLength 数据的长?BR>  * @param header 文g?BR>  */
  private void encryptBuff(byte[] buff,int buffLength,PakHeader header){
  for(int i=0;i<buffLength;i++){
  switch(header.getCipherAction()){
  case PakHeader.ADDITION_CIPHERACTION:
  buff[i]+=header.getCipherValue();
  break;
  case PakHeader.SUBTRACT_CIHOERACTION:
  buff[i]-=header.getCipherValue();
  break;
  }
  }
  }
  /**
  * 使用文g头中的密码对数据q行解密
  * @param buff 被解密的数据
  * @param buffLength 数据的长?BR>  * @param header 文g?BR>  */
  private void decryptBuff(byte[] buff,int buffLength,PakHeader header){
  for(int i=0;i<buffLength;i++){
  switch(header.getCipherAction()){
  case PakHeader.ADDITION_CIPHERACTION:
  buff[i]-=header.getCipherValue();
  break;
  case PakHeader.SUBTRACT_CIHOERACTION:
  buff[i]+=header.getCipherValue();
  break;
  }
  }
  }
  /**
  * 制作Pak文g
  * @param sourceFilePath 源文件\径数l?BR>  * @param destinateFilePath 目的文g路径QPak文gQ?BR>  * @param cipherAction 密码行ؓ
  * @param cipherValue 密码
  * @throws Exception
  */
  public void makePakFile(String[] sourceFilePath,
  String destinateFilePath,PakHeader header) throws Exception{
  PakFileTable[] fileTable=new PakFileTable[sourceFilePath.length];
  //计算文g位移起始?BR>  long fileOffset=workOutOffsetStart(header);
  //逐个建立文gtable
  for(int i=0;i<sourceFilePath.length;i++){
  String sourceFileName=getFileName(sourceFilePath[i]);
  long sourceFileSize=getFileSize(sourceFilePath[i]);
  PakFileTable ft=generateFileTable(sourceFileName,sourceFileSize,fileOffset);
  //计算下一个文件位U?BR>  fileOffset=workOutNextOffset(sourceFileSize,fileOffset);
  fileTable[i]=ft;
  }
  //写入文g?BR>  File wFile=new File(destinateFilePath);
  FileOutputStream fos=new FileOutputStream(wFile);
  DataOutputStream dos=new DataOutputStream(fos);
  writeCharArray(header.getSignature(),dos);
  dos.writeFloat(header.getVersion());
  dos.writeLong(header.getNumFileTableEntries());
  dos.writeByte(header.getCipherAction());
  dos.writeByte(header.getCipherValue());
  writeCharArray(header.getUniqueID(),dos);
  dos.writeLong(header.getReserved());
  //写入文gtable
  for(int i=0;i<fileTable.length;i++){
  writeCharArray(fileTable[i].getFileName(),dos);
  dos.writeLong(fileTable[i].getFileSize());
  dos.writeLong(fileTable[i].getOffSet());
  }
  //写入文g数据
  for(int i=0;i<fileTable.length;i++){
  File ftFile=new File(sourceFilePath[i]);
  FileInputStream ftFis=new FileInputStream(ftFile);
  DataInputStream ftDis=new DataInputStream(ftFis);
  byte[] buff=new byte[256];
  int readLength=0;
  while((readLength=ftDis.read(buff))!=-1){
  encryptBuff(buff,readLength,header);
  dos.write(buff,0,readLength);
  }
  ftDis.close();
  ftFis.close();
  }
  dos.close();
  }
  /**
  * 从DataInputStreamdchar数组     * @param dis DataInputStream
  * @param readLength d长度
  * @return char数组
  * @throws Exception
  */
  private char[] readCharArray(DataInputStream dis,int readLength) throws Exception{
  char[] readCharArray=new char[readLength];
  for(int i=0;i<readLength;i++){
  readCharArray[i]=dis.readChar();
  }
  return readCharArray;
  }
  /**
  * 从PAK文g中读取文件头
  * @param dis DataInputStream
  * @return PakHeader
  * @throws Exception
  */
  private PakHeader readHeader(DataInputStream dis) throws Exception{
  PakHeader header=new PakHeader();
  char[] signature=readCharArray(dis,PakHeader.SIGNATURE_LENGTH);
  header.setSignature(signature);
  header.setVersion(dis.readFloat());
  header.setNumFileTableEntries(dis.readLong());
  header.setCipherAction(dis.readByte());
  header.setCipherValue(dis.readByte());
  char[] uniqueID=readCharArray(dis,PakHeader.UNIQUEID_LENGTH);
  header.setUniqueID(uniqueID);
  header.setReserved(dis.readLong());
  return header;
  }
  /**
  * d所有的文gtable
  * @param dis DataInputStream
  * @param fileTableNumber 文g表L
  * @return 文gtable数组
  * @throws Exception
  */
  private PakFileTable[] readFileTable(DataInputStream dis,int fileTableNumber) throws Exception{
  PakFileTable[] fileTable=new PakFileTable[fileTableNumber];
  for(int i=0;i<fileTableNumber;i++){
  PakFileTable ft=new PakFileTable();
  ft.setFileName(readCharArray(dis,PakFileTable.FILENAME_LENGTH));
  ft.setFileSize(dis.readLong());
  ft.setOffSet(dis.readLong());
  fileTable[i]=ft;
  }        
  return fileTable;
  }
  /**
  * 从pak文gd文g到byte数组
  * @param dis DataInputStream
  * @param fileTable PakFileTable
  * @return byte数组
  * @throws Exception
  */
  private byte[] readFileFromPak(DataInputStream dis,PakHeader header,PakFileTable fileTable) throws Exception{
  dis.skip(fileTable.getOffSet()-workOutOffsetStart(header));
  //
  int fileLength=(int)fileTable.getFileSize();
  byte[] fileBuff=new byte[fileLength];
  int readLength=dis.read(fileBuff,0,fileLength);
  if (readLength<fileLength){
  System.out.println("d数据长度不正?);
  return null;
  }
  else{
  decryptBuff(fileBuff,readLength,header);
  return fileBuff;
  }
  }
  /**
  * buffer中的内容写入到文?BR>  * @param fileBuff 保存文g内容的buffer
  * @param fileName 文g?BR>  * @param extractDir 文g导出目录
  * @throws Exception
  */
  private void writeFileFromByteBuffer(byte[] fileBuff,String fileName,String extractDir) throws Exception{
  String extractFilePath=extractDir+fileName;
  File wFile=new File(extractFilePath);
  FileOutputStream fos=new FileOutputStream(wFile);
  DataOutputStream dos=new DataOutputStream(fos);
  dos.write(fileBuff);
  dos.close();
  fos.close();
  }
  /**
  * 从pak文g中取出指定的文g到byte数组Q如果需要的话可以将byte数组写ؓ文g
  * @param pakFilePath pak文g路径
  * @param extractFileName pak文g中将要被取出的文件名
  * @param writeFile 是否需要将byte数组写ؓ文g
  * @param extractDir 如果需要的话可以将byte数组写ؓ文gQextractDir为取出数据被写的目录文g
  * @return byte数组
  * @throws Exception
  */
  public byte[] extractFileFromPak(String pakFilePath,
  String extractFileName,boolean writeFile,String extractDir) throws Exception{
  File rFile=new File(pakFilePath);
  FileInputStream fis=new FileInputStream(rFile);
  DataInputStream dis=new DataInputStream(fis);
  PakHeader header=readHeader(dis);
  PakFileTable[] fileTable=readFileTable(dis,(int)header.getNumFileTableEntries());
  boolean find=false;        int fileIndex=0;
  for(int i=0;i<fileTable.length;i++){
  String fileName=new String(fileTable[i].getFileName()).trim();
  if (fileName.equals(extractFileName)){
  find=true;
  fileIndex=i;
  break;
  }
  }
  if (find==false){
  System.out.println("没有扑ֈ指定的文?);
  return null;        
  }      
  else{
  byte[] buff=readFileFromPak(dis,header,fileTable[fileIndex]);
  if (writeFile){
  writeFileFromByteBuffer(buff,extractFileName,extractDir);
  }            
  else{
  dis.close();
  fis.close();
  }
  return buff;
  }
  }
  /**
  * 从pak文g中取出指定的Pak文g的信?BR>  * @param pakFilePath pak文g路径
  * @return 装蝲文g头和文gtable数组的Vector
  * @throws Exception
  */
  public Vector showPakFileInfo(String pakFilePath) throws Exception{
  File rFile=new File(pakFilePath);
  FileInputStream fis=new FileInputStream(rFile);
  DataInputStream dis=new DataInputStream(fis);
  PakHeader header=readHeader(dis);
  PakFileTable[] fileTable=readFileTable(dis,(int)header.getNumFileTableEntries());        Vector result=new Vector();
  result.add(header);
  result.add(fileTable);
  return result;
  }
  public static void main(String[] argv) throws Exception{
  PakUtil pu=new PakUtil();
  //构造文件头
  char[] signature=new char[PakHeader.SIGNATURE_LENGTH];
  signature=new String("012345").toCharArray();
  char[] uniqueID=new char[PakHeader.UNIQUEID_LENGTH];
  uniqueID=new String("0123456789").toCharArray();
  PakHeader header=new PakHeader();
  header.setSignature(signature);
  header.setNumFileTableEntries(3);
  header.setCipherAction((byte)PakHeader.ADDITION_CIPHERACTION);
  header.setCipherValue((byte)0x0f);
  header.setUniqueID(uniqueID);
  header.setVersion(1.0f);
  header.setReserved(0L);
  String[] filePathArray={"F:\\eclipse3.1RC3\\workspace\\gmatrixProject_j2se\\testFiles\\apple.png",
  "F:\\eclipse3.1RC3\\workspace\\gmatrixProject_j2se\\testFiles\\cushaw.png",
  "F:\\eclipse3.1RC3\\workspace\\gmatrixProject_j2se\\testFiles\\flash.png"};
  String extractFilePath="F:\\eclipse3.1RC3\\workspace\\gmatrixProject_j2se\\testFiles\\test.pak";
  //制作Pak文g
  System.out.println("制作Pak文g...");
  pu.makePakFile(filePathArray,extractFilePath,header);
  System.out.println("制作Pak文g完成");
  //从Pak文g中取出所有的囄文g
  Vector pakInfo=pu.showPakFileInfo(extractFilePath);
  header=(PakHeader)pakInfo.elementAt(0);
  System.out.println("Pak文g信息:");
  System.out.println("文g?");
  System.out.println(header);
  PakFileTable[] fileTable=(PakFileTable[])pakInfo.elementAt(1);
  for(int i=0;i<fileTable.length;i++){
  System.out.println("文gtable["+i+"]:");
  System.out.println(fileTable[i]);
  }
  String restoreDir="F:\\eclipse3.1RC3\\workspace\\gmatrixProject_j2se\\testFiles\\extract\\";
  String restoreFileName=null;
  byte[] fileBuff=null;
  for(int i=0;i<fileTable.length;i++){
  restoreFileName=new String(fileTable[i].getFileName()).trim();
  System.out.println("从Pak文g中取?+restoreFileName+"文g...");
  fileBuff=pu.extractFileFromPak(extractFilePath,restoreFileName,true,restoreDir);
  System.out.println("从Pak文g中取?+restoreFileName+"文g保存?+restoreDir+"目录");
  }
  }}
  
  七、PakUtilc(j2me版)Q?/B>
  
  PakUtil.java
  package cn.org.matrix.gmatrix.gameLab.util.pak;
  import java.io.*;
  import java.util.Vector;
  /** * Pak工具c?* 功能Q?* 从Pak文g中取出png囄Q构造byte数组Q可以用来构造Image对象Q?* @author cleverpig * */public class PakUtil {
  public PakUtil(){
  }
  /**
  * 计算文g位移的v始点
  * @return 文g位移的v始点
  */
  private long workOutOffsetStart(PakHeader header){
  //计算出文件头+文gtable的长?BR>  return PakHeader.size()+header.getNumFileTableEntries()*PakFileTable.size();
  }
  /**
  * 从DataInputStreamdchar数组
  * @param dis DataInputStream
  * @param readLength d长度
  * @return char数组
  * @throws Exception
  */
  private char[] readCharArray(DataInputStream dis,int readLength) throws Exception{
  char[] readCharArray=new char[readLength];
  for(int i=0;i<readLength;i++){
  readCharArray[i]=dis.readChar();
  }
  return readCharArray;
  }
  /**
  * 从PAK文g中读取文件头
  * @param dis DataInputStream
  * @return PakHeader
  * @throws Exception
  */
  private PakHeader readHeader(DataInputStream dis) throws Exception{
  PakHeader header=new PakHeader();
  char[] signature=readCharArray(dis,PakHeader.SIGNATURE_LENGTH);
  header.setSignature(signature);
  header.setVersion(dis.readFloat());
  header.setNumFileTableEntries(dis.readLong());
  header.setCipherAction(dis.readByte());
  header.setCipherValue(dis.readByte());
  char[] uniqueID=readCharArray(dis,PakHeader.UNIQUEID_LENGTH);
  header.setUniqueID(uniqueID);
  header.setReserved(dis.readLong());
  return header;
  }
  /**
  * d所有的文gtable
  * @param dis DataInputStream
  * @param fileTableNumber 文g表L
  * @return 文gtable数组
  * @throws Exception
  */
  private PakFileTable[] readFileTable(DataInputStream dis,int fileTableNumber) throws Exception{
  PakFileTable[] fileTable=new PakFileTable[fileTableNumber];
  for(int i=0;i<fileTableNumber;i++){
  PakFileTable ft=new PakFileTable();
  ft.setFileName(readCharArray(dis,PakFileTable.FILENAME_LENGTH));
  ft.setFileSize(dis.readLong());
  ft.setOffSet(dis.readLong());
  fileTable[i]=ft;
  }
  return fileTable;
  }
  /**
  * 从pak文gd文g到byte数组
  * @param dis DataInputStream
  * @param fileTable PakFileTable
  * @return byte数组
  * @throws Exception
  */    
  private byte[] readFileFromPak(DataInputStream dis,PakHeader header,PakFileTable fileTable) throws Exception{
  dis.skip(fileTable.getOffSet()-workOutOffsetStart(header));
  //
  int fileLength=(int)fileTable.getFileSize();
  byte[] fileBuff=new byte[fileLength];
  int readLength=dis.read(fileBuff,0,fileLength);
  if (readLength<fileLength){
  System.out.println("d数据长度不正?);
  return null;
  }
  else{
  decryptBuff(fileBuff,readLength,header);
  }        
  return fileBuff;
  }
  /**
  * 使用文g头中的密码对数据q行解密
  * @param buff 被解密的数据
  * @param buffLength 数据的长?BR>  * @param header 文g?BR>  */
  private void decryptBuff(byte[] buff,int buffLength,PakHeader header){
  for(int i=0;i<buffLength;i++){
  switch(header.getCipherAction()){
  case PakHeader.ADDITION_CIPHERACTION:
  buff[i]-=header.getCipherValue();
  break;
  case PakHeader.SUBTRACT_CIHOERACTION:
  buff[i]+=header.getCipherValue();
  break;
  }
  }
  }
  /**
  * 从pak文g中取出指定的文g到byte数组
  * @param pakResourceURL pak文g的资源\?BR>  * @param extractResourceName pak文g中将要被取出的文件名
  * @return byte数组    
  * @throws Exception
  */    
  public byte[] extractResourceFromPak(String pakResourceURL
  ,String extractResourceName) throws Exception{
  InputStream is=this.getClass().getResourceAsStream(pakResourceURL);
  DataInputStream dis=new DataInputStream(is);
  PakHeader header=readHeader(dis);//
  System.out.println("文g?");//
  System.out.println(header);
  PakFileTable[] fileTable=readFileTable(dis,(int)header.getNumFileTableEntries());//
  for(int i=0;i<fileTable.length;i++){//
  System.out.println("文gtable["+i+"]:");//
  System.out.println(fileTable[i]);//
  }
  boolean find=false;
  int fileIndex=0;
  for(int i=0;i<fileTable.length;i++){
  String fileName=new String(fileTable[i].getFileName()).trim();
  if (fileName.equals(extractResourceName)){
  find=true;
  fileIndex=i;
  break;
  }
  }
  if (find==false){
  System.out.println("没有扑ֈ指定的文?);
  return null;
  }
  else{
  byte[] buff=readFileFromPak(dis,header,fileTable[fileIndex]);
  return buff;
  }
  }
  /**
  * 从pak文g中取出指定的Pak文g的信?BR>  * @param pakResourcePath pak文g资源路径
  * @return 装蝲文g头和文gtable数组的Vector
  * @throws Exception
  */
  public Vector showPakFileInfo(String pakResourcePath) throws Exception{
  InputStream is=this.getClass().getResourceAsStream(pakResourcePath);
  DataInputStream dis=new DataInputStream(is);
  PakHeader header=readHeader(dis);
  PakFileTable[] fileTable=readFileTable(dis,(int)header.getNumFileTableEntries());
  Vector result=new Vector();
  result.addElement(header);
  result.addElement(fileTable);
  return result;
  }
  public static void main(String[] argv) throws Exception{
  PakUtil pu=new PakUtil();
  String extractResourcePath="/test.pak";
  //从Pak文g中取出所有的囄文g
  Vector pakInfo=pu.showPakFileInfo(extractResourcePath);
  PakHeader header=(PakHeader)pakInfo.elementAt(0);
  System.out.println("Pak文g信息:");
  System.out.println("文g?");
  System.out.println(header);
  PakFileTable[] fileTable=(PakFileTable[])pakInfo.elementAt(1);
  for(int i=0;i<fileTable.length;i++){
  System.out.println("文gtable["+i+"]:");
  System.out.println(fileTable[i]);
  }
  String restoreFileName=null;       
  byte[] fileBuff=null;
  for(int i=0;i<fileTable.length;i++){
  restoreFileName=new String(fileTable[i].getFileName()).trim();
  System.out.println("从Pak文g中取?+restoreFileName+"文g数据...");
  fileBuff=pu.extractResourceFromPak(extractResourcePath,restoreFileName);
  System.out.println("从Pak文g中取?+restoreFileName+"文g数据完成");
  }   
   }}
  
  八、源代码使用介:
  
  Pakq程Qj2se版的PakUtiltestFiles目录中的三个png文gPak成ؓtest.pak文g?BR>  UnPakq程Qj2se版的PakUtiltestFiles目录中test.pak文g释放到testFiles\extract目录下;j2me版的PakUtil从res目录中的test.pak文gd出其中所包含?个png文g数据q装入到byte数据Q用来构造Image对象Q大家请q行PakUtilTestMIDlet.java便可看到输出的信息?img src ="http://www.tkk7.com/xpsir/aggbug/21931.html" width = "1" height = "1" />

P 2005-11-30 11:42 发表评论
]]>
3步把您的javaE序转换为webservicehttp://www.tkk7.com/xpsir/articles/21929.htmlPPWed, 30 Nov 2005 03:37:00 GMThttp://www.tkk7.com/xpsir/articles/21929.htmlhttp://www.tkk7.com/xpsir/comments/21929.htmlhttp://www.tkk7.com/xpsir/articles/21929.html#Feedback0http://www.tkk7.com/xpsir/comments/commentRss/21929.htmlhttp://www.tkk7.com/xpsir/services/trackbacks/21929.html  2、写wsdd
  3、发?BR>  
  剩下的就只有调用了wsdl2java
  
  我原来的pȝ是CICS的,对后台封装了一层,现在用webservice再封装一层,前台面Q控Ӟ数据传输Q数据处理统l都可以分开了,?BR>  
  //以下是从|上扄关于AXIS的入门教E?BR>  
  一、Axis安装 1、环?J2SE SDK 1.3 or 1.4: 我?1.4.2 Servlet Container: 我用的Tomcat 5.0
  

  2、到 http://ws.apache.org/Axis/|站下蝲Axis安装?BR>  
  3、解压羃安装包,Axis_UNZIP_PATH\Axis-version\webapps下的Axis包拷贝到TOMCAT_HOME\webapps\下,以下U定Axis_HOMETOMCAT_HOME\webapps\Axis目录
  
  4、启动tomcat,讉Khttp://localhost:8080/Axis 查安装是否成?BR>  
  5、以上步骤执行成功,可以开发webservice例子?BR>  
  Axis支持三种web service的部|和开发,分别为:
  
  1、Dynamic Invocation Interface ( DII)
  
  2、Stubs方式
  
  3、Dynamic Proxy方式
  
  二、编写DII(Dynamic Invocation Interface )方式web服务
  
  1.~写服务端程序HelloClient
  
  public class HelloClient
  {
  public String getName(String name)
  {
  return "hello "+name;
  }
  }
  
  2、将源码拯到Axis_HOME下,重命名ؓ HelloClient.jws
  
  3、访问连接http://localhost:8080/Axis/HelloClient.jws?wsdlQ页面显CAxis自动生成的wsdl
  
  4、编写访问服务的客户?TestHelloClient.java
  
  import org.apache.Axis.client.Call;
  import org.apache.Axis.client.Service;
  import javax.xml.namespace.QName;
  import javax.xml.rpc.ServiceException;
  import java.net.MalformedURLException;
  import java.rmi.RemoteException;
  
  public class SayHelloClient2
  {
  public static void main(String[] args)
  {
  try
  {
  String endpoint =
  "http://localhost:8080/Axis/HelloClient.jws";
  
  Service service = new Service();
  Call call = null;
  
  call = (Call) service.createCall();
  
  call.setOperationName(new QName(
  "http://localhost:8080/Axis/HelloClient.jws",
  "getName"));
  call.setTargetEndpointAddress
  (new java.net.URL(endpoint));
  
  String ret = (String) call.invoke(new Object[]
  {"zhangsan"});
  System.out.println("return value is " + ret);
  }
  catch (Exception ex)
  {
  ex.printStackTrace();
  }
  }
  }
  
  三、编写Dynamic Proxy方式讉K服务
  
  1、编写部|服务端E序Q同上边DII方式Q本ơ仍使用上边部v的HelloClient
  
  2、编写代理接?BR>  
  public interface HelloClientInterface
  extends java.rmi.Remote
  {
  public String getName(String name)
  throws java.rmi.RemoteException;
  }
  
  3、编写ƈ执行客户端程序TestHelloClient.java
  
  import javax.xml.rpc.Service;
  import javax.xml.rpc.ServiceFactory;
  import java.net.URL;
  import javax.xml.namespace.QName;
  
  public class TestHelloClient
  {
  public static void main(String[] args)
  {
  try
  {
  String wsdlUrl =
  "http://localhost:8080/Axis/HelloClient.jws?wsdl";
  String nameSpaceUri =
  "http://localhost:8080/Axis/HelloClient.jws";
  String serviceName = "HelloClientService";
  String portName = "HelloClient";
  
  ServiceFactory serviceFactory =
  ServiceFactory.newInstance();
  Service afService =
  serviceFactory.createService(new URL(wsdlUrl),
  new QName(nameSpaceUri, serviceName));
  HelloClientInterface proxy = (HelloClientInterface)
  afService.getPort(new QName(
  nameSpaceUri, portName),
  HelloClientInterface.class);
  System.out.println
  ("return value is "+proxy.getName("john") ) ;
  }catch(Exception ex)
  {
  ex.printStackTrace() ;
  }
  }
  }
  
  四、编写wsdd发布web服务Q编写stub client讉Kweb服务
  
  1、编写服务端E序server,SayHello.javaQ编译server.SayHello.java
  package server;
  public class SayHello
  {
  public String getName(String name)
  {
  return "hello "+name;
  }
  }
  
  2.~写LogHandler.java
  import org.apache.Axis.AxisFault;
  import org.apache.Axis.Handler;
  import org.apache.Axis.MessageContext;
  import org.apache.Axis.handlers.BasicHandler;
  
  import java.util.Date;
  
  public class LogHandler
  extends BasicHandler
  {
  public void invoke
  (MessageContext msgContext)
  throws AxisFault
  {
  /** Log an access each time
  we get invoked.
  */
  try {
  Handler serviceHandler
  = msgContext.getService();
  
  Integer numAccesses =
  (Integer)serviceHandler.getOption("accesses");
  if (numAccesses == null)
  numAccesses = new Integer(0);
  numAccesses = new Integer
  (numAccesses.intValue() + 1);
  Date date = new Date();
  String result =
  date + ": service " +
  msgContext.getTargetService() +
  " accessed " + numAccesses + " time(s).";
  serviceHandler.setOption
  ("accesses", numAccesses);
  System.out.println(result);
  } catch (Exception e)
  {
  throw AxisFault.makeFault(e);
  }
  }
  }
  
  3、编写wsdd文g
  
  deploy.wsdd
  <deployment xmlns=
  "http://xml.apache.org/Axis/wsdd/"
  xmlns:java=
  "http://xml.apache.org/Axis/wsdd/providers/java">
  <handler name="print" type="java:LogHandler"/>
  <service name="sayhello"
  provider="java:RPC">
  <requestFlow>
  <handler type="print"/>
  </requestFlow>
  <parameter name="className"
  value="server.SayHello"/>
  <parameter name="allowedMethods"
  value="*"/>
  </service>
  </deployment>
  
  3、将~译后的文g拯到Axis_HOME/WEB-INF/classes下,如:D:\tomcat\webapps\Axis\WEB-INF\classes
  
  4、发布服务:
  
  java org.apache.Axis.client.AdminClient deploy.wsdd
  
  5、生成client stub文g
  
  a:方式1
  
  SayHello.java拯到Axis_HOME/下,重命名ؓSayHello.jwsQ?BR>  
  执行下面的命令生存client stub
  
  java org.apache.Axis.wsdl.WSDL2Java
  -p client http://localhost:8080
  /Axis/services/SayHello.jws?wsdl
  
  b:方式2
  
  执行如下命o生成SayHello.wsdl
  
  java org.apache.Axis.wsdl.Java2WSDL
  -oSayHello.wsdl -lhttp://localhost:8080
  /Axis/services/SayHello -nsayhello server.SayHello
  
  执行如下命o生成client stub
  
  java org.apache.Axis.wsdl.WSDL2Java
  SayHello.wsdl -p client
  
  生成的stub client文g列表为:
  
  1.SayHello.java
  
  2.SayHelloService.java?BR>  
  3.SayHelloServiceLocator.java
  
  4.SayHelloSoapBindingStub.java
  
  6、编写客LE序Q编译ƈ执行
  
  public class SayHelloClient
  {
  public static void main(String[] args)
  {
  try
  {
  SayHelloService service = new client.
  SayHelloServiceLocator();
  client.SayHello_PortType
  client = service.getSayHello();
  String retValue=client.getName("zhangsan");
  System.out.println(retValue);
  }
  catch (Exception e)
  {
  System.err.println
  ("Execution failed. Exception: " + e);
  }
  }
  }
  
  您也可以写server-config.wsdd
  <?xml version="1.0" encoding="UTF-8"?>
  <deployment xmlns="http://xml.apache.org/axis/wsdd/"
  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <globalConfiguration>
  
  <parameter name="adminPassword" value="admin"/>
  <parameter name="attachments.implementation"
  value="org.apache.axis.attachments.AttachmentsImpl"/>
  <parameter name="sendXsiTypes" value="true"/>
  <parameter name="sendMultiRefs" value="true"/>
  <parameter name="sendXMLDeclaration" value="true"/>
  <parameter name="axis.sendMinimizedElements" value="true"/>
  
  <requestFlow>
  <handler type="java:org.apache.axis.handlers.JWSHandler">
  <parameter name="scope" value="session"/>
  </handler>
  
  <handler type="java:org.apache.axis.handlers.JWSHandler">
  <parameter name="scope" value="request"/>
  <parameter name="extension" value=".jwr"/>
  </handler>
  
  </requestFlow>
  
  </globalConfiguration>
  <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
  <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
  <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
  <handler name="print" type="java:stub.LogHandler"/>
  
  <service name="sayhello" provider="java:RPC">
  <requestFlow>
  <handler type="print"/>
  </requestFlow>
  <parameter name="className"  value="stub.server.SayHello"/>
  <parameter name="allowedMethods" value="*"/>
  </service>
  
  <transport name="http">
  <requestFlow>
  <handler type="URLMapper"/>
  <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
  </requestFlow>
  </transport>
  <transport name="local">
  <responseFlow>
  <handler type="LocalResponder"/>
  </responseFlow>
  </transport>
  </deployment>

P 2005-11-30 11:37 发表评论
]]>
վ֩ģ壺 һ234 | պһ| ҹ޾ƷƬ| avƬvrһ | ޾ƷɫƵ߹ۿԴ | һƵ| պav| ĻѸƵ| һպĻ| jizz18Ƶ| ޾Ʒɫҹרպ| йƷһëƬѲ| ?V?V˵| Ʒ1024| С˵ͼƬ| ձ߹ۿ| 2017| ޾Ʒ| AVר| պAAƬѹۿ | ˾Ʒ˳| ˬˬˬƵ| av뾫Ʒַ| vƬѲ| ww߹Ƶѹۿw| þþƷž޾Ʒ| 18ۿƵ| ƷƬva| 18վѹۿ| þþƷѹۿ97| ҳ߹ۿ| ëƬѹۿ| ձѾƷһ| ޹Ƭ߹ۿ| Ƶ߲| 鵺̳ƷƵվ | ѾƷ99þùۺϾƷ| ޹Ƶ| ׾Ʒһ| ˾þվ| ۺһ뾫Ʒ|