??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲人成人无码网www国产,亚洲宅男天堂在线观看无病毒,亚洲理论电影在线观看http://www.tkk7.com/lijiajia418/category/14434.htmlVicent's blogzh-cnFri, 02 Mar 2007 06:59:28 GMTFri, 02 Mar 2007 06:59:28 GMT60正确优雅的解决用户退出问题——JSP和Struts解决Ҏhttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65541.htmlBinaryBinaryThu, 24 Aug 2006 07:56:00 GMThttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65541.htmlhttp://www.tkk7.com/lijiajia418/comments/65541.htmlhttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65541.html#Feedback0http://www.tkk7.com/lijiajia418/comments/commentRss/65541.htmlhttp://www.tkk7.com/lijiajia418/services/trackbacks/65541.html 注:本文是由 马嘉?/font> 译的javaworld.com上的一名为《Solving the logout problem properly and elegantly》的文章Q原文请参看 Solving the logout problem properly and elegantly ?br />׃2天翻译过后才发现wolfmanchen已经捯先登了,而且译得很准确Q比我的好,^+^Q我q行了修改,在此谢谢wolfmanchen?/strong>
文中所有示例程序的代码可以从javaworld.com中下载,文章后面有资源链接?br />
我看q之后觉得很好,希望对你也有所帮助Q?br />

                             正确优雅的解决用户退出问?br />                                           ------JSP和Struts解决Ҏ

摘要

在一个有密码保护的Web应用当中Q正妥善的处理用户退Eƈ不仅仅只需要调用HttpSession对象的invalidate()ҎQ因为现在大部分览器上都有后退(Back)和前q?Forward)按钮Q允许用户后退或前q到一个页面。在用户退Z个Web应用之后Q如果按了后退按钮Q浏览器把缓存中的页面呈现给用户Q这会用户产生疑惑Q他们会开始担心他们的个h数据是否安全?br />
实际上,许多Web应用会弹Z个页面,警告用户退出时关闭整个览器,以此来阻止用Ld退按钮。还有一些用JavaScriptQ但在某些客L览器中q却不一定v作用。这些解x案大多数实现都很W拙Q且不能保证在Q何情况下?00%有效Q同Ӟ它还要求用户有一定的操作l验?br />
q篇文章以简单的E序CZ阐述了正解决用户退出问题的Ҏ。作者Kevin Le首先描述了一个理想的密码保护Web应用Q然后以CZE序解释问题如何产生q讨决问题的Ҏ。文章虽然是针对JSPq行讨论阐述Q但作者所阐述的概念很Ҏ理解而且能够为其他Web技术所采用。最后最后,作者Kevin Le用Jakarta Struts更ؓ优雅地解决用户退出问题。文中包含JSP和Struts的示例程?(3,700 words; September 27, 2004)




大部分Web应用不会包含像银行̎h信用卡资料那h密的信息Q但是一旦涉及到敏感数据Q就需要我们提供某些密码保护机制。例如,在一个工厂当中,工h必须通过Web应用E序讉K他们的时间安排、进入他们的培训评以及查看他们的薪金等{。此时应用SSL(Secure Socket Layer)有些大材小用了(SSL面不会在缓存中保存Q关于SSL的讨论已l超出本文的范围)。但是这些应用又实需要某U密码保护措施,否则Q工人(在这U情况下Q也是Web应用的用者)可以发现工厂中所有员工的Uh机密信息?br />
cM上面的情况还包括位于公共图书馆、医院?font color="#000000">|吧
{公共场所的计机。在q些地方Q许多用户共同用几台计机Q此时保护用L个h数据显得至关重要?/font> 同时应用E序的良好设计与实现对用户专业知识以及相兛_训要求少之又?

让我们来看一下现实世界中一个完的Web应用是怎样工作的:
1. 用户在浏览器中输入URLQ访问一个页面?br />2. Web应用昄一个登陆页面,要求用户输入有效的验证信息?br />3. 用户输入用户名和密码?br />4. 假设用户提供的验证信息是正确的,l过了验证过E,Web应用允许用户览他有权访问的区域?br />5. 退出时Q用L击页面的退出按钮,Web应用昄认面Q询问用h否真的需要退出。一旦用Lȝ定按钮,Sessionl束QWeb应用重新定位到登陆页面。用L在可以放心的d而不用担心他的信息会被泄霌Ӏ?br />6. 另一个用户坐C同一台电脑前。他点击后退按钮QWeb应用不应该显CZ一个用戯问过的Q何一个页面?br />事实上,Web应用一直停留在登陆面上,除非W二个用h供正的验证信息Q之后才可以讉K他有权限的区域?br />
通过CZE序Q文章向您阐qC如何在一个Web应用中实C面的功能?br />



一. JSP samples

Z更ؓ有效地向您说明这个解x案,本文从展示一个Web应用logoutSampleJSP1中碰到的问题开始。这个示例代表了许多没有正确解决退E的Web应用。logoutSampleJSP1包含一下JSP面Qlogin.jsp,  home.jsp,  secure1.jsp,  secure2.jsp,  logout.jsp,  loginAction.jsp, ?logoutAction.jsp。其中页面home.jsp,  secure1.jsp,  secure2.jsp, ?logout.jsp是不允许未经认证的用戯问的Q也是_q些面包含了重要信息,在用L陆之前或者退Z后都不应该显C在览器中。login.jsp面包含了用于用戯入用户名和密码的form。logout.jsp面包含了要求用L认是否退出的form。loginAction.jsp和logoutAction.jsp作ؓ控制器分别包含了登陆和退出动作的代码?br />
W二个WebCZ应用logoutSampleJSP2展示了如何纠正示例logoutSampleJSP1中的问题。但是第二个CZlogoutSampleJSP2自n也是有问题的。在特定情况下,退出问题依然存在?br />
W三个WebCZ应用logoutSampleJSP3对logoutSampleJSP2q行了改q,比较妥善地解决了退出问题?br />
最后一个WebCZlogoutSampleStruts展示?font size="3">Jakarta
Struts如何优雅地解决退出问题?br />
注意Q本文所附示例在最新版本的Microsoft Internet Explorer (IE), Netscape Navigator, Mozilla, FireFox和Avant览器上试通过?br />


? Login action

Brian Pontarelli的经典文?
《J2EE Security: Container Versus Custom? 讨论了不同的J2EE认证Ҏ。文章同时指出,HTTP协议和基于form的认证方法ƈ不能提供处理用户退出问题的机制。因此,解决Ҏ便是引入用户自定义的安全实现机制Q这提供了更大的灵zL?br />
在用戯定义的认证方法中Q普遍采用的Ҏ是从用户提交的form中获得用戯入的认证信息Q然后到诸如LDAP (lightweight directory access protocol)或关pL据库(relational database management system, RDBMS)的安全域中进行认证。如果用h供的认证信息是有效的Q登陆动作在HttpSession对象中保存某个对象。HttpSession存在着保存的对象则表示用户已经登陆到Web应用当中。ؓ了方便v见,本文所附的CZ只在HttpSession中保存一个用户名以表明用户已l登陆。清?是从loginAction.jsp面中节选的一D代码以此讲解登陆动作:




Listing 1
//...

//initialize RequestDispatcher object; set forward to home page by default
RequestDispatcher rd = request.getRequestDispatcher(
"home.jsp" );

//Prepare connection and statement

rs = stmt.executeQuery(
"select password from USER where userName = '" + userName + "'" );
if (rs.next()) {
//Query only returns 1 record in the result set;
//Only 1
password per userName which is also the primary key
    if (rs.getString(
"password" ).equals(password)) { //If valid password

        session.setAttribute(
"User" , userName); //Saves username string in the session object
    }
    else {
//Password does not match, i.e., invalid user password
        request.setAttribute(
"Error" , "Invalid password." );

        rd = request.getRequestDispatcher(
"login.jsp"
);
    }
}
//No record in the result set, i.e., invalid username

    else {

        request.setAttribute(
"Error" , "Invalid user name." );
        rd = request.getRequestDispatcher(
"login.jsp"
);
    }
}

//As a controller, loginAction.jsp finally either forwards to "login.jsp" or "home.jsp"

rd.forward(request, response);
//...

				
				
		


本文当中所附Web应用CZ均以关系型数据库作ؓ安全域,但本问所讲述的内容同样适用于其他Q何类型的安全域?br />


? Logout action

退出动作包含删除用户名以及调用用户的HttpSession对象的invalidate()Ҏ。清?是从loginoutAction.jsp中节选的一D代码,以此说明退出动作:



Listing 2
//...

session.removeAttribute(
"User" );
session.invalidate();
//...

						
						
				


? L未经认证讉K受保护的JSP面

从提交的form中获取用h交的认证信息q经q验证后Q登陆动作仅仅在HttpSession对象中写入一个用户名。退出动作则刚好相反Q它从HttpSession中删除用户名q调用HttpSession对象的invalidate()Ҏ。ؓ了登陆和退出动作真正发挥作用,所有受保护的JSP面必须首先验证HttpSession中包含的用户名,以便认用户当前是否已经登陆。如果HttpSession中包含了用户名,p明用户已l登陆,Web应用会将剩余的JSP中的动态内容发送给览器。否则,JSP将跌{到登陆页面,login.jsp。页面home.jsp,  secure1.jsp,  secure2.jsp?logout.jsp均包含清?中的代码D:


Listing 3
//...
String userName = (String) session.getAttribute(
"User" );
if (null == userName) {
    request.setAttribute(
"Error" , "Session has ended. Please login."
);
    RequestDispatcher rd = request.getRequestDispatcher(
"login.jsp"
);
    rd.forward(request, response);
}
//...

//Allow the rest of the dynamic content in this JSP to be served to the browser
//...
						
						
				


在这个代码段中,E序从HttpSession?font color="#000000">?/font>username字符丌Ӏ如果username字符串ؓI,Web应用则自动中止执行当前页面ƈ跌{到登陆页Q同时给出错误信息“Session has ended. Please log in.”;如果不ؓI,Web应用l箋执行Q把剩余的页面提供给用户Q从而JSP面的动态内Ҏ为服务对象?br />


?q行logoutSampleJSP1

q行logoutSampleJSP1会出现如下几种情ŞQ?br />
?如果用户没有登陆QWeb应用会正确中止受保护页面home.jsp,  secure1.jsp,  secure2.jsp和logout.jsp中动态内容的执行。也是_假如用户q没有登陆,但是在浏览器地址栏中直接敲入受保护JSP늚地址试图讉KQWeb应用自动蟩转到登陆面Q同时显C错误信息“Session has ended.Please log in.?br />
?同样的,当一个用户已l退出,Web应用会正确中止受保护页面home.jsp,  secure1.jsp,  secure2.jsp和logout.jsp中动态内容的执行。也是_用户退Z后,如果在浏览器地址栏中直接敲入受保护JSP늚地址试图讉KQWeb应用自动蟩转到登陆面Q同时显C错误信息“Session has ended.Please log in.?br />
?用户退Z后,如果点击览器上的后退按钮q回到先前的面QWeb应用不能正保护受保护的JSP面——在Session销毁后Q用户退出)受保护的JSP会重新昄在浏览器中。然而,点击该页面上的Q何链接,Web应用都会跌{到登陆页面,同时昄错误信息“Session has ended.Please log in.?br />


? L览器缓?/font>
 
上述问题的根源就在于C大部分浏览器都有一个后退按钮。当点击后退按钮Ӟ默认情况下浏览器不会从Web服务器上重新获取面Q而是单的从浏览器~存中重新蝲入页面。这个问题ƈ不仅限于ZJava(JSP/servlets/Struts) 的Web应用当中Q在ZPHP (Hypertext Preprocessor)、ASP?Active Server Pages)、和.NET的Web应用中也同样存在?br />
在用Ld退按钮之后Q浏览器到Web服务器(一般来_或者应用服务器Q在java的情况下Q再从服务器到浏览器q样通常意义上的HTTP回\q没有徏立。仅仅只是用P览器和~存之间q行了交互。所以即使受保护的JSP面Q例如home.jsp,  secure1.jsp,  secure2.jsp和logout.jsp包含了清?上的代码Q当点击后退按钮Ӟq些代码也永q不会执行的?br />
~存的好坏,真是仁者见仁智者见智。缓存事实上的确提供了一些便利,但这些便利通常只存在于静态的HTML面或基于图形或影像的页面。而另一斚wQWeb应用通常是面向数据的。由于Web应用中的数据频繁变更Q所以与Z节省旉从缓存中dq显C期的数据相比Q提供最新的数据昑־ؓ重要Q?br />
q运的是QHTTP头信息“Expires”和“Cache-Control”ؓ应用E序服务器提供了一个控制浏览器和代理服务器上缓存的机制。HTTP头信息Expires告诉代理服务器它的缓存页面何时将q期。HTTP1.1规范中新定义的头信息Cache-Control在Web应用当中可以通知览器不~存M面。当点击后退按钮Ӟ览器发送Httph道应用服务器以便获取该页面的最新拷贝。如下是使用Cache-Control的基本方法:

?no-cache:强制~存从服务器上获取该面的最新拷?br />?no-store: 在Q何情况下~存不保存该面

HTTP1.0规范中的Pragma:no-cache{同于HTTP1.1规范中的Cache-Control:no-cacheQ同样可以包含在头信息中?

通过使用HTTP头信息的cache控制Q第二个CZ应用logoutSampleJSP2解决了logoutSampleJSP1的问题。logoutSampleJSP2与logoutSampleJSP1不同表现在如下代码段中,q一代码D加入进所有受保护的页面中Q?br />



//...
response.setHeader(
"Cache-Control" , "no-cache" ); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader(
"Cache-Control" , "no-store" ); //Directs caches not to store the page under any circumstance
response.setDateHeader(
"Expires" , 0); //Causes the proxy cache to see the page as "stale"
response.setHeader(
"Pragma" , "no-cache" ); //HTTP 1.0 backward compatibility
String userName = (String) session.getAttribute(
"User" );
if (null == userName) {
    request.setAttribute(
"Error" , "Session has ended. Please login."
);
    RequestDispatcher rd = request.getRequestDispatcher(
"login.jsp"
);
    rd.forward(request, response);
}
//...

						
						
				


通过讄头信息和查HttpSession对象中的用户名来保览器不会缓存JSP面。同Ӟ如果用户未登陆,JSP面的动态内容不会发送到览器,取而代之的是登陆面login.jsp?br />


? q行logoutSampleJSP2

q行WebCZ应用logoutSampleJSP2后将会看到如下结果:

?当用户退出后试图点击后退按钮Q浏览器不会重新昄受保护的面Q它只会昄登陆login.jsp同时l出提示信息Session has ended. Please log in.

?然而,当按了后退按钮q回的页是处理用h交数据的面ӞIE和Avant览器将弹出如下信息提示Q?br />
           警告Q页面已q期
           The page you requested was created using information you submitted in a form. This page is no longer available. As a security precaution, Internet Explorer does not automatically  resubmit your information for you.

Mozilla和FireFox览器将会显CZ个对话框Q提CZ息如下:

            The page you are trying to view contains POSTDATA that has expired from cache. If you  resend the data, any action from the form carried out (such as a search or online purchase) will be repeated. To resend the data, click OK. Otherwise, click Cancel.

在IE和Avant览器中选择h或者在Mozilla和FireFox览器中选择重新发送数据后Q前一个JSP面重新显C在览器中。显然的Q这病不是我们所想看到的因ؓ它违背了logout动作的目的。发生这一现象Ӟ很可能是一个恶意用户在试获取其他用户的数据。然而,q个问题仅仅出现在点d退按钮后,览器返回到一个处理POSTh的页面?br />


? 记录最后登陆时?

上述问题的发生是因ؓ览器重新提交了其缓存中的数据。这本文的例子中Q数据包含了用户名和密码。尽IE览器给Z安全警告信息Q但事实上浏览器此时起到了负面作用?br />
Z解决logoutSampleJSP2中出现的问题QlogoutSampleJSP3的login.jsp除了包含username和password的之外,q增加了一个称作lastLogon的隐藏表单域Q此表单域将会动态的被初始化Z个long型倹{这个long型值是通过调用System.currentTimeMillis()获取到的?970q??日以来的毫秒数。当login.jsp中的form提交ӞloginAction.jsp首先隐藏域中的g用户数据库中的lastLogonD行比较。只有当lastLogon表单域中的值大于数据库中的值时Web应用才认是个有效的登陆?br />
Z验证登陆Q数据库中lastLogon字段必须用表单中的lastLogonD行更新。上例中Q当览器重复提交缓存中的数据时Q表单中的lastLogong比数据库中的lastLogon值大Q因此,loginAction蟩转到login.jsp面Qƈ昄如下错误信息“Session has ended.Please log in.”清?是loginAction中节选的代码D:




清单5
//...
RequestDispatcher rd = request.getRequestDispatcher(
"home.jsp" ); //Forward to homepage by default
//...
if (rs.getString(
"password" ).equals(password)) { //If valid password
    long lastLogonDB = rs.getLong(
"lastLogon" );
    if (lastLogonForm > lastLogonDB) {
        session.setAttribute(
"User" , userName); //Saves username string in the session object

        stmt.executeUpdate(
"update USER set lastLogon= " + lastLogonForm + " where userName = '" + userName + "'" );
    }
    else {
        request.setAttribute(
"Error" , "Session has ended. Please login."
);
        rd = request.getRequestDispatcher(
"login.jsp"
); }
    }
else {
//Password does not match, i.e., invalid user password

    request.setAttribute(
"Error" , "Invalid password." );
    rd = request.getRequestDispatcher(
"login.jsp"
);
}
//...

rd.forward(request, response);
//...
						
						
				


Z实现上述ҎQ你必须记录每个用户的最后登陆时间。对于采用关pd数据库安全域来说Q这点可以可以通过在某个表中加上lastLogin字段L实现。虽然对LDAP以及其他的安全域来说需要稍微动下脑{,但最后登陆方法很昄是可以实现的?br />
表示最后登陆时间的Ҏ有很多。示例logoutSampleJSP3利用了自1970q??日以来的毫秒数。这个方法即使在许多人在不同览器中用一个用戯̎L陆时也是可行的?br />


? q行logoutSampleJSP3

q行CZlogoutSampleJSP3展C如何正处理退出问题。一旦用户退出,点击览器上的后退按钮在Q何情况下都不会在览器中昄受保护的JSP面。这个示例展CZ如何正确处理退出问题而不需要对用户q行额外的培训?br />
Z使代码更l有效,一些冗余的代码可以剔除。一U途径是把清?中的代码写到一个单独的JSP中Q其他JSP面可以通过标签
<jsp:include>q行使用 ?br />


? Struts框架下的退出实?/font>

与直接用JSP或JSP/servletsq行Web应用开发相比,另一个更好的可选方案是使用Struts。对于一个基于Struts的Web应用来说Q添加一个处理退出问题的框架可以优雅CҎ力的实现。这归功于Struts是采用MVC设计模式的,因此可以模型和视图代码清晰的分R另外,Java是一个面向对象的语言Q支持承,可以比JSP中的脚本更ؓҎ地实C码重用。对于Struts来说Q清?中的代码可以从JSP面中移植到Actioncȝexecute()Ҏ中?br />
此外Q我们还可以定义一个承Struts ActioncȝAction基类Q其execute()Ҏ中包含了cM清单4中的代码。通过l承Q其他Actioncd以承基本类中的通用逻辑来设|HTTP头信息以及检索HttpSession对象中的username字符丌Ӏ这个Action基类是一个抽象类q定义了一个抽象方法executeAction()。所有承自Action基类的子c都必须实现exectuteAction()Ҏ而不是覆盖它。通过l承q一机制Q所有承自Action基类的子c都不必再担心退Z码接口。(plumbing实在不知道怎么译了,^+^Q高手帮帮忙啊!原文QWith this inheritance hierarchy in place, all of the base Action's subclasses no longer need to worry about any plumbing logout code.Q。他们将只包含正常的业务逻辑代码。清?是基cȝ部分代码Q?br />


清单6
publicabstractclass BaseAction extends Action {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                                 HttpServletRequest request, HttpServletResponse response) 
               throws IOException, ServletException {

response.setHeader(
"Cache-Control" , "no-cache" ); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader(
"Cache-Control" , "no-store" ); //Directs caches not to store the page under any circumstance
response.setDateHeader(
"Expires" , 0); //Causes the proxy cache to see the page as "stale"
response.setHeader(
"Pragma" , "no-cache" ); //HTTP 1.0 backward compatibility

if (!this.userIsLoggedIn(request)) {
    ActionErrors errors = new ActionErrors();

    errors.add(
"error" , new ActionError( "logon.sessionEnded" ));
    this.saveErrors(request, errors);

    return mapping.findForward(
"sessionEnded"
);
}

return executeAction(mapping, form, request, response);
}

protectedabstract ActionForward executeAction(ActionMapping mapping,  ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;

privateboolean userIsLoggedIn(HttpServletRequest request) {
if (request.getSession().getAttribute(
"User"
) == null) {
    return false;
}

return true;
}
}
						
						
				


清单6中的代码与清?中的很相像,唯一区别是用ActionMapping findForward替代了RequestDispatcher forward。清?中,如果在HttpSession中未扑ֈusername字符ԌActionMapping对象找到名为sessionEnded的forward元素q蟩转到对应的path。如果找CQ子c通过实现executeAction()ҎQ将执行他们自己的业务逻辑。因此,在struts-web.xml配置文g中ؓ所有承自Action基类的子cd明个一名ؓsessionEnded的forward元素q将其指向login.jsp是至关重要的。清?以secure1 action阐明了这样一个声明:


清单7
<action path=
"/secure1"
type=
"com.kevinhle.logoutSampleStruts.Secure1Action"
scope=
"request" >
<forward name=
"success" path= "/WEB-INF/jsps/secure1.jsp"
/>
<forward name=
"sessionEnded" path= "/login.jsp"
/>
</action>

						
						
				


l承自BaseActioncȝ子类Secure1Action实现了executeAction()Ҏ而不是覆盖它。Secure1ActioncM需要执行Q何退Z码,如清?Q?br />


清单8
publicclass Secure1Action extends BaseAction {
    public ActionForward executeAction(ActionMapping mapping, ActionForm form,
                                                           HttpServletRequest request, HttpServletResponse response)
               throws IOException, ServletException {

               HttpSession session = request.getSession(); 
               return (mapping.findForward(
"success" ));
         }
}
						
						
				


上面的解x案是如此的优雅有效,它仅仅只需要定义一个基c而不需要额外的代码工作。将通用的行为方法写成一个承StrutsAction的基cL者的推荐的,而且q是许多Struts目的共同经验?br />



十一. 局限?/font>

上述解决Ҏ对JSP或基于Struts的Web应用都是非常单而实用的Q但它还是有某些局限。在我看来,q些局限ƈ不是臛_紧要的?br />
• ?通过取消与浏览器后退按钮有关的缓存机Ӟ一旦用L开面而没有对数据q行提交Q那么页面将会丢失所有输入的数据。即使点L览器的后退按钮q回到刚才的面也无于事,因ؓ览器会从服务器获取新的I白面昄出来。一U可能的Ҏq不是阻止这些JSP面包含数据数据表格。在ZJSP的解x案当中,那些JSP面可以删除在清?中的代码。在ZStruts的解x案当中,Actionc需要承自Struts的Actionc而非BaseActioncR?br />
•  上面讲q的Ҏ在Opera览器中不能工作。事实上没有适用于Opera览器的解决ҎQ因为Opera览器与2616 Hypertext Transfer Protocol—HTTP/1.1紧密相关。Section 13.13 of RFC 2616 states:          
User agents often have history mechanisms, such as "Back" buttons and history lists, which can be used to redisplay an entity retrieved earlier in a session.

History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved.

q运的是Q用微软的IE和基于Mozilla的浏览器用户多余Opera览器。上面讲q的解决Ҏ对大多数用户来说q是有帮助的。另外,无论是否使用上述的解x案,Opera览器仍然存在用户退出问题,Opera来说没有M改变。然而,正如RFC2616中所_通过像上面一栯|头文g指oQ当用户点击一个链接时QOpera览器不会从~存中获取页面?br />



十二. l论

q篇文章讲述了处理退出问题的解决ҎQ尽方案简单的令h惊讶Q但在所有情况下都能有效地工作。无论是对JSPq是StrutsQ所要做的不q是写一D不过50行的代码以及一个记录用h后登陆时间的Ҏ。在有密码保护的Web应用中用这些方案能够确保在M情况下用LUh数据不致泄露Q同Ӟ也能增加用户的经验?br />
About the author
[i]Kevin H. Le[/i] has more than 12 years of experience in software development. In the first half of his career, his programming language of choice was C++. In 1997, he shifted his focus to Java. He has engaged in and successfully completed several J2EE and EAI projects as both developer and architect. In addition to J2EE, his current interests now include Web services and SOA. More information on Kevin can be found on his Website http://kevinhle.com.



Binary 2006-08-24 15:56 发表评论
]]>
整理一下技术\U?-载至Robbin原文http://www.tkk7.com/lijiajia418/archive/2006/08/24/65521.htmlBinaryBinaryThu, 24 Aug 2006 07:10:00 GMThttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65521.htmlhttp://www.tkk7.com/lijiajia418/comments/65521.htmlhttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65521.html#Feedback0http://www.tkk7.com/lijiajia418/comments/commentRss/65521.htmlhttp://www.tkk7.com/lijiajia418/services/trackbacks/65521.html一、Y件开发技?

1Q服务器?

在最q?q内QJavaq是LQ不光是因ؓ当前的普及程度和遗留pȝ问题Q而且除Microsoft几乎所有大公司都投资到Java上面的原因,此外开源也是一股无法忽略的力量Q除了Java斚w的开源框架在推动JavaQ也有Linux在带动java企业应用在普及(别忘记dotnet只能?Windows Server上面q行Q?

dotnet有自q优势Q但是在五年内无法和Java取得均势Q不光是因ؓJava普及带来的优势,也不光因为开源界对java的推动,也不光因为其他大公司在java上面的投资,而是很多公司的行业性质军_了dotnet的出局Q例如电信行业,金融行业Q电子政务行业等{,是根本没有可能采?dotnet的?

Python和Ruby不上后P但是很有竞争实力Q不q基于上面的原因Q仍然不能成Z?

在Java服务器端技术中Q清晰的分ؓ两条路线Q高端的商业路线Q这条\U是EJB3QJ2EE5.0Q低端的开源\U,q条路线是HibernateQ?Spring。这两条路线也有重叠的地方,例如开源的Struts几乎成ؓJ2EE Web层的标准Q开源的Hibernate奠定了EJB3的基。但是划分\U不是基于技术上的区别,而是Z商业q作上的区别。注重技术支持和商业服务的公怼选择前者,注重成本控制和选择自由的公怼选择后者?

商业路线的技术方案是QEJB3QStrutsQ?
开源\U的技术方案是QSpringQHibernateQStruts/Webwork

Struts是一个很成功的开源框Ӟ它的C短期内还无法动摇QJavaEye有一命,是动摇Struts在Java Web领域的地位,把它赶下王Q把Webwork扶上位!

商业的Web层技术,JSTL是一个不错的东西Q但是和灉|的模板语a如FreeMarker相比Q却有很大的差距。JSF基本上是一个没有前途的东西。商业Web层技术因Z直没有出现好的应用,q样也导致了Struts的上位?

服务器端业务层和持久层框Ӟ我非常看好EJB3Q原因也不用多谈了,从商业上来说Q需要这样一个东西,跨国公司们也需要这样一个品来卖,来取代糟p的 EJB2。开源的Ҏ里面QSpringQHibenrate是一个很好的商业Ҏ的开源替代,他们不存在很直接的竞争,而是一个互补的关系。这里比较尴的反而是JDOQJDO是商业品(目前没有好的开源实玎ͼQ造成开源应用不会对它感兴趣QJDO没有一个像EJB容器那样的脱环境,造成商业Ҏ对它不感兴趣。不q有了JDOQ我觉得是对EJB3Q对Hibernate形成一个良好的竞争环境Q这一Ҏ非常有利的?

2Q客L技?

准确的说是RIA应用。虽然我前面对XAMLq行了正面的评hQ但是我认ؓ我前面有些结论给错了。经q这D|_我觉得,XAMLx在多q之后,也未必能够成Z个非常成功的解决Ҏ。道理很二:

1、XAML会带来比ActiveX更严重的安全性问题?
XAML本质上就是一个本地应用程序,虽然L可以在IE览器里面运行,但IE是一个皮而已QXAML应用具备Ҏ地资源完全的讉K能力Q就IE限制也没有用QIE限制׃失功能,那样的话Q功能ƈ不会比Javascript来得更多Q不限制的话Q就为所Ʋؓ了)Q因此只要IE具备了运行XAML的能力,黑客可以非常轻易的通过IEq行入RQ这仅仅需要引导用户在不知不觉中访问一个恶意的|页搞定了Q用户必面临选择Q要么禁止IE对XAML的运行能力,要么接受随时被攻ȝ危险?

2、XAML应用本质上也是RIA应用Q因此必进行大量的RPC调用
当前XAML采用XML Web Servicesq行通讯Q这是一U低效的RPC。当前的XAML案例中ƈ没有注意到RPC领域Q实际上Ҏ我现在做RIA的体验来_RPCl对不是一个简单的事情Q要考虑的问题非常多?

从当前的阶段来说Q最实际可用的方案有两个Q?

1、AJAX
实际上就是基于XMLHTTP的JS异步交互Q这个东西已l出现很多年了,最q随着Google应用和Sun Blueprint的推出开始火热。我原来对这个东西持否定态度Q但是后来{变了。我原来否定态度的一个前提就是:XMLHTTP~Z成熟的组件库Q但是没有想到的是,现在XMLHTTP从去q下半年开始,如雨后春W般冒出来。AJAX应用最大的好处是充分利用现有资源Q我认ؓ应成为RIA应用的首选?

2、Flash
Flash的优势也很明显,强大的AS支持Q强大的lg可视化设计,强大的交互能力和很炫的用户体验,q且Flash Remoting也已l非常成熟了。Flash的缺点就是Flash虽然嵌入|页Q但是和|页没有数据交互能力QFlash另一个缺点就是不适合处理大量文本内容QHTML最适合Q。现在有些h开始滥用Flash了?

因此比较好的方式可能是两U؜用,一般不q度复杂的交互交lAJAXQ非常复杂,甚至需要托拽操作的Q交lFlash?

ȝ一下:

软g开发领域服务器端技术Java是主,两个技术\U,一个是EJB3Q一个是SpringQHibernateQ此外iBATIS也有一席之圎ͼ客户端技术就是AJAX和Flash?

二、数据库技?

基本上格局不会发生多大变化QOracleq是高高在上QSQL Serverq一步蚕食NTq_其他数据库的领地。开源方面,MySQL一枝独UQ但是开源数据库在很多方面还是和商业数据库有无法拉近的巨大差距。这也得商业数据库的地位不可替代。我会比较关注OracleQMySQLq两个数据库。面向对象数据库仍然不会有什么v艌Ӏ?

三、桌面编E技?

我还是相信一点,对于桌面应用来说Q本C码的位置永远无法被取代,所以我总觉得XAML那样的东西效率实在很成问题。Longhorn要像成熟Q也不是W一个版本就可以辑ֈ的。当前桌面应用开发技术,q是首推DelphiQ不q我觉得Python是后起之UQ非常有可能在未来取代Delphi?br />
初探在下一?Windows 中编写和部v应用E序
http://www.microsoft.com/china/MSDN/library/windev/longhorn/DevelopAppLonghorn.mspx

首先Q以Microsoft公司的实力和Windows操作pȝ的占有率来说QLonghornq早会被普及Q而XAML的开发方式也有可能普及的。记得当初WindowsXP刚出来的时候,因ؓ资源占用率和新的Ȁzd度招致一片骂壎ͼ但是慢慢的,现在也都接受了下来。由此可以推断,Longhorn以其更加丰富的桌面功能和׃h的外观,会在来成ؓL?

但是Longhorn什么时候才会全面普及,q是很值得琢磨的问题。WindowsXP?001q推出的Q在随后的几q_Microsoft采用了一些商业手D|q用户升Q例如企囑֏消Windows98的技术支持,不再提供WindowsNT技术支持,不再销?WindowsNT/Windows98Q将Windows2000保持在一个比较高的售L同时Q对WindowsXP推出优惠hQ让 WindowsXP的售价低于Windows2000{等手段。但是直到现在,Windows2000仍然占据了非帔R的䆾额,据我个h的观察是?WindowsXP略高。按照这U情冉|推断QLonghorn要普及,恐怕难度更大,非常多的用户现在仍然是Windows2000的死忠派Q?WindowsXP推广了四q还未能过Windows2000Q那么LonghornI竟要几q才能超qWindowsXP呢?我估计四q以上是L的?

XAML应用E序不同以往Q它只能跑在Longhorn上面Q甚xJava和dotnet要求更严|后者仅仅下载安装一个运行环境就可以了,但是前者要求你必须更新操作pȝ。XAML在IE览器中q行虽然肯定是下一代RIA的主,但是不可忽视的问题是Q只要Longhorn没有d淘汰 Windows2000/XPQY件开发商和网站开发商׃敢大面积采用XAML。而根据我的观察,现在企业中,Windows98仍有部分市Z额。因此Longhorn必须要等待到d的,毫不D留的淘汰Windows98QWindows2000QWindowsXP之后Q才会全面普及,而在此之前,不得不经历一个O长的q渡期?

好像现在,假设你开发桌面应用程序,你敢只针对WindowsXP开发吗Q而彻底不支持98?000吗?我想Q没有哪个Y件开发商敢这样做。除?Windows2000几乎被彻底淘CQ你才敢q样做,但是WindowsXP已经推出四年了,q没有Windows2000占用率高Q哪全面淘汰I竟要几q呢Q再看看现在dotnet winforms应用Q推Z已经五年旉了,但是到现在仍然没有普及开来,Ҏ的原因就是Windows2000/WindowsXP没有预装 dotnet framework。仅仅是需要打包安装一个运行环境就使得winforms五年都推q不了,更何况要求你升操作pȝ呢?

我个人的估计是,假设2006qLonghorn如期上市Q那么将需?-9q时间来d淘汰Windows2000/WindowsXP?Longhorm上面XAML应用的初步普及也臛_需?-5q时间以后才会有软g开发商大量dQ想向dotnet?000q开始宣传和推广的,?2004q开始普及,今年和明q才会全面普?。因此,ZXAML应用的普及可能是?010q以后!上面的估计中q没有包括MacOS 和Linux在桌面会否有什么表现?

先说说服务器端吧Q?

从可预见的未来来看,服务器和客户端TCP通讯的主方式一定是HTTP协议Q即旉讯软g走UDP端口Q不在讨_。在ZHTTP协议之上Q又分ؓ两类Q一cLSOAP协议Q异构系l支持良好,但是性能很差Q目前Microsoft很喜Ƣ用q种方式Q一cL轻量U二q制协议Q例如Flash?AMF协议QResin的Hessian协议。值得一提的是,不管哪种方式Q他们都支持异构的系l,所以完全可用在客户端采用dotnetQ在服务器端采用Java或者Python。因此,XAML的流行不会对服务器端技术生致命的影响Q肯定会提高dotnet的服务器的市Z额)。所以我们可用抛开客户端媄响,单独来看服务器端技术:

1、Java
Java是当前服务器端技术当之无愧的王者,在未来五q内Q也不会有Q何动摇(受到dotnet和python的媄响,市场份额会下降一些)。Java特别有利的一ҎQ现在有太多的现存系l基于JavaQ这些系l都不会Lq移到其他^C。另外还有一个决定因素是除了Microsoft之外的几乎全?IT大公叔R在Java斚w的投资巨大,攑ּJava对他们来说也意味着沉重的打击,甚至毁灭性的打击。这些公司可以列很长很长QIBMQHPQ?OracleQSAPQSunQBEAQMacromedia{等?

2、dotnet
׃Microsoft的媄响力Qdotnet会成Zؓ仅次于Java的第二大服务器端技术,但是Microsoft有一个隐忧,是Linux操作pȝ在服务器端的高速成ѝ虽然现在Linux在整个服务器端市场的量只?3%左右Q但是成长率惊hQ根据我看到的资料显C,?008q_占?25%以上的市Z额。考虑到很多公司是自己安装LinuxQ因此不会被g服务器厂商统计进来,因此Linux的服务器端的市场份额应该?5%高一些。ƈ且现在主要的服务器厂商都对Linux有非常巨大的投入和支持,q些公司包括IBMQHPQDellQ只有Sun不支持)Q因此Linux在未来会对Windows在服务器端的市场构成最严重的威胁?

不要忘记dotnet只能在Windowsq_上面跑,虽然有monoQ但是你不可能移植MTSQCOM+QSQL Server etc。所以只要Linux在服务器市场对Windows构成持箋的威胁,dotnet׃可能过JavaQJava的地位还是稳E的老大。从某种E度上来_Java的命q是和Linux联系在一LQ只要Linux在服务器端不输于WindowsQJavaqE_制dotnet?

BTW:从未来来看,Linux和Windows会在低端和中端服务器市场成ؓ主要竞争ҎQ由于各自都有其不可替代性,所以双斚w不可能彻底消灭对方,最大的可能性是Linux和Windowsq_市场Q或者Windows市场份额略高一炏V?

3、Python
我个为Python会成长ؓW三大服务器端技术,Python成长于开源,但是又有商业公司来商业运作,q且背后q有大公司的支持Q在Ƨ洲普及的非常好。当然最重要的原因是我觉得Python在技术上非常先进Qƈ且技术发展方向上比较l一Q不会出现Java那种吉|的事情?

4、PHP
PHPq东西是不错QYahoo也在用,IBM现在也对他感兴趣Q但是我q是要说PHP没有太广阔的前途,原因很简单,PHP没有服务端中间gQ例?Java有App ServerQdotnet有IIS/MTSQPython有ZopeQ但是PHP他就是一个脚本,没有自己的中间g是致命问题。Yahoo用PHP有其特定的原因,主要是从原先自己的技术迁UdPHP很方便,而IBM支持PHPQ显焉之意不在酒QIBM意不在推qPHPQ而在于争取到那些使用 PHP的商业大客户们,向他们卖服务?

BTWQ感觉欧z用Python/PHP的很多,g开源在Ƨ洲非常深入人心?

从服务器端技术来_Javaq是我们最需要下功夫d习和掌握的,此外Q我会比较們֐于钻研和应用PythonQ而不是dotnet。原因也很简单,跟随Micorsoft的技术会很辛苦,Microsoft产生的新概念多,他L会猛的推出n多种技术,然后让他们在市场上自q存,最后根据市场反馈,无情的抛弃某些东西,大力推进有市场前景的东西Q这L例子太多了,举不胜D了。我的感觉就是这U方式会让Microsftl过市场试在技术竞争中{选最优秀的技术,但是对于Microsoft技术的跟随者来_未免有点太不公^Q整天吭哧吭哧被Microsoft拿来当免费的试验品来用。我特别不理解的是MSDN宇宙版,MicrosoftL把无Ih的文档灌给你,让你永远学不完,但实际上我真的不需要那么多概念Q我只需要能够很好的完成我工作的技术,q且q个技术可以持l的完善好了。而不是今天给我这样一个东西,明天灌给我无IL文档Q后天当我用手以后Q又告诉我这东西作废了,你给我重新学习新东西Q然后又是无IL文档QM很恼火?

所以就是:重点学习JavaQ有旉d习PythonQ保持对dotnet的关注即可?


客户端:

前面说了那么多XAML的东西,都是和这有关Q七q以后肯定是XAML的天下,但是五到七年之内q不是:

1、Java
Java在客L真的是扶不v的阿斗,q都怪Sun。Sun造就了Java的成功,又一手毁了Java在客L的市场。那些个Swing和SWT的死忠团也不要和我争什么,我也懒得和你们争Q你们觉得好好吧,道不同不怸谋,你觉得好你就用你的,我觉得不好我q别的。用不着~着我非逼我说Java做客L好,没必要,况且q你逼我承认又怎样Q我是玉皇大帝金口玉言了?得到我的承认QJava有前途了Q我好像q没有那么大本领吧?是IBMQ?Sun也没有那么大本领Q所以好不好也不是我说了,用不着逼我?

2、dotnet winforms
׃Windows2000/WindowsXP不带dotnet CLRQ所以winforms一直没有能够普及得很好Q等Longhorn一出来Q又变成了XAML了,winforms又被淘汰了,所?winforms的地位特别尴,但是在这5-7q中Q你惛_发既能够在Windows2000/WindowsXPQ又能够在Longhorn上面跑的桌面E序Qwinforms好像又是Microsoft技术中最好的选择。所以只好一直尴下厅R?

3、VCQVB
dotnet出来以后开始尴了Q说用吧Q好像很落伍了,都dotnet时代了,说不用吧Q又没有好的替代品,现阶D开发桌面程序,q真得不得不用,而且q挺好用的。所以VC6SP5QVB6的死忠团也比较多?

4、Delphi
dotnet出来以后Borland开始跟风了Q这一跟风Q连老本都跟没有了。未来的XAML时代Q我也不知道Borland怎样找自q定位Q但不管怎么_从历史来看,本地代码的应用程序永q有它一席之圎ͼqXAML又如何如何做得漂亮了Q关键的地方Q和特定资源处理相关的部分,q是本地代码的程序管用。你看VB出来多少q了Q用VB开发的都是一些上层的目U别的应用YӞ一旦涉及品领域,q是VC和Delphi用。所以现在大家还是不得不用Delphi7ѝ?

BTWQXAML应用致力于快速开发项目别的应用Q特别是可以跑在IE览器里面的Q因此是RIA的首选。但是毕竟也有很多不适合用RIA的场所Q特别是例如我要备䆾某些文gQ你用XAMLQ那性能׃用提了。所以Delphi如果好好发展VCLQ封装Windows32 APIQ我觉得也是一条\Q未必比现在跟随dotnet差?

5、Flash RIA
其实我觉得Flash不适合做RIA的,但是Flash普及率太高,XAML又离普及太遥q,而Flash现在可以用了,所以是当前RIA的首选。不q我对Macromedia公司比较失望Q如果Macromedia能够公布Flash实现l节Q作Z个公开的标准向ISO提交Q同时免费开源FlexQ我敢说QFlash RIA会迅速普及的。等5-7qXAML的时代,׃Flash的市场占有率QXAML未必能拼得qFlash。可惜的是Macromedia公司目光q于短浅Q只知道赚眼前的钱?

6、Python
q?-7q内QRIA应用和RCP应用不会l一QXAML才具备将RIA和RCPl一的实力。从q?-7q来看,Flash是RIA的首选,而RCP的首选,我要推荐Python。原因前面已l提q,单ȝ一下:
1QwxWidgets是一个比MFC优雅的库QTortoiseCVS用wxWidges而不用MFCQ就是因为wxWidgets好用Q而不是ؓ了可以移植?
2QPython的面向对象脚本语a~程适合快速界面开?
3QPython在服务器端和客户端都非常有前途,可以形成一个统一的解x案,q一Ҏ显比Java有优?
4QPython桌面应用E序可以完全~译为本C码,qPythonq行环境Q这一Ҏdotnet winforms都有优势
5QPython可以不受限制的Q意调用Windows32 APIQ所以凡是VC6可以做的事情QPython可以做

试想一下,现在我们开发桌面应用程序有什么要求?
一、不要附带一个JRE或者CLR的篏?
二、可以快速开?
三、性能要有保证
四、方便的q程Ҏ调用支持
此外如果能够跨^台就最好了

Java前三炚w不符合;dotnet winforms不符合一QVC6不符合二和四QVB6不符合三和四QDelphi7W合前四点;Flash RIA不符合三QPython全部都符合!q且误住Python是一个完全开源免费的ҎQ?

客户端技术在q?-7q中Q在RIA领域我会学习一下FlashQ在RCP领域我会重点学习PythonQ此外会观望一下XAML?/span>


Binary 2006-08-24 15:10 发表评论
]]>
理解企业应用框架Q-本文原蝲于《程序员》杂?http://www.tkk7.com/lijiajia418/archive/2006/08/24/65520.htmlBinaryBinaryThu, 24 Aug 2006 07:08:00 GMThttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65520.htmlhttp://www.tkk7.com/lijiajia418/comments/65520.htmlhttp://www.tkk7.com/lijiajia418/archive/2006/08/24/65520.html#Feedback0http://www.tkk7.com/lijiajia418/comments/commentRss/65520.htmlhttp://www.tkk7.com/lijiajia418/services/trackbacks/65520.html我想让这些词中的一个——“框架”——荡污垢,重现青春。要完成q样的Q务,必须动用重典才行。Y件业圣经《设计模式》对框架有如下定义:“A framework is a set of cooperating classes that make up a reusable design for a specific class of softwareQ一个框Ӟ是一l相互协作的c,对于特定的一cYӞ框架构成了一U可重用的设计)”。这个定义虽然主要着g面向对象的Y件开发,但已l基本上l出了这个词的核心含义:框架是Y件系l的设计、开发过E中的一个概念,它强调对以完成的设计、代码的重复使用Qƈ且,一个框架主要适用于实现某一特定cd的Y件系l?
Z更好地说明框架是什么,也许q应该看看框架不是什么?
框架不是现成可用的应用系l。它仍是一个半成品Q等待后来者做“二ơ开发”,实现为具体的应用pȝ?
框架不是“^台”。后者的概念更加泛和模p——h们说的一个^収ͼ可以是一U操作系l,一U应用服务器Q一U数据库软gQ一U通信中间件等{,因此“^台”几乎成了所有系lY件的l称。在q_的大家族中,框架的概念可能与q来Z常说的“应用^台”最为接q,但^C要指提供特定服务的系lYӞ而框架则更侧重于设计、开发过E,或者可以说Q框枉过调用q_提供的服务而v作用?
框架不是工具包(toolkitQ?cdQlibraryQ?/API。目前流行的很多框架中,包括了大量的类库和APIQ但是调用APIq不是在用框架开发。仅仅用APIӞ开发者完成系l的M部分Qƈ不时地调用类库实现特定Q务。而框架构成了通用的、具有一般性的pȝM部分Q“二ơ开发者”只是像做填I题一PҎ具体业务Q完成特定应用系l中与众不同Ҏ的部分?
框架不是构架QarchitectureQ。构架确定了pȝ整体l构、层ơ划分、不同部分之间的协作{设计考虑。框架比构架更具体,更偏重于技术实现。确定框架后Q构架也随之定Q而对于同一U构Ӟ比如web开发中的MVCQ,可以通过多种框架Q比如Apache Struts或Apache VelocityQ实现?

2

那么Q在企业应用pȝ开发中Q框架具有什么样的意义?要阐明这一点,大概要看一看在q个领域里Y件开发方式的演变。在计算机应用普及之前,只有数大企业才负担得v企业信息pȝ软gQ这一cȝ软g开发也已委托定Ӟcustom-made softwareQؓ丅R在企业信息化基设施逐步完备之后Q多C、小企业也要在预不高的前提下实施企业应用系l,按照以前的方式逐个定制开发,是这U类型的企业难以承受的。因此,对于一些需求简明的pȝQ往往会购买现成YӞshrink-wrapped softwareQ解决问题。但是各个企业具体业务不同,需求很隄一Q现成Y件只能满x通用的情况和最一致的操作Q比如胦会系l、网站内容发布系l等Q,对于头A众多的业务处理就难以胜Q了?
如何最大程度地萃取不同企业应用pȝ的共性,重复使用已经完成的设计和代码Q对企业应用pȝ中典型场景给出最佌x案——这是一个“一般性”的问题Q如何让一个早先完成的软g产品贴切地适应极ؓ多变、复杂的企业需求——这是一个“特D性”的问题。作为对q一l冲H的一U解x案,不少厂商推出了自q企业应用框架。这些框架往往是从大量的委托项目开发中_N出的系l“不变项”,因此h很强的普适性和实用性?
目前Q主企业应用框架中大都包含对以下问题的现成解决ҎQ?
* 持久性(persistenceQ:实现数据存储、处理,数据与对象映,数据~存QcachingQ?
* 事务QtransactionQ:保一l关联操作正常、完整的执行?
* 安全性(securityQ:保证pȝ的通信安全、数据安全?
* 负蝲均衡Qload balanceQ:在大量ƈ发访问时Q保持系l可用?
* 监控Qsystem monitoring/managementQ:监控pȝq行状况Q设|系l参数?
* 日志QloggingQ:记录pȝq行情况和异常,记录特定用户操作?
* 应用集成 Qapplication integrationQ:与其他系l、应用程序集成?
* 认证/权限/l织角色理Qauthentication/authorizationQ:理pȝ用户、组l职权结构,限制特定用户对特定功能、特定数据的讉K?
* 业务模型Qdomain modelQ:理pȝ中业务对象的属性、字Dc?
* 业务逻辑Qbusiness logic/rulesQ:实现业务规则和业务逻辑?
* 工作(work flowQ:实现多用戗多环节之间的业务处理流E?
* 文g理Qfile managementQ:理文档Q实现系l内部的文g传递?
* 报表/打印 Qreporting/printingQ:实现数据打印Q实现报表的定制和输出?
* 门户/信息发布 Qportal solutionQ:发布企业相关的信息、新闻,提供企业客户的访问入口?
* 通信Qcommunication/messagingQ:pȝ内部的消息、通知Q系l与外部角色Q比如企业客P之间通过不同通信媒介Q电话、网站、邮件等Q的互动?
* 特定行业/领域模块 Qbusiness modulesQ:实现特定行业、流域相关的业务模块?
以上诸方面中Q除了前四项目前主要由应用服务器解决之外Q其他的部分本n都是专门的Y件开发领域。框架的作用Q在于确定上q每U因素的具体技术实玎ͼq规定它们在pȝ中的l织方式和协作方式,从而给出完整的企业应用解决Ҏ?
企业应用框架的特炚w先是Q当应用框架定之后Q系l的整个构架Q也是Ml构已l固定。因此框架的选取往往是方案选型的首要问题?
其次Qh们常常听信“组件式开发”的一面之词,认ؓpȝ搭徏的过E类g搭积木,好像是用胶水代码Qglue codeQ拼合现成的lg或模块。其实采用框架开发时Q系l的构徏q程更类g填空——系l骨架早已完成,开发者填写特定的代码Q由pȝ来调用。《设计模式》中提到的“好莱坞原则Qthe Hollywood principle——Don't call us, we'll call youQ”,非常W合我们谈的q种情况。很多框架还允许下游厂商开发系l插Ӟplug-insQ,以满特定需要——这是另一UŞ式的“填I”?
另外Q对于实现具体应用系l的二次开发者来_不少d都无需通过~程实现。比如要l一个业务模型增M个新字段Q或是要讄一U新的工作流E,q些工作都可以通过单的囑Ş用户界面QGUIQ操作,或是修改部v描述W(DDQ,或是~写脚本来完成。也是_相当多(而不是全部)的开发Q务是通过声明/配置的(declarativeQ,而不是编E的QprogrammaticQ的方式实现的。系l往往会在启动或运行时载入相关的配|,据此实现特定的功能?

企业应用框架是菜场里的半成品。当我们面对要么自己下厨、要么去饭馆吃饭的选择Ӟ我们往往会采取这U省时省力的折衷Ҏ。但是选择之所以ؓ选择Q就因ؓ其中肯定包含Ҏ益和代h的权衡,都隐含着复杂的利弊关p(pros and consQ。下面我们也来检讨一下企业应用框架的情况Q?
ProsQ?
* ~短开发周?
毫无疑问Q采用框架的开发,要比一切从头做起快速、高效得多。通过一般化QgeneralizationQ和重用QreuseQ机Ӟ框架能最大限度地加快一个特定应用系l的实现?
* 客户?
如上所qͼZ框架的系l有很多功能通过配置而不是编E实玎ͼq样也给用户带来了一定便利。比如,企业内部的IT人员l过一定培训,p够自己完成一U新的工作流E的讄。这对于不断变化的业务需求是一个很理想的解x案?
* 不重新发明轮?
框架对于大量典型场景l出了最优的实践。在具体开发时Q与其无视前人的成果Q重新构思答案,不如套用q些成熟、稳定的做法。这不仅能加快开发进度,更能够提升系l的质量和健壮性?
* 可维护?知识׃n
完全通过委托开发完成的pȝ很难由其他厂商维护。框架往往是多个企业、大量开发者实늚成果Q因此能在一定程度上打破上述壁垒Q增q系l的可维护性。当框架使用者Ş成社Z后,q能实现更高层次上的知识׃n?
Cons:
* 太多
半成品L其代仗超市配好的一包菜里,老是又我们用不到的调料——但是我们却不得不ؓ之付贏V同PZ辑ֈ一般性和普适性,框架L紧凑、脓切的特定应用多出不少内容。二ơ开发完成后Q企业获得的只是一U特定的实现Q却要ؓ所有的客户化可能性付费,为所有用不上的功能付贏V这是一个相当让人尴的事实?
* 太少
框架L一U限制。就像半成品菜限制了我们的烹调方法,框架也限制了我们实际应用的可能性。当框架本n设计的够普适时Q我们不太会感到cM的限制。但是,情况往往正好相反——面对一个够特D的需求,二次开发者L一U冲破框架的渴望。最后的解决办法Q往往是狡计、妥协和框架补丁的结合体?
* 效率
上面说过Q基于框架的pȝ中,具体功能l常是通过配置实现的。与编码(hard-codedQ的方式相比较,q虽然能提供很大的灵zL,但也往往牺牲了运行时的效率?
* 锁定
一个采用特定框架的pȝ几乎肯定被锁定在q个厂商的品上。换a之,框架意味着all or nothing式的态度Q很难调和两U不同的框架Q各取所长,更难把应用系l从一个框架迁Ud另一个——这往往要求pȝ的全部改写?
* 学习曲线
一U框架也是一U方a。要_N特定框架的开发,你要熟悉其中的所有的用法、思\和弱炏V对于开发者,q也意味着比较陡峭的学习曲Uѝ?

3

上面谈到的种U弊端,q属于一般开发框架共有的~陷。对于市面上行的很多企业应用框架来_更大的问题是框架产品自n的hD高。我在别处也讲过Q企业应用系l项目往往不能靠运行安装程序,再作单的讄完成,而是一个复杂、Oѝ不断尝?修改的过E,或者说Q更q似于一U服务而不是简单的产品销售。但是框架厂商的产品Q或者说是半成品QhD高,l常p食了整个pȝ的大部分开发预,使方案Mh偏重于框架本w而不是后期开发。对于需求不甚符合原有框Ӟ需要大量开发的目Q或是需求本w不够清晰的目Q这都几乎肯定会D整个目的失败?

软g工程宗师F. Brooks曄表述q这样一个道理:没有银弹QNo Silver Bullet/NSBQ。那意思是_没有一U万应药能够戏剧性地提升软g开发的效率和质量。最q的很多舆论好像是专门和q个l典抬杠Q动不动把一些特D的解决Ҏ奉ؓ银弹。对于企业应用开发而言Q基于框架的开发模式是多种选择中的一U。在不少情况下,q种选择是不错的Q但同时应该留意随之而来的风险,更不该以为,选定了框架就一定能保证目成功?
很多企业应用目的难点,在于客户自n~Z规范的企业管理制度和合格的计机应用水^。客户不具备成型的业务流E,也无法明晰表N求,不知道怎样的应用Ş式对自n业务更合理:q种需求不清、或是需求剧烈变更的困境是困扰大量企业应用开发项目的症结。简a之,企业应用目的成败经常是“业务”、“技术”、“管理”三U因素共同作用的l果Q而单U引入框Ӟ只能解决部分“技术问题”。如果过于乐观地估计框架在其中的作用Q甚臌为它能解决Q何项目的M问题Q这对于本领域的各个环节Q厂商、项目开发商、企业客P都只能v到消极作用?
我个人的是:在搭Z业应用系l时Q针对应用情况不同、预?旉不同、对pȝ指标要求不同Q有多种替代Ҏ可以从中选择。当需求明、固定,又有现成产品完全满需要时Q或者当企业惌以极低预消除某个业务瓶颈时Q应该优先考虑现成产品Q在需求明、固定,但很难被现成产品完全覆盖Ӟ可以选择应用框架Qƈ由合格开发商完成实施Q在需求不够明,或者预感到需求会发生剧烈变更Ӟ采用开发源码的应用框架Q从而避免高昂的初期投资Qƈ“Y化”框架带来的U种限制Q是另一U可供选择的思\。还是那个比方,一K怎么吃,I竟是下馆子、买半成品或者全p己动手,q要视具体情形而定——我也希望,每个企业都能吃上可口心的应用大?

Binary 2006-08-24 15:08 发表评论
]]>
վ֩ģ壺 ԻƵ| ձƵ߹ۿ| AV벻߹ۿ| avվ߿| þúݺݸ߳޾Ʒ| ߲Ƶ| 91Ƶѹۿۿ| ŷղר| ĻƵ| 97Ƶѹۿ2| 鶹AVþþƷ | һëƬ| 㽶Ƶ߹ۿ| һ| AV߹ۿ| þòþüƵ7| ޾ƷAAAAƬAPP| ޹Ʒ߹ۿ| Ҹ߳Ƶ| 99Ƶѿ| aëƬƵѿ| ҹƷһţӰԺ| ޻ƻƻվ߹ۿ| պƵ߾ƷƵѹۿ| jizzӰӹۿվ| ҹþþþ| ޵һAVվ| ˳ɼƵ| ԸŮƵվҹ| 99߹ۿ| һƬѿ| Ҹ24p| ŮƷƵ| պvavaŷva| ޸ƵһƵƵ| 㽶žžþþƷ| ŮպѲ| ƷëٸAVѾþ | 99þ޾ƷѶ| þùŮѹۿƷ| AV˾Ʒպһ |