花了几天的时间研究了一下EJB的使用,一直以来都主要是在写终端中的程序,对Java框架的相关的开发非常不熟悉,中间遇到了不少麻烦,还好总算都攻克了。写篇日志记录一下。


经验总结

  • 为什么选择JBoss5.1:

从8開始最新的jboss已经改名为WildFly了,jboss5还是09年的东西.刚開始的时候我准备用WildFly部署EJB的,由于没有经验并且相关的资料非常少.仅仅能换用更老一点的Jboss5

  • 怎样打包公布:

    ejb的公布非常easy,仅仅要将打包好的代码(jar,ear,war ….)复制到 ==~/jboss-5.1.0.GA/server/default/deploy/==里,jboss就会自己主动检測到变动自己主动载入

MyEclipse可保存后就自己主动公布,Eclipse-J2EE版似乎没有这个功能,只是即使是MyEclipse的自己主动公布也可能存在问题,比較稳妥的办法是自己写一个ant的自己主动编译文件.

  • ant配置文件的写法

    ant能够帮助完毕编译,复制,粘贴,打包,部署等反复的操作,以下是一份ant的模版.

<?

xml version="1.0" encoding="UTF-8"?

>
<project name="EJB" basedir=".">
<property name="src.dir" value="${basedir}/ejbModule" />
<property name="jboss.home" value="/home/ckboss/jboss-5.1.0.GA/" />
<property name="jboss.server.config" value="default" />
<property name="build.dir" value="${basedir}/build" /> <path id="build.classpath">
<fileset dir = "${jboss.home}/client">
<include name="*.jar" />
</fileset>
<pathelement location ="${build.dir}" />
</path> <target name="prepare">
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}" />
</target> <target name="compile" depends="prepare" description="编译">
<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath refid = "build.classpath" />
</javac>
</target> <target name = "ejbjar" depends="compile" description="创建EJB">
<jar jarfile="${build.dir}/${ant.project.name}.jar">
<fileset dir="${build.dir}">
<include name="**/*.class" />
</fileset>
</jar>
</target> <target name="deploy" depends="ejbjar" description="公布">
<copy file ="${build.dir}/${ant.project.name}.jar"
todir = "${jboss.home}/server/${jboss.server.config}/deploy/" />
</target> <target name="undeploy" description="卸载">
<delete file="${jboss.home}/server/${jboss.server.config}/deploy/${ant.project.name}.jar" />
</target> </project>

详解一下ant的使用:

1.在工程文件夹下新建一个叫 build.xml 的文件填上以上内容就能够了,然后会发现xml变成了小蚂蚁的图标,这样就能够了.这个build.xml所在的位置就叫做basedir , 其它文件能够依据这个相对路径来定位.

2.代码的解释:

<project name="EJB" basedir=".">
<property name="src.dir" value="${basedir}/ejbModule" />
<property name="jboss.home" value="/home/ckboss/jboss-5.1.0.GA/" />
<property name="jboss.server.config" value="default" />
<property name="build.dir" value="${basedir}/build" />

这一段主要定义了一些变量的路径,project name 就是工程的名字,也就是${ant.project.name}

src.dir:是源代码位置

jboss.home: jboss部署在哪

jboss.server.config: jboss的启动配置

build.dir: 生成的jar包的位置

<path id="build.classpath">
<fileset dir = "${jboss.home}/client">
<include name="*.jar" />
</fileset>
<pathelement location ="${build.dir}" />
</path>

所须要的jar包的位置,这里包括了jboss下client的全部jar包,假设引入了别的jar包能够手动的包括进去.

<target name="prepare">
<delete dir="${build.dir}" />
<mkdir dir="${build.dir}" />
</target>

这里定义了一个叫prepare的过程,功能是删除可能存在的build.dir,再新建一个build.dir

    <target name="compile" depends="prepare" description="编译">
<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath refid = "build.classpath" />
</javac>
</target>

一个叫做 compile 的过程,这个过程的执行须要prepare在它前面执行.

编译全部src里的文件,编译到build里

<target name = "ejbjar" depends="compile"  description="创建EJB">
<jar jarfile="${build.dir}/${ant.project.name}.jar">
<fileset dir="${build.dir}">
<include name="**/*.class" />
</fileset>
</jar>
</target>

创建一个jar包到build.dir中,包括了build.dir里的class类

<target name="deploy" depends="ejbjar" description="公布">
<copy file ="${build.dir}/${ant.project.name}.jar"
todir = "${jboss.home}/server/${jboss.server.config}/deploy/" />
</target> <target name="undeploy" description="卸载">
<delete file="${jboss.home}/server/${jboss.server.config}/deploy/${ant.project.name}.jar" />
</target>

公布和卸载,在jboss上的部署非常easy,公布仅仅要把jar复制到jboss里相应的deploy文件夹里就能够了,卸载就是把这个jar包移除就能够了.

3.怎样使用ant?



点击XML文件,选择大纲视图,选择所需的步骤,右键用ant执行

这种界面就是执行成功了

  • jboss的 jndi

jndi比較难以理解,各种服务器的调用也个不一样,放弃WildFly的一个原因就是不知道怎么用jndi,也找不到靠普的文档

但jboss5中的jndi使用比較简单,

控制台上的输出就是某个应用的jndi

怎样获取jndi,

外部调用ejb就要用Context找到相应的jndi,并转换成相应的接口,获取Contex的參数设置各种服务器是不一样的,jboss5中的一种调用方法是:

Properties properties = new Properties();
properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs", "org.jboss.naming rg.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
InitialContext ctx = new InitialContext(properties);

为了写起来更方便,也能够直接在src下建立一个叫jndi.properties的配置文件,这样就不用写一堆properties了

这个配置文件内容例如以下:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming rg.jnp.interfaces
java.naming.provider.url=localhost\:1099

有了这个配置文件仅仅要写一句就能够了

InitialContext ctx = new InitialContext();

有了ctx后就能够将相应的jndi找到并转换成接口了

例如以下,调用一个远程接口

AccountServerRemote asl = (AccountServerRemote) ctx.lookup("AccountServer/remote");
  • jndi的数据库使用

用实体bean来完毕对数据库的持久化操作.由于曾经用过hibernate在处理数据库的时候就自然想到了用hibernate.于是想法设法把hibernate往EJB里弄,忙活了一下午,最后无果而终,看了JPA之后才知道JPA採用的就是hibernate的实现…..

ejb使用数据库第一步就是连接写一个*-ds.xml文件,这个能够在jboss文件夹下 ==jboss-5.1.0.GA/docs/examples/jca/== 找到,以下是一个msql-ds.xml的文件

<?

xml version="1.0" encoding="UTF-8"?>

<!-- See http://www.jboss.org/community/wiki/Multiple1PC for information about local-tx-datasource -->
<!-- $Id: mysql-ds.xml 88948 2009-05-15 14:09:08Z jesper.pedersen $ -->
<!-- Datasource config for MySQL using 3.0.9 available from:
http://www.mysql.com/downloads/api-jdbc-stable.html
--> <datasources>
<local-tx-datasource>
<jndi-name>tomysql</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/USERS</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>javaTest</user-name>
<password>123456</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
<!-- should only be used on drivers after 3.22.1 with "ping" support
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
-->
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->
<!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
--> <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>

改成自己的内容后,粘贴到==jboss-5.1.0.GA/server/default/deploy/==,

同一时候要把相应的驱动放到==/jboss-5.1.0.GA/server/default/lib/==

同一时候在项目文件夹META-INF下要新建一个persistence.xml的文件,

内容例如以下:

<?

xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="ejbdb" transaction-type="JTA">
<jta-data-source>java:tomysql</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit> </persistence>

能够看到,这里直接使用hibernate的配置就能够了…..

注意一定要保证打包后persistence.xml在META-INF中….

ejb里实体bean开发是使用注解的,基本上和hibernate一样,可是用一个叫 @PersistenceContext private EntityManager em;的东西进行操作(就像hibernate里的session),用相似与HQL用一种叫JPQL的东西查询…..

  • 消息bean

    一个点对点的消息bean

首先须要新建一个叫*-service.xml的文件新建一个队列,

文件内容例如以下:

<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=myMDB">
<attribute name="JNDIName">queue/myMDB</attribute>
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
</mbean>
</server>

新建一个叫做queue/myMDB的jndi

发送一个消息:


InitialContext ctx = new InitialContext(); QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("ConnectionFactory");
QueueConnection conn = factory.createQueueConnection();
QueueSession session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
Destination destination = (Destination) ctx.lookup("queue/myMDB");
MessageProducer producer = session.createProducer(destination); producer.send(session.createTextMessage(MSG)); session.close();
conn.close();

接受一个消息:

@MessageDriven
(
mappedName = "jms/MessageDriverBean",
activationConfig =
{
@ActivationConfigProperty
(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty
(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty
(propertyName = "destination" , propertyValue = "queue/myMDB")
}
) //重载的onmessage方法
@Override
public void onMessage(Message msg) {
TextMessage tmsg = (TextMessage)msg;
try {
System.out.println(tmsg.getText()); FileWriter fw = new FileWriter("/home/ckboss/桌面/Log.record", true);
fw.append(tmsg.getText());
fw.close(); } catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
  • EJB工程的结构

我也不知道EJB的正确姿势是什么样的…

公布一个EJB后,其它的java项目能够通过Jndi找到相应的bean,可是须要在源代码中包括这个bean的接口.

为了方便,以下的登陆应用放在了一个EJB中.

一个登陆应用

包括了一个实体bean和一个点对点的消息驱动bean,由client包调用,假设登陆成功会通过消息驱动bean发送一条消息,并被接受到记录一条记录

文件结构

➜  EJB_LogIn  tree

└── ejbModule
├── client
│ ├── client1.java
│ └── LogInClient.java
├── db
│ ├── Account.java
│ ├── AccountServer.java
│ ├── AccountServerLocal.java
│ └── AccountServerRemote.java
├── jndi.properties
├── META-INF
│ ├── MANIFEST.MF
│ └── persistence.xml
└── msg
├── MessageDriverBean.java
└── QueueSender.java 14 directories, 32 files

EJB_LogIn.zip下载1

EJB_LogIn.zip下载2

一个基于JBoss5.1+EJB3.0 登陆应用的更多相关文章

  1. 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架 - LinFx

    LinFx 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架,遵循领域驱动设计(DDD)规范约束,提供实现事件驱动.事件回溯.响应式等特性的基础设施.让开发者享受到正真意义的面向对象 ...

  2. 分享一个基于 ABP(.NET 5.0) + vue-element-admin 管理后台

    1.前言 分享一个基于ABP(.NET 5.0) + vue-element-admin项目.希望可以降低新手对于ABP框架的学习成本,感兴趣的同学可以下载项目启动运行一下.对于想选型采用ABP框架的 ...

  3. 一个基于thinkphp的微信授权登陆功能

    共享一份基于thinkphp开发的用户授权登陆的功能代码,本实例使用thinkphp的第三方微信公众平台PHP-SDK,地址https://github.com/dodgepudding/wechat ...

  4. 基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。

    基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...

  5. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

  6. Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

  7. 一个基于Net Core3.0的WPF框架Hello World实例

    目录 一个基于Net Core3.0的WPF框架Hello World实例 1.创建WPF解决方案 1.1 创建Net Core版本的WPF工程 1.2 指定项目名称,路径,解决方案名称 2. 依赖库 ...

  8. 痞子衡嵌入式:kFlashFile v1.0 - 一个基于Flash的掉电数据存取方案

    大家好,我是痞子衡,是正经搞技术的痞子.今天给大家带来的是痞子衡的个人小项目 - kFlashFile. 痞子衡最近在参与一个基于 i.MXRT1170 的项目,项目有个需求,需要在 Flash 里实 ...

  9. 开源低代码平台开发实践二:从 0 构建一个基于 ER 图的低代码后端

    前后端分离了! 第一次知道这个事情的时候,内心是困惑的. 前端都出去搞 SPA,SEO 们同意吗? 后来,SSR 来了. 他说:"SEO 们同意了!" 任何人的反对,都没用了,时代 ...

随机推荐

  1. Java代理模式精讲之静态代理,动态代理,CGLib代理

    代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...

  2. IoC简介

    控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来降低程序代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency Injecti ...

  3. delphi 新版数组操作

    https://www.cnblogs.com/xalion/p/4283491.html

  4. day13 函数模块之序列化 random 模块 os模块 sys模块 hashlib模块 collections模块

    json import json dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串 ...

  5. 【亲测可行】Dev c++调试、运行报错解决方法总结

    一.编译后  0错误 0警告,但是开始出现‘‘停止运行’’或者进行输入时出现‘‘停止运行’’ 可能的原因: 结构体指针为空,但调用了其成员. 有些scanf语句中忘记添加取址符. 无法跳出递归. 二. ...

  6. hdu 6441 Find Integer(费马大定理+勾股数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6441(本题来源于2018年中国大学生程序设计竞赛网络选拔赛) 题意:输入n和a,求满足等式a^n+b^ ...

  7. 企业级监控nagios实践

    nagios 监控服务应用指南 小区:视频监控,保安 企业工作中为什么要部署监控系统 监控系统相当于哨兵的作用,监控几百台上千台服务器,监控系统非常重要. 监控系统都需要监控 1. 本地资源:负载up ...

  8. JavaScript基础对象---Number

    一.创建Number实例对象 /** * new Number(value); * value 被创建对象的数字值 * * Number 对象主要用于: 如果参数无法被转换为数字,则返回 NaN. 在 ...

  9. 使用 ES (elasticsearch) 搜索中文

    1.创建索引 curl -XPUT http://172.16.125.139:9200/ques2.创建索引类型 curl -XPOST http://172.16.125.139:9200/que ...

  10. kafka flumn sparkstreaming java实现监听文件夹内容保存到Phoenix中

    ps:具体Kafka Flumn SparkStreaming的使用  参考前几篇博客 2.4.6.4.1 配置启动Kafka (1) 在slave机器上配置broker 1) 点击CDH上的kafk ...