2005年03月29日

作者: 车东 Email: chedongATbigfoot.com/chedongATchedong.com

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
http://www.chedong.com/tech/cms.html

关键词:”content manage system” cms 内容管理系统

内容摘要:

内容管理系统概述


内容管理系统是一个很泛的概念:从商业门户网站的新闻系统到个人的Weblog都可以称作发布系统。

但无论如何,在发布系统选型之前,首先了解自己的实际需求是最重要的:想根据现成系统将自己的需求硬往上照搬是非常不可取的。访问量,权限控制和各种功能需求。每个模块和功能自己都比较清晰一点以后,再去网上找找类似的实现:你会发现其实每个环节到目前上都有比较成熟的实现了,而且还在不断完善和发展中,如果没有:你的需求太特殊,或者可以尝试分解成更小的系统组合实现。

内容管理系统被分离成以下几个层面:各个层面优先考虑的需求不同

  1. 后台业务子系统管理(管理优先:内容管理):新闻录入系统,BBS论坛子系统,全文检索子系统等,针对不同系统的方便管理者的内容录入:所见即所得的编辑管理界面等,清晰的业务逻辑:各种子系统的权限控制机制等;
  2. Portal系统(表现优先:模板管理):大部分最终的输出页面:网站首页,子频道/专题页,新闻详情页一般就是各种后台子系统模块的各种组合,这种发布组合逻辑是非常丰富的,Portal系统就是负责以上这些后台子系统的组合表现管理;
  3. 前台发布(效率优先:发布管理):面向最终用户的缓存发布,和搜索引擎spider的URL设计等……

内容管理和表现的分离:很多成套的CMS系统没有把后台各种子系统和Portal分离开设计,以至于在Portal层的模板表现管理和新闻子系统的内容管理逻辑混合在一起,甚至和BBS等子系统的管理都耦合的非常高,整个系统会显得非常庞杂。而且这样的系统各个子系统捆绑的比较死,如果后台的模块很难改变。但是如果把后台各种子系统内容管理逻辑和前台的表现/发布分离后,Portal和后台各个子系统之间只是数据传递的关系:Portal只决定后台各个子系统数据的取舍和表现,而后台的各个子系统也都非常容易插拔。

内容管理和数据分发的分离:需要要Portal系统设计的时候注意可缓存性(Cache Friendly)性设计:CMS后台管理和发布机制,本身不要过多考虑“效率”问题,只要最终页面输出设计的比较Cacheable,效率问题可通过更前端专门的缓存服务器解决。

此外,就是除了面向最终浏览器用户外,还要注意面向搜索引擎友好(Search engine Friendly)的URL设计:通过URL REWRITE转向或基于PATH_INFO的参数解析使得动态网页在链接(URI)形式上更像静态的目录结构,方便网站内容被搜索引擎收录;

---------------    ---------------     ---------------                    
|新闻管理子系统| | BBS论坛子系统| | 商城子系统 |
--------------- --------------- ---------------
| \ / | \ / 内
| ----------|--- \ / 容 <== 业务子系统(零件生产)
| / | \ \ / 管
--------------- | --------------- 理
|专题制作子系统| | |全文检索子系统|
--------------- | ---------------
\ | /
-------------------------|---------------------------------------------
\ | / 频
--------------- 道 <== Portal系统(产品组装)
| Portal 系统 | 管
--------------- 理
|
-------------------------|---------------------------------------------
| 前
| 台 <== 发布系统(分发代理)
--------------- 发
|前台发布系统 | 布
---------------
/ \
/ \
--------------- ---------------
| 用户浏览器 | |Search Engine|
--------------- ---------------

这里,我把在内容发布系统选型中找到的一些资料总结如下:

    内容管理系统的选型

    关键词:CMS Content Manage System

    CMS行业研究
    http://www.cmswatch.com
    http://www.cmsreview.com
    http://www.cmsinfo.org

    CMS讨论邮件列表
    http://www.cms-list.org

    商业软件和开源项目列表:
    http://directory.google.com/Top/Computers/Software/Internet/Site_Management/Content_Management/

    推荐:基于XML的发布框架
    http://cocoon.apache.org/

    具体实现复杂程度可能会根据需求的不同而不同,但越是大型的系统越是需要分工:将内容(数据),表现(模板)和应用逻辑(程序)尽可能分离和对这3 者的管理。

    Portal—门户系统
    Open source Projects:
    http://jportlet.sourceforge.net/
    Apache Software Foundation: Jakarta JetSpeed 1.3
    JetSpeed home page: http://jakarta.apache.org/jetspeed/site/index.html
    JetSpeed Portlet API: http://cvs.apache.org/viewcvs/jakarta-jetspeed/proposals/portletAPI/
    http://www.liferay.com/home/index.jsp
    http://basicPortal.com/
    http://www.jahia.org/
    http://jporta.sourceforge.net/

    商业软件:
    BEA WebLogic Portal – http://edocs.bea.com/wlp/docs81/javadoc/com/bea/Portal/model/Portlet.html
    IBM Websphere Portal – http://www.software.ibm.com/wsdd/zones/Portal/
    Oracle Portal Developer Kit – http://Portalstudio.oracle.com/

    其它:
    PSML – http://jakarta.apache.org/jetspeed/site/psml.html
    BEA: Web Logic Portal 4.0 http://www.bea.com/products/weblogic/Portal/index.shtml
    IBM: WebSphere Portal 2.1 http://www-4.ibm.com/software/webservers/Portal/
    iPlanet: iPlanet Portal Server 3.0 http://www.iplanet.com/products/iplanet_Portal/home_Portal.html
    Oracle: Oracle 9i Portal http://www.oracle.com/ip/deploy/ias/Portal/index.html
    SAP Portal: http://www.iviewstudio.com
    Epicentric Portal: http://www.epicentric.com/solutions/products/efs/

    参考:
    Wafer:Java开发框架研究
    http://www.waferproject.org/index.html

    门户(Portal)系统相关开发框架:
    http://udoo.51.net/mt/archives/000011.html

    广告管理系统

    关键词:ad server

    广告系统和内容的分离,可以大大降低系统之间的关联度。
     
    专业行业研究网站:
    http://adres.internet.com

    相关厂商和开源项目:
    http://directory.google.com/Top/Computers/Programming/Languages/PHP/Scripts/Ad_Management/?il=1
    http://directory.google.com/Top/Computers/Software/Internet/Servers/Advertising/?tc=1
    http://www.jspin.com/home/apps/admanage?cob=winedit
    http://www.scriptdex.com/dex/php_ad_management.shtml

    推荐:
    http://www.phpadsnew.com/ 功能性比较强
    http://oasis.sourceforge.net/ 免费 基于日志记录和定期导入MYSQL统计,可以负载50万请求/每小时 以上

    如果看重广告的第3方特性,可以选择第三方服务:
    http://www.doubleclick.net/
    http://www.allyes.com/

    论坛/社区系统

    关键词: BBS FORUM

    论坛软件介绍:
    http://directory.google.com/Top/Computers/Internet/Web_Design_and_Development/Message_Boards/

    推荐:
    http://www.phpBB.com PHP + MySQL open source
    http://www.vbulletin.com/order/ PHP + MySQL  有付费的商业支持85-160$

    http://www.jivesoftware.com/products/pricing.jsp 商业论坛系统,1000$-2500$ 有知识库扩展应用
    http://yazd.yasna.com/features.jsp 基于 java

    所见即所得(WYSIWYG)编辑器

    在内容的录入管理方面,所见即所得是比较重要的,这样可以大大简化对系统中布局排版的需求。
    基于浏览器的WYSIWYG(所见即所得)编辑器是CMS设计中,编辑工具的主要考虑方面。目前主要是通过JAVASCRIPT调用IE或其他浏览器的内置方法实现。其中基于IE5.5浏览器的实现最为简洁。这里有一个完整的例子:
    Building a WYSIWYG HTML Editor Part 1/2
    Building a WYSIWYG HTML Editor Part 2/2

    主要功能:

    • 能够通过JAVASCRIPT实现的基本功能:加粗,斜体字,居中,添加链接,添加图片,模式切换:HTML和文本模式的切换,
    • Word垃圾代码过滤
    • 图片上载接口:图片上载最好通过其他独立模块实现。

    选型指标:

    • 不依赖服务器端代码:只通过JAVASCRIPT或客户端控件实现代码,可以保证以后系统迁移的方便。
    • WORD垃圾代码过滤

    可视化编辑器大全:
    http://www.bris.ac.uk/is/projects/cms/ttw/ttw.html

    推荐:
    http://www.aine.be/aynhtml/

    图片/文件上传组建

    图片和文件等非结构化数据还是分别使用另外的服务解决比较好。这样可以大大简化CMS本身的复杂程度。

    推荐:
    文件上传:
    Apache Commons项目
    http://jakarta.apache.org/commons/

    ImageJ:图片处理缩略图生成和水印等
    http://rsb.info.nih.gov/ij/

    关于Blog系统的选型,目前主流的基于PHP的包括:
    · Nucleus 3.0 www.nucleuscms.org
    · pmachine 2.3 www.pmachine.com
    · b2evolution 0.9.0.3 www.b2evolution.net
    · Serendipity 0.6 www.s9y.org
    · WordPress 1.2 www.wordpress.org
    · bBlog 0.7.3 www.bblog.com
    · pLog 0.3.1 www.plogworld.org
    · Simplog .9 www.simplog.org
    · Textpattern 1.18a www.textpattern.com

原来一直用tomcat4,就直接在server.xml里写<context />配虚拟目录。
可是后来出了tomcat5,就一直没搞明白该在哪里写才对。
今天又搜了很多资料,都没有明白的阐述,只好看tomcat文档,经过摸索终于得出正确结论。
1、server.xml里不再管虚拟目录了,只能配虚拟主机host,但是要记住这个host的名字,一般是localhost。另外还要记住当前的tomcat服务名,默认是<Service name=”Catalina”>,即Catalina
2、在tomcat的conf目录建立两级子目录,第一级是服务名,即Catalina,第二级是主机名,即localhost。
3、在localhost目录下,建立你想要的虚拟目录.xml文件,比如bbs.xml,那么将来在浏览器里输入http://localhost/bbs才能找到你的目录,即文件名要与将来用的目录同名。
4、在这个xml文件里写虚拟目录的配置:比如
<Context docBase=”c:/tomcat55/webapps/mybbs” debug=”0″ reloadable=”true” crossContext=”true” />
 相比原来的写法,就是不要了path,因为path就是你的xml文件名。docBase与tomcat目录或host的appBase目录无关。
5、重新启动tomcat5,输入网址试试看,成功了别忘感谢我。
附:默认端口号8080还是在server.xml里修改。

http://blog.csdn.net/xiaozhen/archive/2005/02/14/287689.aspx

2005年03月25日

引言

Web框架一般是通过一个Servlet提供统一的请求入口,将指定的资源映射到这个servlet,在这个servlet中进行框架的初始化配置,访问Web页面中的数据,进行逻辑处理后,将结果数据与的表现层相融合并展现给用户。WEB框架想要在符合Servlet规范的容器中运行,同样也要符合Servlet规范。
将一个WEB框架注入到一个servlet中,主要涉及到Servlet规范中以下部分:
Ø         部署描述符
Ø         映射请求到Servlet
Ø         Servlet生存周期
Ø         请求分发

 Servlet相关技术规范简介

部署描述符

部署描述符就是位于WEB应用程序的/WEB-INF目录下的web.xml的XML文件,是WEB应用程序不可分割的部分,管理着WEB应用程序的配置。部署描述符在应用程序开发人员,应用程序组装人员,应用程序部署人员之间传递WEB应用程序的元素和配置信息。
在WEB应用程序的部署描描述符中以下类型的配置和部署信息是所有的servlet容器必须支持的:
Ø         ServletContext初始化参数
Ø         Session配置
Ø        Servlet声明
Ø        Servlet映射
Ø        应用程序生存周期监听器
Ø         Filter的定义和映射
Ø         MIME类型的映射
Ø        欢迎文件列表
Ø        错误文件列表
出现在部署描述符中的安全信息可以不被支持,除非这个Servlet容器是J2EE规范实现的一部分。
所有正确的WEB应用程序部署描述符(Servlet2.3规范)必须包含下面的DOCTYPE声明:
<!DOCTYPE web-app PUBLIC “-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN” “http://java.sun.com/dtd/web-app_2_3.dtd”>
 
下面说明在部署描述符中是如何进行Servlet声明和映射的,这个DTD的全部内容可以在下面这个地址获得:
http://java.sun.com/dtd/web-app_2_3.dtd
在这个DTD中有关Servlet声明和映射和映射的部分如下:
<!–
The servlet element contains the declarative data of a
servlet. If a jsp-file is specified and the load-on-startup element
is present, then the JSP should be precompiled and loaded.
Used in: web-app
–>
<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,
(servlet-class|jsp-file), init-param*, load-on-startup?, runas?,
security-role-ref*)>
<!–
The servlet-class element contains the fully qualified class name
of the servlet.
Used in: servlet
–>
<!ELEMENT servlet-class (#PCDATA)>
<!–
The servlet-mapping element defines a mapping between a servlet
and a url pattern
Used in: web-app
–>
<!ELEMENT servlet-mapping (servlet-name, url-pattern)>
<!–
The servlet-name element contains the canonical name of the
servlet. Each servlet name is unique within the web application.
Used in: filter-mapping, servlet, servlet-mapping
–>
<!ELEMENT servlet-name (#PCDATA)>
根据以上DTD,一个典型的Servlet的声明的格式如下:
<servlet>
<servlet-name>catalog</servlet-name>
<servlet-class>com.mycorp.CatalogServlet</servlet-class>
<init-param>
<param-name>catalog</param-name>
<param-value>Spring</param-value>
</init-param>
</servlet>
一个典型的Servlet映射如下:
<servlet-mapping>
<servlet-name>catalog</servlet-name>
<url-pattern>/catalog/*</url-pattern>
</servlet-mapping>
 
通过上面的方法,我们就声明了一个名称为catalog的Servlet,它的实现类为com.mycorp.CatalogServlet,并且带有一个catalog参数,参数值为Spring,所有向/catalog/*的请求都被映射到名称为catalog的Servlet。
 

映射请求到Servlet

接收到一个请求后,WEB容器要确定转到哪一个WEB应用程序。被选择的应用程序的最长的上下文路径必须和请求的URL开始部分匹配。URL匹配的部分是映射到Servlet的上下文路径。
WEB容器下一步必须按照下面的程序定位处理请求的Servlet。
用来映射到Servlet的路径是请求对象的URL减去上下文的路径。下面的URL路径映射规则按顺序执行,容器选择第一个成功的匹配并且不在进行下一个匹配:
Ø        容器试着对请求的路径和Servlet的路径进行精确匹配,如果匹配成功则选择这个Servlet。
Ø        容器会循环的去试着匹配最长的路径前缀:把’/’当作路径分隔符,按照路径树逐级递减的完成,选择最长匹配的Servlet。
Ø        如果这个URL路径的最后有扩展名(比如.jsp),Servlet容器会试着匹配处理这个扩展名的Servlet。
Ø        如果前面的没有与前面三条规则相匹配的Servlet,容器会试着为资源请求提供适当的资源,如果有“默认”的Servlet定义给这个应用程序,那么这个Servlet会被使用。
 
容器必须使用一个大小写敏感的匹配方式。
在部署描述符中,用下面的语法定义映射:
Ø        一个以’/’开始并且以’/*’结束的字符串用来映射路径。
Ø        一个以’*.’为前缀的字符串用来映射扩展名。
Ø        一个只包含’/’的字符串指示着这个应用程序“默认”的Servlet,在这种情况下,servlet的路径是请求的URI减去上下文路径,并且这个路径是null。
Ø        所有其他的字符只用来精确匹配。
如果容器内置JSP容器,那么*.jsp被映射到这个容器,并允许JSP页面在需要的时候被执行。这种映射叫做隐含映射。如果WEB应用程序中定义了*.jsp的映射,那么这个映射有比隐含映射高的优先级。
WEB容器允许显式的声明隐含映射以获得优先级,例如,*.shtml的隐含映射可以在服务器上被映射为包含功能。
映射实例:
path pattern
servlet
/foo/bar/*
servlet1
/baz/*
servlet2
/catalog
servlet3
*.bop
servlet4
下面是实际请求映射的结果
incoming path
servlet handling request
/foo/bar/index.html
servlet1
/foo/bar/index.bop
servlet1
/baz
servlet2
/baz/index.html
servlet2
/catalog
servlet3
/catalog/index.html
“default” servlet
/catalog/racecar.bop
servlet4
/index.bop
servlet4
请注意/catalog/index.html 和/catalog/racecar.bop这两种情况,因为是精确匹配,所以并没有映射到处理/catalog的servlet。
 

Servlet生存周期

在介绍Servlet的生存周期之前需要先介绍一下javax.servlet.Servlet接口。所有的Servlet必须实现或者间接实现这个借口,我们通常可以通过继承javax.servlet.GenericServlet或者javax.servlet.http.HttpServlet.类来实现这个接口。
这个接口中定义了下面5种方法:
public void init(ServletConfig config);
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res);
public String getServletInfo();
public void destroy() ;
 
init()方法
init方法在容器器装入Servlet 时执行,Servlet容器在实例化后只调用一次init方法, init方法必须在servlet接收到任何请求之前完成。
这个方法通常用来进行一些资源的管理和初始化,如从配置文件读取配置数据,读取初始化参数,初始化缓冲迟等一次性的操作。
getServletConfig()方法
GetServletConfig方法返回一个 ServletConfig 对象,该对象用来返回这个Servlet的初始化信息和启动参数。返回的是传递到init方法ServletConfig。
Service()方法
Service方法是应用程序逻辑的进入点,是servlet方法的核心,WEB容器调用这个方法来响应进入的请求,只有servlet成功被init()方法初始化后,Service方法才会被调用。
getServletInfo()方法
这个方法返回一个字符串对象,提供有关servlet 的信息,如作者、版本等。
destroy()方法
destroy方法在容器移除Servlet 时执行,同样只执行一次。这个方法会在所有的线程的service()方法执行完成或者超时后执行,调用这个方法后,容器不会再调用这个servlet的方法,也就是说容器不再把请求发送给这个Servlet。      这个方法给servlet释放占用的资源的机会,通常用来执行一些清理任务。
 
这个接口定义了初始化一个servlet,服务请求和从容器中移除servlet的方法。他们按照下面的顺序执行:
1.         servlet被实例化后,用init方法进行初始化
2.         客户端的任何请求都调用service方法
3.         servlet被移除服务,调用destroy方法销毁

servlet的生存周期如下图:
 

请求分发

请求分发可以让一个Servlet把请求分配到另外一个资源,RequestDispatcher接口提供了实现他的机制。可以通过下面两种方式从ServletContext中获得一个实现了RequestDispatcher接口的对象:
• getRequestDispatcher
• getNamedDispatcher
getRequestDispatcher方法接受一个指向目标资源的URL路径
RequestDispatcher rd = getServletContext().getRequestDispatcher(“/catalog”);
 
 
getNamedDispatcher方法接受一个Servlet名称参数,这个名称是在部署描述符中<servlet-name>元素指定的那个名称。
RequestDispatcher rd = getServletContext().getNamedDispatcher (“catalog”);
 
 
RequestDispatcher接口有两个方法,允许你在调用的servlet完成初步处理后把请求响应分配到另外一个资源,
forward()方法:
public void forward(ServletRequest request, ServletReponse reponse) throws SwerletException,IOException
forward方法上让你把请求转发到另外的Servlet或者jsp或者html等资源,由这个资源接下来负责响应。如:
RequestDispatcher rd = getServletContext().getRequestDispatcher(“/catalog”);
rd. forward(request,response);
 
include()方法:
public void include (ServletRequest request, ServletReponse reponse) throws SwerletException,IOException
include方法让你的Servlet响应中包含另外一个资源生成内容
RequestDispatcher rd = getServletContext().getRequestDispatcher(“/catalog”);
rd. include(request,response);
 
 

结合WebWork的具体分析

WebWork是由OpenSymphony组织开发实现MVC模式的J2EE Web框架。在介绍完servlet规范的相关内容后,我们看看WebWork是如何注入到一个Servlet中的,假设我们有一个上下文环境为“/WebWorkdDemo”的WEB应用。

部署描述符

在部署描述符中,我们需要进行如下配置:
<servlet>
<servlet-name>webwork</servlet-name>
<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>
</servlet>
……
<servlet-mapping>
<servlet-name>webwork</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
我们声明了一个名为webwork的Servlet和*.action到这个Servlet的映射,这个Servlet就是webwork中的controller,担任MVC框架中非常重要的控制器角色。

映射请求到Servlet

在XWork的配置文件xwork.xml中有如下片段:
<action name=”demo” class=” webworkapp.DemoAction”>
    <result name=”success” type=”dispatcher”>
       <param name=”location”>/demo.jsp</param>
    </result>
</action>
这样我们由http://localhost:8080/WebWorkDemo/demo.action这个URL向服务器发出请求时,WEB容器首先确定转到哪一个WEB应用程序,容器将请求URL和上下文环境进行匹配后知道将转到/WebWorkdDemo这个WEB应用。
接下来容器会在/WebWorkdDemo这个应用的部署描述符中进行查找处理这个请求的servlet,根据后缀*.action找到名称为webwork这个Servlet,这样根据部署描述符,这个请求被映射到webwork中的controller组件com.opensymphony.webwork.dispatcher.ServletDispatcher来处理。这个担任控制器组件的Servlet在他的service()方法中在根据请求的路径解析出对应的action来进行处理。
通过上面的的处理,实现了将web请求转到了webwork中的控制器ServletDispatcher。不止是webwork,实现MVC的web框架都需要进行类似的处理来将web请求转入到自己的controller.以便进行进一步的处理。

Servlet生存周期

ServletDispatcher这个Servlet的存周期可以如下:
1)      在服务器启动的时候,容器首先实例化ServletDispatcher
2)        实例化完成后,将调用init()方法,在init方法中执行了以下操作:
Ø         初始化Velocity引擎
Ø         检查是否支持配置文件重新载入功能。如果支持,每个request请求都将重新装载xwork.xml配置文件,在开发时非常方便。
Ø         设置一些文件上传的信息,比如:上传临时目录,上传的最大字节等。
3)      每次请求都调用service()方法,在service方法中执行了以下方法
Ø         通过request请求取得action的命名空间
Ø         根据servlet请求的Path,解析出要调用该请求的Action的名字(actionName)
Ø         创建Action上下文(extraContext),遍历HttpServletRequest、HttpSession、ServletContext 中的数据,并将其复制到Webwork的Map实现中,至此之后,所有数据操作均在此Map结构中进行,从而将内部结构与Servlet API相分离。
Ø         以上述信息作为参数,调用ActionProxyFactory创建对应的ActionProxy实例。ActionProxyFactory 将根据Xwork 配置文件(xwork.xml)中的设定,创建ActionProxy实例,ActionProxy中包含了Action的配置信息(包括Action名称,对应实现类等等)。
Ø         执行proxy的execute()方法
4)      容器移除Servlet 时执行destroy(),在ServletDispatcher这个Servlet中并没有重写destroy方法,在移除Servlet时,将什么也不做。

请求分发

WebWork提供了多种活灵活视图展现方式,例如还是我们上面在xwork.xml中的配置:
<action name=”demo” class=” webworkapp.DemoAction”>
    <result name=”success” type=”dispatcher”>
       <param name=”location”>/demo.jsp</param>
    </result>
</action>
根据以上配置当DemoAction的返回值为”success”时的处理类型为”dispatcher”,当result的type为”dispatcher”时,通过javax.servlet.RequestDispatcher的forward()或include()方法将处理结果和表现层融合后展现给用户
我们可以看看WebWork提供的dispatcher类型Result Type的实现类com.opensymphony .webwork.dispatcher.ServletDispatcherResult中的代码片断:
  HttpServletRequest request = ServletActionContext.getRequest();
  HttpServletResponse response = ServletActionContext.getResponse();
  RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
 
  if (dispatcher == null) {
    response.sendError(404, “result ‘” + finalLocation + “‘ not found”);  
    return;
  }
 
  if (!response.isCommitted() && (request.getAttribute(“javax.servlet.include.servlet_path”) == null)) {
    request.setAttribute(“webwork.view_uri”, finalLocation);
    request.setAttribute(“webwork.request_uri”, request.getRequestURI());
   
    dispatcher.forward(request, response);
  } else {
    dispatcher.include(request, response);
  }
ServletDispatcherResult类的从ServletActionContex中得到HttpServletRequest和HttpServletResponse,然后调用request.getRequestDispatcher(finalLocation)方法得到一个RequestDispatcher实例,如果返回的是null,则输出404页面未找到的错误,否则将调用dispatcher.forward(request, response)或者dispatcher.include(request, response)进行请求分发,将处理结果和表现层融合后展现给用户。
 

结束语

       通过以上的介绍,我们对web框架是如何注入到servlet中有了简单的了解,如果想更深入的研究,可以阅读Servlet规范以及一些成熟框架的源码。
 
                                        written by 绝对零度
                                              email:hongjunshi@gmail.com

看到很多文章在问和答关于java网页汉字乱码的情况,有些甚至认为这是servlet包容器实现上的错误。可是如果读过servlet规格说明书,关于java网页编码的问题就应该迎刃而解了。

编写java网页(servlet\jsp),需要关心response(反馈给客户端的页面)和request(来自客户端的数据)的编码问题。

response的编码可以直接用代码实现。而request的编码怎么办呢?以下是servlet规范书上的文字(我粗略翻译一下吧,不怕见笑):

– 整理自<Java Servlet Specification Version 2.3> SRV.4.9 –

当前,很多浏览器并不发送带有“Content-Type”头信息的字符编码限定符,而由读取HTTP请求的代码来决定字符的编码方式。如果客户端请求未定义编码限定符,则包容器(如tomcat)用于创建request reader和分析POST数据的request的缺省编码方式必须是“ISO-8859-1”。然而,为了向开发者指明客户端没有发送字符编码信息的情况,包容器对getCharacterEncoding方法返回null。

如果客户端不设置字符编码方式,并且request不是按照以上缺省编码方式(iso-8859-1)来编码,则会发生问题。为了解决这个问题,在接口ServletRequest中加入了一个新的方法setCharacterEncoding(String enc)。开发者可以调用这个方法来替换包容器提供的缺省字符编码方式。但是,必须在从request中分析任何POST数据或者读取任何输入之前,调用这个方法。一旦数据已被读取,则调用这个方法将不会影响编码方式。

2005年03月24日

花了2天的时间把机器和软件重新安装了一遍,原来的数据用DVD刻录备份了一下。硬盘上面的数据满满整理中,删除和缩减师姐的个人资料,加入我的资料。

1。本周直到月底的工作是消化以前积累的文档资料,对资料涉及的内容做好笔记和分类整理。

验收目标:读书笔记

2。四月份前2周根据iMan和SmarTeam各个模块的划分和实现方法,制定出整个系统的架构。

验收目标:可行性分析报告,项目开发计划,需求规格说明书,概要设计说明书

3。四月后2周到6月底

完成权限控制模块,产品结构管理模块

2005年03月19日

http://www.sun.com/products-n-solutions/edu/programs/sai/

The Sun Academic Initiative is a program designed to create a collaborative relationship between Sun and academic institutions. Courses delivered through this program will introduce students to Sun Microsystems technologies, prepare them for industry-leading certification, and equip them with marketable IT job skills.

As part of this program, non profit institutions (not individuals) become authorized, enabling those institutions to deliver training on Sun technologies to their faculty, staff and students. In addition, faculty, staff and students can obtain free access to selected online courses through the Sun Learning Center

http://www.jug.edu.cn/index.html

中国大学生JAVA/Solaris协会

校园Java/Solaris协会的成员,将能够享受如下优惠:

1. 高水平的技术交流

校园Java/Solaris协会将会定期的邀请国内外著名IT公司到学校来举办与Java/Solaris技术相关的讲座、研讨会、座谈会,共同讨论 java/Solaris技术的发展方向和应用前景。仅有校园Java/Solaris协会的注册会员方有资格或的邀请参加此类高水平的技术交流。

在2005年,Sun公司将在全国多家软件学院开展免费的Solaris 10培训,仅有校园Java/Solaris协会的注册会员方能够参加到此项培训。此外,Sun大学合作计划有大量与Java/Solaris相关的网上 教程,也要求您注册成为校园Java/Solaris协会会员后方能访问。

2. SCJP考试特惠

Sun Certified java Programmer (SCJP)考试是目前国际上相当热门的一项技术认证考试,对于即将走出校门的大学生来说,拥有SCJP证书能够明显的提高您的就业竞争力。Sun公司正 在和国内众多的IT公司达成协议,将SCJP证书作为招聘Java技术人员的一个资格要求。SCJP考试的原价是人民币1250元,针对参与Sun大学合 作计划院校的校园Java/Solaris协会会员的价格是40美金。学生从学校毕业之后,将不再有资格享受此项优惠。点击此处获得更多信息。

3. 正版软件的免费使用权

我用正版我自豪!校园Java/Solaris协会已经 获得部分公司的授权,该授权以site license的方式允许校园Java/Solaris协会的注册会员能够合法地使用一些著名IT公司开发的正版商用Java开发工具。此外,这些公司还 承诺不定期的向校园Java/Solaris协会的注册会员提供最新版开发工具的试用版。

校园Java/Solaris协会的注册会员,还可以从本站下载使用Sun公司最新发布的Solaris 10操作系统。

为了最大程度地委校园Java/Solaris协会的注册会员提供方便,我们正在对我们的软件下载功能进行调试,计划于2005年4月开通该功能。

4. Java书籍优惠

我们正在 与一些出版机构进行交流,为校园Java/Solaris协会的注册会员提供技术书籍打折等优惠。电子工业出版社已经初步表 明与校园Java/Solaris协会进行合作的意向,具体条款待定。我们也欢迎其他的出版机构与我们联系,共同为校园Java/Solaris协会提供 支持。

5. 全国大学生Java大赛

为了提高中国大学生的Java应用水平,倡导科学的Java开发理念,太阳计算机系统(中国)有限公司将于今年联合多个高校共同举办“Java杯”全国大 学生信息技术大奖赛。参赛者要针对一个特定的实际问题提出自己的解决方案,并通过实际设计、开发、优化该解决方案来展示自己的技术实力。大赛优胜者将获得 丰厚的奖金以及前往美国参加2006年JavaONE大会的机会。

6. 更多的就业机会

为学生Java/Solaris协会做出杰出贡献的注册会员,将在毕业时获得Sun中国技术社区提供的推荐信,为其争取更好的就业机会。Sun公司也会不 定期的向校园Java/Solaris协会的注册会员发布Sun公司内部的招聘信息,组织校园Java/Solaris协会的注册会员到Sun公司参观, 为校园Java/Solaris协会的注册会员提供实习机会。其他对校园Java/Solaris协会提供支持的国内外IT公司也已承诺为校园 java/Solaris协会的注册会员提供类似的优惠。

7. 其他优惠

我们将继续为校园Java/Solaris协会的注册会员争取更多的优惠。如果您是在校大学生,请您立即申请加入校园Java/Solaris协会,并经 常性地返回本网站察看新增加的优惠政策。如果您是愿意为校园Java/Solaris协会提供支持的公司或者是单位,请您与 ecommunity@prc.sun.com联系。

2005年03月15日

elook

2005年03月13日

1应该从基于数据表的设计提高到基于model的设计上来,首先把整个系统的model抽象好,接下来才转化成数据表

2原有系统权限部分必须重新设计,单独做一个权限表出来

3原有树型结构也需要重新设计,结构由于需要经常检索,单独用一个表存储,具体节点的内容用另外的表存储

4增加是否是叶子节点的属性

5业务对象和业务逻辑用EJB来实现,业务对象与数据库之间的关系映射由DAO实现,这样把数据访问层从业务层抽取出来,DAO返回给EJB的是Collections,而不是recordset对象,这样就实现了业务对象跟数据层的解耦,以后如果更改数据库,那么重新实现一遍DAO层就可以了,其他的代码可以完全不用修改。

6Web层用Struts来实现。

7引入版本控制系统,单元测试系统

2005年03月11日

  1. 要有一个职业生涯的规划。首先需要定位自己做什么合适,是做买卖还是做技术,一条路走到黑;当然,做了技术,后来改行也行;

  2. 做技术,就是要做精做深,成为这个行业的这个技术的专家;最好就是去国内的大公司,才能全面学到东西,能够给你培训的机会;如果大公司进不去,先到小公司练技术,找机会再到大公司去镀金,学高深的技术。千万不要自己做产品,要做也是对这个行业熟悉了,再去做。

  3. 积极争取机会。积极争取学习和进步的机会。比如,做技术,就需要多锻炼,多学习,来提高自己的水平。一门技术,只要有机会去学习,都能学的会;要是没有机会,天才也没有办法学到这个技术。柳传志就说,杨元庆就是“哭着喊着要进步”,实际上,就是争取自己的机会;当然,这种强烈的进步欲望,也是领导看重的地方。每一步都走在前面,积累10年,你就有了比其他人更多的机会了。

  4. 积累个人的信誉。从你的职业生涯的第一天,就要按照诚信的原则办事。要做到,当人们提起你的名字的时候,说,这哥们还不错,做事还行。

  5. 注意利用资源。如果你有有钱的亲戚、成功的长辈或者朋友,可以充分利用这些机会,得到更加顺利的发展前景。

  6. 注意财富的不断积累。人生要想得到自由,财富是很关键的。否则,永远仰人鼻息,永远看人脸色。人都是势利眼。今后的家庭、职业生涯,金钱的积累很重要,没有钱,永远不能开张自己的事业,得到更多的机会;财富要做到逐年积累,你才能家庭生活幸福。没有钱是不可能有幸福的家庭的。

  7. 注意人脉的积累。最终,事业要靠在社会上的人脉的资源。要注意认识在你这个行业的人,结交他们,最终他们会成为你事业上的助力。

  8. 寻求贵人相助。要找大老板来帮助你,得到大老板的赏识。想想看,大蛋糕,切一点就够了,小蛋糕,都给你也吃不饱啊。

  9. 多听听成功的前辈和成功的朋友的意见。注意少听家里长辈的意见,尤其是都已经退休的长辈,他们对社会的认识还停留在很久以前,而这个社会已经发生很大的变化呢。最重要的是,长辈有时候会强求你做一些事情,但是,最终的结果他们是不负责的。只有你才能对自己负责。

全文见一个研究生毕业以后的人生规划

 上午

 wordlist1,听录音

manual所有相关的SQL

 下午 实现用户添加删除部分修改
 晚上 实现页面添加删除部分修改