`
benqend
  • 浏览: 32074 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Seam的HelloWorld 使用Seam开发简单的Web应用

    博客分类:
  • seam
 
阅读更多
Seam版Hello World

我们下面使用Seam框架开发一个HelloWrld的例子。

Seam的难不再Seam本身,而在于Seam使用的内容,Seam使用JSF和EJB3,所以想要使用Seam必须首先学会JSF和EJB3,另外Seam的难还在于Seam的开发和部署结构,Seam程序被推荐以ear的形式部署,而ear又是由war,jar构成,这本身给Seam的使用增加了难度,虽然这些配置文件在多个不同的Seam应用之间大同小异,但是毕竟给初学者增加了难度。现在我们说一说war,jar和ear的结构。



war,jar和ear都是和zip兼容的压缩格式,所以这些文件都可以使用winzip或者winrar直接打开查看结构,一个典型的war的结构为

app.war

    **/*.jsp

    **/*.js

    WEB-INF

        web.xml

        classes

        lib



一个ejb类型的jar的典型结构为:

app.jar

     META-INF

         ejb-jar.xml

     **/*.class 



ear的结构有若干个war或者jar构成。



我们接下来将要将的helloworld应用程序的结构如下,我们会逐步讲解这些内容

helloworld.ear│
├─app.jar
│  │  seam.properties
│  │
│  ├─com
│  │  └─jpleasure
│  │      └─seam
│  │          └─helloworld
│  │                  Manager.class
│  │                  ManagerAction.class
│  │                  Person.class
│  │                
│  └─META-INF
│          ejb-jar.xml
│          MANIFEST.MF
│          persistence.xml
│        
├─app.war
│  │  hello.jsp
│  │  index.html
│  │
│  ├─META-INF
│  │      MANIFEST.MF
│  │    
│  └─WEB-INF
│          components.xml
│          faces-config.xml
│          navigation.xml
│          web.xml
│        
├─lib
│      jboss-el.jar
│      jboss-seam.jar
│    
└─META-INF
        application.xml
        MANIFEST.MF



这里先留一个问题,为什么所有的class文件都不在war文件内部,而在jar的内部呢?

提示:jboss的classloader机制。



程序的业务

这个程序的业务很简单,只有一个页面,这个页面上面是一个输入组件,下面是一个列表组件。可以将自己的名字填写在输入组件中,点击提交按钮,将自己的名字登录到数据库中,同时回到这个页面,在下面的列表中输出数据库中所有的名字,这个例子来源于Michael JunTao Yuan的《JBoss Seam simplicity and power beyond java ee》请大家参考。



数据库

我们使用HSQL的内存数据库,每次启动的时候在内存中创建,每次停止的时候废弃所有的数据,HSQL的特点是开发非常的方便。

我们首先定义一个EJB3的Entity Bean用来记录录入的人员信息,代码为:



package com.jpleasure.seam.helloworld;



import org.jboss.seam.annotations.Name;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;



@Entity
@Name("person")
public class Person implements Serializable {
    private long id;
    private String name;


    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

这里需要介绍一些基本的内容,

1. Entity需要实现Serializable接口,这是EJB3 的要求,对于可能存在远程调用的情况也是业务的要求。

2. @Entity 这个标注(Annotation)标记了Person类似一个Entity Bean,也就是对应着数据库中的一张表,在默认的情况下这个表和这个类同名,所以数据库中的表名为Person 。

3. @Name("person")是Seam的标注,在这个应用程序中以后可以使用person这个字符串来关联到Person的示例。

4. @Id 说明private long id表示的属性在数据库中对应为主键

5. @GeneratedValue表示这个主键会自动生成



上述代码中最关键的是Name这个标注,在后续的代码中你将会看到如何使用Name这个标注。



业务处理

业务处理在Seam中使用EJB3中的Session Bean充当,使用Session Bean可以利用EJB容器提供的各种特定,例如声明式的事务,安全等。

使用Session Bean一般需要定义一个接口,用来约束所能够提供的服务,这个接口为:



package com.jpleasure.seam.helloworld;


import javax.ejb.Local;
@Local
public interface Manager {
    public String sayHello();
}

一些说明:

1. @Local说明了这是这个Session Bean的本地接口



业务实现类(Session Bean)

package com.jpleasure.seam.helloworld;



import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;



@Stateless
@Name("manager")
public class ManagerAction implements Manager {

    @In
    @Out
    private Person person;

    @Out
    private List<Person> fans;

    @PersistenceContext
    private EntityManager em;

    public String sayHello() {
        em.persist(person);
        person = new Person();
        fans = em.createQuery("select p from Person p")
                .getResultList();

        return null;
    }
}

一些说明:

1. @Stateless 标记这个类为Stateless 类型的Session Bean。

2. @Name(“manager”)是Seam组建,标记了在Seam框架环境下ManagerAction这个Stateless Session Bean。

3. @In表示这个对象可以被注入,也就是大家常说的依赖注入,在运行的时候每每生成一个ManagerAction,就会创建一个名字叫person的对象(@In没有参数的时候绑定属性名字相同的对象),也就是上面定义的Person这个EJB3的Entity Bean。

3. @Out表示,这个属性所在的类(ManagerAction)的方法执行完毕之后,这个标注标记的属性会被注出到后续使用这个属性的地方。

   对于这个地方需要解释一下,当用户提交的信息的时候,这些信息会给放在Person类型的实例中,放在ManagerAction的person属性中,这是注入

   当sayHello执行完毕之后,person被赋值new Person(),这个时候上次所填写的内容将会被new Person()替代,后续使用到person属性的地方那个将会使用new Person(),而不会使用原来的输入内容,这叫做注出

    使用@In和@Out可以达到bijection的效果



我们接着来看看JSF页面

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

<html>
<body>
<f:view>

    <f:verbatim>
        <h2>Seam Hello World</h2>
    </f:verbatim>

    <h:form>
        <f:verbatim>
            Please enter your name:<br/>
        </f:verbatim>

        <h:inputText value="#{person.name}" size="15"/><br/>
        <h:commandButton type="submit" value="Say Hello"
                         action="#{manager.sayHello}"/>
    </h:form>

    <f:subview id="fans"
               rendered="#{!empty(fans)}">
        <f:verbatim>
            <p>The following fans have said "hello" to JBoss Seam:</p>
        </f:verbatim>

        <h:dataTable value="#{fans}" var="fan">
            <h:column>
                <h:outputText value="#{fan.name}"/>
            </h:column>
        </h:dataTable>
    </f:subview>

</f:view>
</body>
</html>

一些说明:

1. 关于表达式语言,例如 #{person.name}表示跟person的name属性绑定,根据上面@Name的定义,我们知道跟Person的一个实例绑定。

    #{manager.sayHello} 表示调用manager的sayHello方法,也就是ManagerAction的sayHello方法。

    #{fans} 由于ManagerAction的fans使用了@Out标注,且诶有制定名字,所以fans在表达式语言中表示ManagerAction的属性,这里只是用来表示,没有输入,所以我没有使用绑定这个词,绑定的含义是提交的时候赋值,输出的时候显示。



再说一说配置文件:

WEB-INF/web.xml文件是Web项目集成Seam的切入点,参看一下代码,特别是黑体部分:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/navigation.xml</param-value>
    </context-param>

    <!-- Seam -->
    <listener>
        <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
    </listener>

    <context-param>
        <param-name>
            javax.faces.STATE_SAVING_METHOD
        </param-name>
        <param-value>server</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>

</web-app>



WEB-INF/navigation.xml定义了JSF的画面迁移关系,由于只有一个页面,所以不用定义迁移关系:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config
    PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
    "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>
  <!-- single page app, no navigation rules -->
</faces-config>

WEB-INF/navigation.xml是JSF的基本配置文件,这里也为空,因为真的没什么可以配置的,我们的程序是Hello World。

<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">

</faces-config>



WEB-INF/component.xml是Seam的基本配置文件,定义的内容如下,这些内容在不同的应用之间只有简单的变化,例如jndi-patter中helloworld替换为新的项目名字。

<?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="helloworld/#{ejbName}/local" debug="false"/>

  <core:manager conversation-timeout="120000"/>

</components>



conversation-timeout我们在后续状态部分讲解。



seam.properties文件用来定义seam的一些基本配置,这里暂时不需要,所以seam.properties为空。



ejb模块中,META-INF/ejb-jar.xml文件,用来定义EJB,这里由于这里都是用了标注(@Stateless,@Entity等)所以这里没有ejb的定义,只有Seam的一个拦截器的定义,对所有EJB的调用都需要经过SeamInterceptor,这是Seam对于EJB项目的切入点。



<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar 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/ejb-jar_3_0.xsd"
         version="3.0">
  <interceptors>
     <interceptor>
       <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
     </interceptor>
   </interceptors>

  <assembly-descriptor>
    <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>
        org.jboss.seam.ejb.SeamInterceptor
      </interceptor-class>
    </interceptor-binding>
  </assembly-descriptor>
</ejb-jar>

ejb模块中,META-INF/persistence.xml文件,这个文件根据EJB规范的要求,为EJB3中的Entity定义持久化单元(简单的说是数据访问的上下文环境),包含数据库,提供者等信息。

<persistence>
  <persistence-unit name="helloworld">
    <provider>
      org.hibernate.ejb.HibernatePersistence
    </provider>
    <jta-data-source>java:/DefaultDS</jta-data-source>
    <properties>
      <property name="hibernate.dialect"
          value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto"
          value="create-drop"/>
      <property name="hibernate.show_sql" value="true"/>
    </properties>
  </persistence-unit>
</persistence>



ear的lib目录中包含了我们需要使用的类库文件,分别是jboss-el.jar和jboss-seam.jar.

ear的META-INF目录包含了对这个ear项目定义的application.xml文件,内容为:

<application>
  <display-name>Seam Hello World</display-name>

  <module>
    <web>
      <web-uri>app.war</web-uri>
      <context-root>/helloworld</context-root>
    </web>
  </module>

  <module>
    <ejb>app.jar</ejb>
  </module>

  <module>
    <ejb>lib/jboss-seam.jar</ejb>
  </module>

</application>

现在回答前面我们设置的问题。



在JBoss服务器启动的时候Load的继承机构为EJBCLassLoader是WEBClassLoader的父类,所以EBJClassLoader装在的内容在WEBClassLoader装在的内容中是可见的。


添加Facelets功能

1. 追加Facelets功能需要添加新的类库,这些类库文件需要放在WEB-INF/lib目录下,这些文件的名字是:

   jboss-seam-ui.jar

   jboss-seam-debug.jar

   jsf-facelets.jar

2. 需要配置JSF如何处理文件的方式,使用xhtml代替jsp文件:

faces-config.xml文件追加如下内容:

  <application>
    <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
  </application>

3. 还需要在web.xml添加如下内容:

  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
  </context-param>

4. 将hello.jsp修改为hello.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
<body>

<h2>The Facelets Demo</h2>

<h:form>
    Please enter your name:<br/>
    <h:inputText value="#{person.name}" size="15"/><br/>
    <h:commandButton type="submit" value="Say Hello"
                     action="#{manager.sayHello(person)}"/>
</h:form>

<f:subview id="fans"
           rendered="#{!empty(fans)}">
    <p>The following people have said "hello" to JBoss Seam:</p>
    <h:dataTable value="#{fans}" var="fan">
        <h:column>
            <h:outputText value="#{fan.name}"/>
        </h:column>
    </h:dataTable>
</f:subview>

</body>
</html>

Link:http://blog.csdn.net/struts2/article/details/1882980
分享到:
评论

相关推荐

    Seam 例子 Hello World

    Seam 例子 Hello World,算是对seam的使用的一个最基本的入门吧

    JBOSS.SEAM.WEB应用开发

    JBOSS.SEAM.WEB应用开发 中文版 (美)MichaelYuan.

    深入浅出JBoss Seam

    什么是Seam? 1. 整合和强化Java EE框架 ...Seam Hello World 1. 创建一个数据模型 2. 将数据模型映射到web表单 2. 处理web事件 4. 更易于理解的seam编程模型 5. 配置和打包 6. 为何这么简单?

    Seam2.0GA 中文开发指南

    Seam 中文开发指南 seam中文文档

    JBOSS_SEAM_WEB应用开发

    什麽是seam?当中有大家熟知的helloword范本供给入门都快速夺seam做一个了解,是一本很好的荐绍书喔…

    SEAM 中文开发指南

    SEAM 中文开发指南(官方)

    使用JBoss Seam简化Web开发(入门教学Flash)

    使用JBoss Seam简化Web开发 (入门教学Flash) 对于刚接触的比较好。 seam下载可以从以下地址下载:http://www.jboss.com/products/jbosside/downloads

    seam 2中文手册

    seam下一代web开发框架

    Seam 2.1 安全模块框架

    Seam2.10安全API为你使用Seam开发的应用程序提供了大量与安全认证相关的特性,包含了以下几块: • 安全验证 - 一个可扩展的、基于JAAS的安全验证层,允许用户to authenticate against any security provider • ...

    Seam简单入门学习教程.docx

    java JBoss Seam 是 EJB3 和 JSF 中间的粘合剂,这是 Jboss Seam 最基本的和最广泛的应用。通过被 Seam 管理的组件,Seam 允许这两个框架之间无缝(不是有意双关的)的集成。它为整个 web 应用拓展了基于注解的 EJB3 ...

    Seam框架文档简述

    Seam全称是Jboss Seam,是一个Java EE 5框架。它通过把JSF与EJB3.0组件合并在一起,以及利用JDK5.0的Annotation技术,从而为开发基于Web的企业应用程序提供一个最新的模式。

    seam 2.1 参考手册

    seam 2.1 GA 最新版出来了! Seam 2.1打算支持Wicket。作为第一选择的显示层,这包含着一些技术细节:我们所作的是让你能够...JBoss Seam 2.1在性能上也有很大改进,它将会成为令我们非常期待的Java企业应用开发框架。

    java seam开发环境搭建

    1、 Java环境的安装和配置 2、 JBoss环境的安装和配置 3、 Ant环境的安装和配置 4、 Seam环境的安装和配置 5、 Eclipse环境及JBoss Tools 插件的安装和配置

    Seam2.XWebDevelopment.pdf 英文原版

    Seam 2.X Web Development

    jboss-seam2.1

    Seam 是一种业级 企 Java 的应规用程序框架。它的灵感源自下列原 : 只有一种“工具” Seam为 应 业务业业 义 种统 组 你的 用程序中所有的 定 了一 一的 件模型。 Seam组件可能是 态义 关关 态 有状 的,包含与几...

    Seam Framework Web开发宝典(第2版).zip

    Seam Framework Web开发宝典(第2版).zip

    Seam Carving的C++实现代码

    SeamCarving的C++实现代码,使用opencv库。包含完整项目工程及测试图像,可直接使用

    Seam全称是Jboss Seam,是一个Java EE 5框架

    它通过把JSF与EJB3.0组件合并在一起,以及利用JDK5.0的Annotation技术,从而为开发基于Web的企业应用程序提供一个最新的模式。Seam可以让你把EJB组件直接绑定到JSF页面。Seam还可以把JBPM流程定义直接地集成到应用...

    jboss seam

    这是中文手册,Seam为持久化集成了JPA和Hibernate 3,为轻量化的异步性集成了EJB ... Seam组件可以同时作为一个Web Service进行调用,异步地从客户端JavaScript或者Google Web Toolkit,或者当然也可以直接从JSF调用。

    Java Web开发学习路线图(JBoss Seam方向)

    Java Web开发学习路线图(JBoss Seam方向)

Global site tag (gtag.js) - Google Analytics