- 浏览: 62782 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
hjing315:
还是不行啊 2种方式都试过了
no XXX in java.library.path的解决办法 -
goodayforme:
还有个解决方案
直接把××.dll文件复制放置到jre/bi ...
no XXX in java.library.path的解决办法 -
chunming7:
也有可能是在catalina里设置的jvm内存超过了机器内存的 ...
tomcat启动一闪而过 -
wushanlang:
楼主 那如果 是部署的时候报这个错呢
no XXX in java.library.path的解决办法
为了将 Struts Web 应用程序与 JSF 集成,遵循以下步骤:
- 将 struts-faces.jar 文件与特定于 JSF 的 JAR(jsf-api.jar、jsf-ri.jar) 添加到 Web 应用程序的 WEB-INF/lib目录中。
- 如果准备使用 JSF 和 JSTL,则将特定于 JSTL 的 JAR(jstl.jar、standard.jar)添加到 WEB-INF/lib 文件夹中。这一步只有在部署到常规 Tomcat 时才会需要。JWSDP 已经提供了这些 JAR。
- 修改 Web 应用程序部署描述符 ( /WEB-INF/web.xml)以便有一个 Faces Servlet 项, 如清单 5 所示。
- 修改 JSP 页面以使用 JSF 和 Struts-Faces 标记而不是 Struts 标记。特别是用 Struts-Faces 相应标记替换
html、b
ase、
form
和errors
标记。用 JSF 相应标记替换text
、textarea
和radio
标记。Struts-Faces 没有单独针对这些的标记。尽管没有要求,但是您可能还会考虑用 JSTL 标记替换 Struts Logic 标记。 - 对于每一个使用 JSF 标记的 JSP,修改 struts-config.xml 文件以在指向该 JSP 的 Action Mapping 中的 global-forwards和 local-forwards中加入前缀 /faces。
- 如果 Web 应用程序使用了任何您创建的自定义组件,那么您就需要用 JSF 实现的默认 RenderKit 注册它们。可以通过在 WEB-INF 文件中创建一个 faces-config.xml 文件、并增加每一个组件和 renderer 的项做到这一点。不过,要记住 faces-config.xml 文件已经绑定在 struts-faces.jar 文件中了。您必须从 struts-faces.jar 文件中提出它、加入自己的内容并将它放到 WEB-INF文件夹中。
清单 5. 在 web.xml 中声明 FacesServlet
<servlet>
<servlet-name>faces</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- JavaServer Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
Struts-Faces 库提供了 Struts 与 JSF 之间的一个高效的桥梁,使得在 J2EE Web 应用程序中拥有丰富的表示层成为现实。您可以通过在组合体中添加 Titles 使表示层更丰富,这样不仅得到了 Struts 和 JSF 组合的好处,而且还可以高效地重复使用不同的 JSP 页面,因为它们将由可以根据需要添加或者删除的组件部分或者 tiles 所构成。
本文已经展示了 Struts 和 JSP 的集成,您会想将 Tiles 加入到组合中只是小事一桩,是不是?
不幸的是,JSF 仍然处于早期阶段,还没有给出最后的发布。基于这一考虑,Struts-Faces 集成软件开发仍然在不断地发展以包括 JSF 的不同的功能,并且还没有支持 Tiles。
Struts 和 Tiles 可以无缝地共同工作,但是在集成之路上您会遇到路障。在下面几小节中,您会看到在与 Tiles 共同使用 Struts-Faces 集成库时经常遇到的问题的汇总。对于每一个问题,我们详细说明了一个修改 Struts-Faces 类的解决方案。我们将用一个航班搜索示例解释这个解决方案。
清单 6 展示了航班搜索页面的布局。注意我们称它为航班搜索页面而不是 FlightSearch.jsp。这是因为 FlightSearch JSP 是用户在 foobar 旅行 Web 站点看到的合成页面的主体。
现在,我们保持实际的 FlightSearch.jsp 不变。我们将随着进展改变它。在您这边,也需要用航班搜索页的定义创建一个 Tiles 定义文件。清单 7(紧接着清单 6)展示了 Tiles 定义文件中航班搜索页的一项。注意对带有 extends
属性的主布局模板的重复使用。
在清单 6 和 7 后是每一个可能的挑战。
<%@ taglib uri="http://jakarta.apache.org/struts/tags-faces"prefix="s" %>
<!-- Layout component parameters: header, menu, body, footer -->
<s:html>
<head>
<title> <tiles:getAsString name="title"/></title>
<s:base/>
</head>
<body>
<TABLE border="0" width="100%" cellspacing="5">
<tr>
<td><tiles:insert attribute="header"/></td>
</tr>
<tr>
<td><tiles:insert attribute="body"/></td>
</tr>
<tr><td><hr></td></tr>
<tr>
<td><tiles:insert attribute="footer" /></td>
</tr>
</TABLE>
</body>
</s:html>
<definition name="foobar.master-layout"
path="/faces/layout/MasterLayout.jsp">
<put name="title" value="Welcome to Foo Bar Travels" />
<put name="header" value="/faces/common/header.jsp" />
<put name="footer" value="/faces/common/footer.jsp" />
<put name="body" value="" />
</definition>
<!-- Definition for Flight Search Page -->
<definition name="/foobar.flight-search"
extends="foobar.master-layout">
<put name="body" value="/faces/FlightSearch.jsp" />
</definition>
这是您在试图访问航班搜索表单时马上会看到的第一个问题。小心查看堆栈跟踪。您会看到问题出在类 com.sun.faces.lifecycle.ViewHandlerImpl
上。这是一个实现了 ViewHandler
接口的 JSF-RI 类。
图 2展示了 ViewHandler
所扮演的角色。这是一个将请求转发给下一页的类。在转发请求时,它不在转发前检查响应的状态 -- 这只有在使用 Tiles 时才会发生,因为 Tiles 内部将 JSP 页面包括在响应内,而 JSF-RI 在第一次转发后提交响应、然后试图再次转发给下面的包括 JSP 的 Tiles。
要解决这个问题,必须创建一个自定义的 ViewHandler
实现,它将检查响应的状态以确定它是否提交过。如果响应没有提交过,那么请求就转发给下一页,否则,就加入请求并显示相应的 JSP。我们将创建一个名为 STFViewHandlerImpl
的类,它实现了 ViewHandler
接口并实现了所需要的方法 renderView()。
清单 8 展示了 STFViewHandlerImpl
中的 renderView()
方法:
Tree tree = context.getTree();
String requestURI = context.getTree().getTreeId();
rd = request.getRequestDispatcher(requestURI);
/** If the response is committed, include the resource **/
if( !response.isCommitted() ) {
rd.forward(request, context.getServletResponse());
}
else {
rd.include(request, context.getServletResponse());
}
现在您实现了自己的 ViewHandler
,如何通知 JSF-RI 使用您的 ViewHandler
而不是默认的实现呢?要回答这个问题,就必须理解 FacesServlet
的工作过程。
在 Faces 初始化过程中, FacesServlet
会让 LifecycleFactory
实现返回 Lifecycle
类的一个实现,如清单 9 所示:
清单 9. FacesServlet 中 Faces 的初始化
LifecycleFactory factory = (LifecycleFactory)
FactoryFinder.getFactory("javax.faces.lifecycle.LifecycleFactory");
//Get the context param from web.xml
String lifecycleID =
getServletContext().getInitParameter("javax.faces.lifecycle.LIFECYCLE_ID");
//Get the Lifecycle Implementation
Lifecycle lifecycle = factory.getLifecycle(lifeCycleID);
Lifecycle
实现对象拥有在呈现响应阶段要使用的 ViewHandler
。您可以通过对 Lifecycle
实现调用 setViewHandler
方法让自己的 ViewHandler
实现成为默认的。
现在问题变为如何得到默认 Lifecycle
实现?回答是不需要这样做。只要创建一个新的实现并用一个惟一 ID 注册它,如清单 10 所示:
清单 10. 注册自定义 ViewHandler 和 Lifecycle
LifecycleFactory factory = (LifecycleFactory)
FactoryFinder.getFactory("javax.faces.lifecycle.LifecycleFactory");
//Create a new instance of Lifecycle implementation -
//com.sun.faces.lifecycle.LifecycleImpl
//According to the documentation, factory.getLifecycle("STFLifecycle")
//should work, but JSF-RI has a defect.
//Hence this workaround of creating a RI class explicitly.
LifecycleImpl stfLifecycleImpl = new LifecycleImpl();
//Create a new instance of our STFViewHandler and set it on the Lifecycle
stfLifecycleImpl.setViewHandler(new STFViewHandlerImpl());
//Register the new lifecycle with the factory with a unique
//name "STFLifecycle"
factory.addLifecycle("STFLifecycle", stfLifecycleImpl);
lifecycleId
硬编码为 STFLifecycle
。实际上不是这样。当您回过头分析 清单 9时就会清楚。 FacesServlet
从在 web.xml 文件中声明的上下文参数中得到名为 javax.faces.lifecycle.LIFECYCLE_ID
的 lifecycle ID,如下所示:<param-name>javax.faces.lifecycle.LIFECYCLE_ID</param-name>
<param-value>STFLifecycle</param-value>
</context-param>
因为 FacesServlet
取决于其初始化时的 Lifecycle
实现,在 清单 10中展示的代码应该在 FacesServlet
初始化之前执行。通过创建另一个 servlet 并在 FacesServlet
之前初始化它而做到这一点。
但是一种更聪明的办法是实现一个 ServletContextListener
接口。这个类声明两个方法: contextInitialized()
和 contextDestroyed()
,在 Web 应用程序被创建及 Web 应用程序被销毁之前会分别调用它们。因而 清单 10中的代码在 contextInitialized()
方法中执行,而自定义 ViewHandler
已经用标识名 STFLifecycle
注册到 Lifecycle
,并且可被 FacesServlet
使用。 ServletContextListener
类本身是在 web.xml 文件中声明的,如下所示:
<listener-class>foo.bar.stf.application.STFContextListener
</listener-class>
</listener>
这不是注册一个带有自定义 ViewHandler
的 Lifecycle
惟一方法。事实上 FactoryFinder
实现了自己的发现算法以发现 Factory
对象,包括 LifecycleFactory
。这些机制按照顺序包括在系统属性中查看工厂实现类名的机制、faces.properties file、或者 1.3 Services 发现机制( META-INF/services/{factory-class-name}
)。不过,我们讨论的这种机制是最容易的,也是最不具有破坏性的一种。
在解决了提交响应的问题后,单击任何一个 Tiles 特定的链接或者输入一个会呈现 Faces 响应的 URL。在这里,可以输入显示 FlightSearchForm
的 URL。
在这样做了以后,您会得到一个 foobar.flight-search - 404 Resource Not Found 错误。 foobar.flight-search
是航班搜索页面的 Tiles 定义的名字。 FacesRequestProcessor
不能处理 Tiles 请求(因为它扩展的是RequestProcessor
而不是 TilesRequestProcessor
),所以会得到错误。
为解决这个问题,我们将创建一个名为 STFRequestProcessor
(表示 Struts-Tiles-Faces Request Processor)的新的请求处理程序。现在我们将拷贝 FacesRequestProcessor
的所有代码到这个新类中。惟一的区别是 STFRequestProcessor
继承的是 TilesRequestProcessor
而不是继承常规的 RequestProcessor
。这个新的 RequestProcessor
可以处理 Tiles 请求。清单 11 详细列出了这个 STFRequestProcessor
:
清单 11. STFRequestProcessor.java
正如您所知道的, Struts
框架的 RequestProcessor
是在 struts-config.xml 文件中指定的。将下面的项添加到 struts-cinfig.xml
文件中后, STFRequestProcessor
就成为处理程序:
<controller processorClass="foobar.stf.application.STFRequestProcessor" />
由于 STFRequestProcessor
的作用,这时您就可以浏览并查看航班页面了。不过,在提交航班搜索表单时,您会得到返回来的同一个表单,而且没有页头和页脚!并且没有验证错误。事实上,根本就没有进行验证!
为了了解到底发生了什么事情,我们用浏览器回到航班页面并检查 HTML 源代码。您会看到像下面这样的一项:
|
注意表单 action 是指向 JSP 页而不是一个 .do 的。啊哈!这就是问题!这不是由于同时使用 Tiles 和 Struts-Faces 而带来的新问题,Struts-Faces 的默认行为是让 JSP 与表单 action 有同样的名字。这种行为在有单一的 JSP 页(如在前面的 Struts-Faces 例子中)时没有问题。 清单 3展示了原来的 FlightSearch.jsp,让我们继续并像下面这样修改 action:
|
当然,光有这种修改并不能解决问题。作了这种改变后,您就会发现 STFRequestProcessor
不能找到 ActionForm
。显然还需要其他的改变。
不过,在继续往下之前,看一下图  5。它显示了在呈现负责 Struts-Faces 表单的 faces 时相关的一系列事件。这与 图 3相同,除了在 FormComponent
中突出显示的方法 createActionForm()。
由 Struts-Faces API 提供的 FormComponent
类是 javax.faces.component.UIForm
的特殊子类,它支持请求或者会话范围的表单 Bean。
图 5. 呈现 Struts-Faces 响应
单击这里以查看该图。
正如您所看到的, createActionForm()
方法使用 action 名以从 Struts 配置文件中得到 ActionMapping
。因为没有对于 /listFlights.do 的 ActionMapping
,所以 Struts 不能找到 ActionForm。
这个问题的解决方法是使用 org.apache.struts.util.RequestUtils
。 RequestUtils
中的 static 方法 getActionMappingName()
具有足够的智能解析映射到正确 ActionMapping
的路径( /x/y/z)或者后缀( .do)。
清单 12 以粗体显示对 createActionForm
方法的改变。我们没有对 Struts-Faces 中的 FormComponent
作这些改变,而是通过继承 FormComponent
并覆盖 createActionForm()
方法创建了一个新的 STFFormComponent。
清单 12. FormComponent 中修改过的 createActionForm() 方法
|
对新的 STFFormComponent
还要作一项改变。Struts-Faces 将 action 名本身作为表单名。这需要改变,因为 action 带有后缀 .do,而表单名没有后缀 .do。所以我们在 STFFormComponent
上增加一个名为 action
的新属性,并覆盖 getAction()
和 setAction()
方法。
必须对 FormRenderer
(以 HTML 格式呈现 Struts-Faces 表单的类)的 encodeBegin
方法进行类似于 清单 10所示的修改。
同样,通过继承 FormRenderer
做到这一点。此外,还必须改变写出到 HTML 的表单 action。清单 13以粗体详细列出了这些改变:
|
FormTag的改变
正如您已经知道的,当组件和 renderer 改变时,标记也必须改变。在这里,通过继承 Struts-Faces 中的 FormTag
创建一个新的标记: STFFormTag
。不必改变任何功能,只要覆盖 getComponentType()
和 getRendererType()
方法。清单 14 展示了从 STFFormComponent
覆盖的方法:
|
自定义组件和 renderer 必须在 faces-config.xml 文件中声明,这样 JSF 框架才可以初始化并使用它们。现在我们已经创建了一个新组件 STFFormComponent
和一个新 renderer STFFormRenderer
。
现在我们将在 faces-config.xml 文件中增加一个声明,如清单 15 所示。 component-class 是组件的完全限定类名。 component-type 指的是在 STFFormTag
( 清单 12)中用于标识组件的名字。以类似的方式发现和解释 renderer。注意 faces-config.xml 文件是在 struts-faces.jar 文件中的。从 struts-faces.jar 文件中取出这个文件并将它放到 Web 应用程序的 WEB-INF文件夹中并修改它。
清单 15. 在 faces-config.xml 中声明自定义组件和 renderer
|
您不会在这个示例 Struts-Faces 应用程序中看到 struts-faces.tld 文件,它打包到了 struts-faces.jar 文件中。打开并分析这个文件。它声明了一个名为 org.apache.struts.faces.taglib.LifecycleListener
的类,这个类实现了 ServletContextListener
并初始化 FacesRequestProcessor
。
因为希望使用新的 STFRequestProccessor
,所以必须将这个文件从 struts-faces.jar 文件中删除,将它放到 Web 应用程序的 WEB-INF 文件夹中,并删除侦听器声明。如果让这个 tld 文件保持原样,那么在初始化这个 Web 应用程序时,除了 STFRequestProcessor
,还会实例化一个 FacesRequestProcessor。
|
程序所有页面浏览都是相对于布局页面计算的。如果加入的 base href
标记只达到 Web 应用程序上下文则会很方便,像这样:
|
我们可以通过定制 Struts-Faces BaseTag
做到这一点。这个类中的改变相当微不足道。只须在 base href 中去掉 HttpServletRequest.getServletPath()
。
因为这些改变是与显示相关的,所以为它创建了一个名为 STFBaseRenderer
的新 renderer。这个新标记称为 STFBaseTag
,它声明 STFBaseRenderer
作为其关联的 renderer。不需要新的组件。
有了这些信息,通过继承 BaseTag
并覆盖 getRendererType
方法创建新的 STFBaseTag
,如下所示:
|
恭喜!经过这些相对较小的修改,您已经成功地集成了 Struts、Tiles 和 JSF,并保留了您以前在这些技术上所做的所有投资。本文演示了如何将 JSF 强大的前端能力、 Tiles 的内容格式编排优势以及 Struts 控制器层的灵活性结合在一个包中,使得创建一个 J2EE Web 应用程序成为一项更容易的任务。
padding-top: 0px; padding-right: 0px; padding-left: 0px; padding-bottom: 6px; clear: both; text-align: left; margin-top: 0px; margin-right: 0px; marg
相关推荐
- **Hibernate**:作为ORM框架,Hibernate提供了一种高级的面向对象的数据持久化机制,能够将Java对象自动映射到关系型数据库表。它支持懒加载、缓存机制等多种优化手段,有效提高数据访问性能。 #### 二、JPA+EJB+...
#### 二、JSF与Struts2的对比 ##### 1. 规范性与标准性 - **JSF**:作为Java EE的一部分,JSF更符合企业级应用开发的标准和规范,提供了丰富的组件库和事件驱动机制,使得前端界面的开发更加便捷高效。 - **Struts2...
Struts2遵循MVC原则,将业务逻辑(Model)、视图(View)和控制器(Controller)明确分开,提高代码的可读性和可维护性。 **发展历程**: - **静态HTML页面**:早期的网页开发主要依靠静态HTML,功能有限。 - **...
Struts通过Action和ActionForm组件处理HTTP请求,将数据传递到模型,并由控制器决定视图如何显示。此外,Struts还提供了国际化、异常处理和标签库等功能,提高了开发效率和代码复用性。 **Hibernate框架**是一个...
4. **添加struts.xml**:将配置文件struts.xml添加到项目的classpath中。 5. **创建示例项目**:根据需求构建简单的Hello World示例。 以上是对文档标题、描述及相关内容中提到的知识点的详细解释。通过这些内容的...
Java EE的核心技术包括Servlets、JSP、EJB、JPA、JMS、JSF等,这些技术覆盖了从Web层到业务逻辑层再到数据访问层的整个应用架构。 ### Struts框架 Struts框架是一个开源的MVC(Model-View-Controller)框架,主要...
这里我们采用struts来UI层,虽然比起Tapestry以及JSF这些事件驱动的表现层技术而言,Struts的设计显得有些老土,但它目前仍是表现层事实上的标准,在这一层还采用JSTL标签库,使它具有可移植性、可跨平台。...
9. **JSF、Spring MVC与Struts**:这些是JavaEE应用中常用的MVC框架,帮助开发者构建用户界面。JSF是官方标准,Spring MVC是Spring框架的一部分,Struts是早期流行的选择,但现在更多地被Spring MVC取代。 10. **...
在学习和开发J2EE应用程序时,需要掌握这些核心概念,并理解如何将它们整合到实际项目中。此外,对于大型项目,还需要考虑性能优化、安全性、测试策略以及持续集成和部署流程。通过不断的实践和学习,开发者可以掌握...
Java作为一种跨平台的编程语言,具备面向对象、分布式、健壮、安全、中性结构、可移植、解释型、高性能、多线程和动态等特性,这些特征使得Java在各种计算环境中具有广泛的应用。 Java的历史始于1990年代,由Sun ...
【Java 面向对象编程基础】 Java 是一种由 Sun Microsystems 在1995年推出的高级编程语言,其设计初衷是安全、...同时,Java还提供了丰富的框架和库,如Servlet、JSP、EJB、Struts和JSF,用于构建更复杂的企业级应用。
还将学习Struts、WebWork、Tapestry、JSF、Velocity、Freemarker等框架,以及Hibernate和iBatis等ORM工具。重点将放在Struts1&2的应用开发上,包括MVC理论、国际化支持、异常处理和测试。对于Hibernate,学员将学习...
在J2EE平台上,开发者可以使用一系列服务、APIs和协议来构建可移植、安全、可伸缩和高效率的应用程序。以下是一些关键的J2EE知识点,这些内容可能在教程中有所涉及: 1. **Servlet**:Servlet是Java语言写成的...
10. **Struts、Spring和JSF框架**:这些是J2EE领域常见的开发框架,Struts提供了一种基于MVC的控制层实现,Spring是一个全方位的框架,包括依赖注入、AOP(面向切面编程)和完整的Web MVC支持,JSF(JavaServer ...
- Hibernate能够将Java对象直接映射到数据库表,以及对象属性到表字段上,简化了数据持久化操作。 - Hibernate支持多种数据库,具有良好的可移植性。 **2. Hibernate工作流程** - **读取配置文件**:首先读取...
4. 集成其他框架:Servlet可以与Spring、Struts、JSF等MVC框架集成,提升应用的复杂性和灵活性。 5. 使用Servlet 3.0及以上版本的特性,如注解配置、异步处理等,简化代码并提高性能。 【Servlet Filter编程】 ...
1. **平台无关性**:Java的跨平台能力使得在不同操作系统上的程序能无缝通信,提高了代码的可移植性。 2. **安全机制**:Java具有强大的安全特性,可以在运行时对程序进行权限检查,确保网络通信的安全性。 3. **...
J2EE是一个多层架构的平台,它为开发和部署可移植、高效且安全的网络应用程序提供了全面的框架。 一、J2EE架构概述 J2EE架构由多个层次组成,包括客户端层、Web层、业务逻辑层(EJB层)和数据访问层。这些层次协同...
尽管后来出现了WebWork、Tapestry和Sun的JSF等竞争框架,Struts依然保持着其在Java Web应用框架中的领导地位。 Hibernate的出现则在很大程度上改变了J2EE开发的思维模式。它作为ORM(对象关系映射)工具,对比EJB的...