千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0
Seam是一个挺不错的框架,但是用netbeans来开发它,却有点难度,因为目前netbeans没有seam插件,不像Eclipse有jboss提供的官方插件,但是插件是死的,人是活的,它要能跑起起来,一定有它的配置,下面我们就用netbeans做为IDE来开发一个seam的应用.

当然,我们还有另外一个方法,那就是利用seam自带的seam-gen工具,生成一个工程的框架,然后可以用netbeans打开,但是有一些不太好的地方,那就是所有的工程内容都混到一起去了,WEB的工程和EJB的工程都在同一个工程下面,并且由于是基于ant的,所以工程的目录看得可能不太习惯.但它也有一个好处,那就是它会为你生成各种必须的配置文件,而不需要手工的编写,但是它的坏处就是,如果你后面想要添加EJB或者添加网页内容,就不太方便了,因为目录的组织是怪怪的,不是标准的Netbeans工程组织方式,所以我还是觉得自己建标准的netbeans工程,然后手工添加这些配置文件,并且这些配置文件也不一定需要自己全部手工编写,完全可以复制过来,然后在一些细节的地方改动一下就可以了.并且配置好以后,要添加工程内容,就可以完全按照netbeans标准工程的方式来添加了.

由于自己也是前几天接触的seam,所以错误之处难免,还望大家指出.

首先我们说一说周边的东西,那就是要添加哪些配置文件,配置文件大概是什么内容,以及各个工程都需要哪些库,这些是基础,也是很重要的,否则布署工程的时候就会出现一大堆的错误.
在正式工作之前,先准备好要用到的工具,我这里的工具列表如下:
1,Netbeans6.1,可以到http://www.netbeans.org下载,下载的时候,选择下载全部的版本,也就是最大的那个版本.
2,Jboss-4.2.2.GA,可以到http://www.jboss.org下载.
3,Jboss-seam-2.0.1.GA,也可以到http://www.jboss.org下载

以上具体地址我就不给了,可以自己到首页上去找,这个应该不难吧.
至于richfaces就不用准备了,seam里面都带了,什么spring,hibernate等等,它里面都有自带.

本文的流程如下,先是大概介绍每个工程的配置文件有哪些,以及它们需要哪些库文件,然后才真正写一个示例程序,所以前面的配置文件内容仅供参考,让我们知道,里面包括了哪些元素,因为实际的工程和它不一定是一样的.

准备工作做好以后,就可以开始了,打开我们熟悉的Netbeans,选择新建工程,然后选择新建Web工程,在建WEB工程的时候, 不要选择使用任何框架,因为现在还没有seam的netbeans插件,所以,一切的配置都得靠手写.建好了WEB工程以后,在WEB-INF文件夹下面添加如下文:pages.xml,components.xml,faces-config.xml,而web.xml是我们本来就有的,但是我们要修改一下里面的内容,好让它可以配合seam框架运行.更改好的web.xml内容大致如下:
如果你的WEB容器支持JAVAEE5,则下面的web-app version就可以等于2.5了,如果是支持J2EE1.4的,那么就要把它改成2.4的版本,建议是利用netbeans生成的web.xml基础上改,也就是只改内容,而不改xml的头部说明,也就是下面的web-app部份,一般不要去改,我们只改动里面的元素而已.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    xmlns
="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee 

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>
    
    
<display-name>Test</display-name>
    
    
<!-- Seam -->
     
    
<listener>
        
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
    
</listener>
    
    
<servlet>
        
<servlet-name>Seam Resource Servlet</servlet-name>
        
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
    
</servlet>
    
    
<servlet-mapping>
        
<servlet-name>Seam Resource Servlet</servlet-name>
        
<url-pattern>/seam/resource/*</url-pattern>
    
</servlet-mapping>
    
    
<filter>
        
<filter-name>Seam Filter</filter-name>
        
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
    
</filter>

    
<filter-mapping>
        
<filter-name>Seam Filter</filter-name>
        
<url-pattern>/*</url-pattern>
    
</filter-mapping>
    
    
<!-- 这里用了facelets的技术,我们的例子里面没有用到 -->
    
    
<context-param>
        
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        
<param-value>.xhtml</param-value>
    
</context-param>

    
<context-param>
        
<param-name>
            javax.faces.STATE_SAVING_METHOD
        
</param-name>
        
<param-value>server</param-value>
    
</context-param>

    
<context-param>
        
<param-name>facelets.DEVELOPMENT</param-name>
        
<param-value>true</param-value>
    
</context-param>
    
    
<servlet>
        
<servlet-name>Faces Servlet</servlet-name>
        
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
    
    
<servlet-mapping>
        
<servlet-name>Faces Servlet</servlet-name>
        
<url-pattern>*.seam</url-pattern>
    
</servlet-mapping>

    
<session-config>
        
<session-timeout>10</session-timeout> 
    
</session-config>    
    
</web-app>

在添加其它三个文件的内容之前,先说一下那三个文件是干什么用的,首先components.xml,这个文件里面写的是seam组件的配置,它是必不可少的,一般来说,它可以放在很多地方,但是最好还是放在WEB-INF下面,下面来看看它里面的内容:

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core
="http://jboss.com/products/seam/core"
            xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation
=
              "http://jboss.com/products/seam/core
               http://jboss.com/products/seam/core-2.0.xsd
               http://jboss.com/products/seam/components
               http://jboss.com/products/seam/components-2.0.xsd"
>
    
<core:init jndi-pattern="Seam6/#{ejbName}/local" debug="true"/>
    
<core:manager conversation-timeout="120000"/>
</components>

上面的配置几乎是最简单的配置,它给出了查找EJB的时候,JNDI的形式,以及对话(conversation)的超时时间.
然后我们再来看faces-config.xml,它是标准的JSF的说明文件,但是它在SEAM里面并没有完全起到在JSF里面的作用,在JSF里面,它定义backingbean,并且定义导航规则,但是在SEAM里面,它总是很小,backingbean不需要在这里定义了,因为在SEAM里面,我们可以把EJB做为backingbean,并且用注释的方式来指定它的名字以及范围,另外一个,导航规则也不用在这里定义了,我们可以用另外一个专门的文件来定义,那就是pages.xml,所以在SEAM的应用里面,虽然用到了JSF的技术,但是JSF的主要配置文件faces-config.xml却不用怎么配置了,当然,你也可以在这里面配置导航规则,只有当我们使用了facelets技术以后,才确定要在这个文件里面配置一些东西,否则,这个文件空在那里也没什么关系,facelets是SEAM框架里面推荐使用的技术,当然,我们也可以不用,也可以只用JSF,如果我们使用facelets的话,就需要要faces-config.xml里面添加如下的声明以支持facelets:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
              xmlns
="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee 

http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
>
    
    
<application>
        
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
    
</application>

</faces-config>

最后我们再来看pages.xml,它是定义页面之间的导航规则的,这个文件是可有可无的,SEAM启动的时候,会找这个文件,找到了就读里面的配置,找不到也没关系,就当什么也没有发生.
它的大概内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
       xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation
="http://jboss.com/products/seam/pages 

http://jboss.com/products/seam/pages-2.0.xsd"


       no-conversation-view-id
="/main.xhtml"
                 login-view-id
="/home.xhtml">

    
<page view-id="/register.xhtml">
    
        
<action if="#{validation.failed}"
           execute
="#{register.invalid}"/>
    
        
<navigation>
            
<rule if="#{register.registered}">
                
<redirect view-id="/home.xhtml"/>
            
</rule>
        
</navigation>
        
    
</page>

    
<page view-id="/home.xhtml">
    
        
<navigation>
            
<rule if="#{identity.loggedIn}">
                
<redirect view-id="/main.xhtml"/>
            
</rule>
        
</navigation>
        
    
</page>
    
    
<page view-id="/password.xhtml"
          login-required
="true">
    
        
<navigation>
            
<rule if="#{changePassword.changed}">
                
<redirect view-id="/main.xhtml"/>
            
</rule>
        
</navigation>
        
    
</page>

    
<page view-id="/main.xhtml" 
          login-required
="true">
    
        
<navigation from-action="#{hotelBooking.selectHotel(hot)}">
            
<redirect view-id="/hotel.xhtml"/>
        
</navigation>
        
        
<navigation from-action="#{bookingList.cancel}">
            
<redirect/>
        
</navigation>
        
    
</page>
    
    
<page view-id="/hotel.xhtml" 
          conversation-required
="true" 
          login-required
="true">
          
        
<description>View hotel: #{hotel.name}</description>
        
        
<navigation from-action="#{hotelBooking.bookHotel}">
            
<redirect view-id="/book.xhtml"/>
        
</navigation>
        
    
</page>

    
<page view-id="/book.xhtml" 
          conversation-required
="true" 
          login-required
="true">
          
        
<description>Book hotel: #{hotel.name}</description>
        
        
<navigation from-action="#{hotelBooking.setBookingDetails}">
            
<rule if="#{hotelBooking.bookingValid}">
                
<redirect view-id="/confirm.xhtml"/>
            
</rule>
        
</navigation>
        
    
</page>

    
<page view-id="/confirm.xhtml" 
          conversation-required
="true" 
          login-required
="true">
          
        
<description>Confirm booking: #{booking.description}</description>
        
        
<navigation from-action="#{hotelBooking.confirm}">
            
<redirect view-id="/main.xhtml"/>
        
</navigation>
        
    
</page>
    
    
<page view-id="*">
    
        
<navigation from-action="#{identity.logout}">
            
<redirect view-id="/home.xhtml"/>
        
</navigation>

        
<navigation from-action="#{hotelBooking.cancel}">
            
<redirect view-id="/main.xhtml"/>
        
</navigation>
        
    
</page>
    
    
<exception class="org.jboss.seam.security.NotLoggedInException">
        
<redirect view-id="/home.xhtml">
            
<message severity="warn">You must be logged in to use this feature</message>
        
</redirect>
    
</exception>

</pages>

一般来讲,SEAM可以配合richfaces来使用,这样可以补充标准的JSF组件不足的情况,并且richfaces和seam都是一家产品,所以运用起来可能会方便一些,在做SEAM应用的时候,推荐用richfaces做JSF的组件库,当然,你也可以用别的组件库,如apache的MyFaces.在配置文件建好模型以后,再为WEB工程添加项目所需要的库,一般来说,需要添加的库如下:
jboss-seam-debug.jar 调试的时候用
jboss-seam-ui.jar    调用seam的组件,比如<s:validate 等等
jsf-facelets.jar     JSF的facelets技术
richfaces-impl.jar   richfaces的实现库
richfaces-ui.jar     richfaces的UI库
richfaces-api.jar    richfaces的API库
jboss-el.jar         jboss的EL库
当然,根据不同的应用,可能所要包含的库会有点不同,具体库的依赖性,可以查看SEAM的官方说明.WEB项目的部份大概就这些,下一章,我们再说一说EJB项目的部份.







尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2008-05-06 15:53 千里冰封 阅读(4178) 评论(5)  编辑  收藏 所属分类: JAVAEENetbeans

FeedBack:
# re: 使用Netbeans开发Seam应用(一)
2008-05-06 17:01 | 日月雨林
如果要用RichFaces的话,现在已经有NetBeans的插件了,
http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=8934

如果有兴趣可以看看Geertjan's 的博客!里面介绍了如何使用这个插件!
http://blogs.sun.com/geertjan/entry/richfaces_for_netbeans_ide_6

还有ICEfaces,现在官方只有6.0的插件,还没有6.1的。我想应该很快就会有了,呵呵!
http://www.icefaces.org/main/downloads/os-downloads.iface  回复  更多评论
  
# re: 使用Netbeans开发Seam应用(一)
2008-05-06 17:46 | 千里冰封
@日月雨林
是的,但是现在还没有Seam的插件啊,所以配置有点麻烦,并且用Richfaces插件不一定适用于Seam,没配好可能会库冲突  回复  更多评论
  
# re: 使用Netbeans开发Seam应用(一)
2008-05-06 17:54 | 日月雨林
还有个好消息就是现在已经有人在开发seam的NetBeans的插件了
不过现在还没有什么动静,邮件列表业很长时间没有更新了
https://nbseam.dev.java.net/
还有myfaces
https://nbmyfaces.dev.java.net/  回复  更多评论
  
# re: 使用Netbeans开发Seam应用(一)
2008-05-06 18:25 | 日月雨林
这个或许可以

28 November 2007
Many people ask me, when a version of facelets support will be available for NetBeans 6.0. Here you can donwload it.

https://nbfaceletssupport.dev.java.net/files/documents/5684/77220/nbfaceletssupport-0-6.zip
  回复  更多评论
  
# re: 使用Netbeans开发Seam应用(一)
2009-08-06 09:33 | 鱼中鱼
怎么会找不到类呢?org.jboss.seam.servlet.SeamListener
我有jboss-seam2.1.jar这个文件啊

java.lang.NoClassDefFoundError: javassist/util/proxy/MethodHandler
at org.jboss.seam.contexts.Contexts.destroy(Contexts.java:243)
at org.jboss.seam.contexts.Lifecycle.endApplication(Lifecycle.java:56)
at org.jboss.seam.contexts.ServletLifecycle.endApplication(ServletLifecycle.java:135)
at org.jboss.seam.servlet.SeamListener.contextDestroyed(SeamListener.java:40)
at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:3882)
at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4523)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4387)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:516)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
Caused by: java.lang.ClassNotFoundException: javassist.util.proxy.MethodHandler
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 29 more  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: