Java EE EJB拦截器教程和示例

在此示例中,我们将看到如何在EJB中使用拦截器并使用简单的Web应用程序对其进行测试。

1.简介

顾名思义,当您想拦截对EJB方法的调用时,将使用拦截器。 如果为Bean声明一个拦截器,则每次调用该Bean的方法时,该拦截器的一个方法都将拦截该方法。 这意味着执行直接进入了拦截器的方法。 然后,拦截方法可以决定是调用被拦截的EJB方法还是简单地替换它。

您可能会发现上述行为类似于面向方面的编程哲学,并且您是正确的。 尽管这两种技术的实现方式完全不同,但事实是它们可以用于相同的目的。 例如,当您想在执行Beans方法之前或之后记录某些内容时。 或者,当您要强制执行有关方法调用的特定策略时,例如,身份验证,输入检查等。当然,EJB可以具有一系列拦截器,这些拦截器将按特定顺序拦截该方法。

在这个示例中,我们将创建一个EAR项目和一个EJB项目,它们将托管我们的EJB和拦截器,以及一个动态Web应用程序,它将托管一个Servlet以测试上述行为。 我们将使用Eclipse Java EE IDE 4,3 Kepler和Glassfish 4.0作为容器。

2.创建一个新的企业应用程序项目

创建一个名为EJBInterceptorEAR的新企业应用程序项目。在Eclipse IDE中,选择File-> EJBInterceptorEAR > Enterprise Application Project并填写表单,然后单击Finish:

新耳计划

3.创建一个新的EJB Projet

创建一个名为InterceptorsEJB的新EJB项目。 我们将基于此创建会话bean。 转到文件->新建-> EJB项目并填写表单。 注意选择“ Add EAR Project”,然后选择“ EJBInterceptorEAR ”作为EAR项目名称:

新项目

单击下一步两次,然后选择创建EJB客户端JAR以及生成ejb-jar.xml部署描述符:

4.创建一个简单的拦截器类

我们将定义一个只有一种方法的简单拦截器。 在InterceptorsEJB项目的ejbModule文件夹下,创建一个名为com.javacodegeeks.enterprise.ejb.interceptor的新包,并创建以下类:

SimpleInterceptor.java:

package com.javacodegeeks.enterprise.ejb.interceptor;import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;public class SimpleInterceptor {@AroundInvokepublic Object intercept(InvocationContext context) throws Exception {System.out.println("SimpleInterceptor - Logging BEFORE calling method :"+context.getMethod().getName() );Object result = context.proceed();System.out.println("SimpleInterceptor - Logging AFTER calling method :"+context.getMethod().getName() );return result;}
}

请注意,使用@AroundInvoke注释的public Object intercept 。 这意味着该特定方法将在EJB方法调用上进行拦截。 重要的是要解决这样一个事实,即拦截器类可以具有任意数量的方法,但是@AroundInvoke只能注释一个方法。

可以将intercept方法的InvocationContext参数用于两个目的。 您可以提取与被拦截的EJB方法有关的有用信息(例如,我们使用getMethod().getName() API调用链来获取被拦截方法的名称),也可以使用proceed() API继续执行方法。 如果链中没有拦截器,则此方法会将执行流切换到链中的下一个拦截器,或切换到实际的拦截的EJB方法。 该方法将返回EJB方法调用的结果。 但是我们不知道返回的类型,因此proceed()返回一个Object实例。 如果您确实知道EJB方法的返回类型,则可以将proceed()的结果转换为该特定类型,然后根据需要使用该实例。 注意, intercept方法还返回实际EJB调用的结果。 这将被传递到拦截器链中的下一个拦截器,或者如果没有其他拦截器则传递给客户端。

因此,在调用实际的EJB方法之前要执行的任何业务逻辑都应放在调用proceed()之前。 因此,在调用proceed()之后,将要执行的代码放入实际的EJB方法之后。 当然,如果需要,您可以一起绕过EJB方法的常规执行。

4.创建一个简单的EJB

这是将使用上述拦截器拦截其方法的EJB。 在InterceptorsEJB项目的ejbModule文件夹下,创建一个名为com.javacodegeeks.enterprise.ejb的新包,并创建以下类:

package com.javacodegeeks.enterprise.ejb;import javax.ejb.Stateless;
import javax.interceptor.Interceptors;import com.javacodegeeks.enterprise.ejb.interceptor.SimpleInterceptor;@Stateless
@Interceptors(SimpleInterceptor.class)
public class SimpleEJB {public String printMessage(String message) {System.out.println(" Executing method : printMessage" + message);return "Message is "+message;}}

如您所见,我们已使用@Interceptors(SimpleInterceptor.class)批注标记了该类。 这意味着该类的所有方法将被SimpleInterceptor拦截

让我们创建一个简单的Servlet来测试所需的功能。

5.创建一个新的动态Web项目

转到文件->新建->动态Web项目。 填写表单,确保您选中“将项目添加到EAR”,并把EJBInterceptorEAR作为“ EAR项目名称”:

新动态网络应用

单击“完成”后,转到项目资源管理器,然后右键单击“ Project InterceptorTesting然后转到“属性”->“部署程序集”->“添加”->“项目”->“ EJBInterceptorEAR

部署组装

6.创建新的Servlet

转到 InterceptorTesting Web项目并创建一个名为 TestSerlvet 的新Servlet :

新丝绒

让我们看一下该Servlet的代码:

TestServlet.java:

package com.javacodegeeks.enterprise.servlet;import java.io.IOException;import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.javacodegeeks.enterprise.ejb.SimpleEJB;@WebServlet("/TestSerlvet")
public class TestSerlvet extends HttpServlet {private static final long serialVersionUID = 1L;public TestSerlvet() {super();}protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {System.out.println("Hello from Servlet");InitialContext ic;SimpleEJB bean;String message = request.getParameter("printMessage");if (message != null) {try {ic = new InitialContext();bean = (SimpleEJB) ic.lookup("java:global/EJBInterceptorEAR/InterceptorTesting/SimpleEJB!"+ "com.javacodegeeks.enterprise.ejb.SimpleEJB");bean.printMessage(message);} catch (NamingException e) {e.printStackTrace();}}}
}

正如你可以看到我们简单的解析printMessage查询参数和我们的价值传递给printMessage的方法SimpleEJB

提示: 如果您在找出EJB PassivationObject的可移植JNDI名称时遇到麻烦,请在部署项目时查看Glassfish的日志或输出,您会发现这样的一行:2014-01-09T15:14:14.627 + 0200 | INFO :EJB5181:EJB SimpleEJB的便携式JNDI名称:java:global / EJBInterceptorEAR / InterceptorTesting / SimpleEJB!
com.javacodegeeks.enterprise.ejb.SimpleEJB,java:global / EJBInterceptorEAR / InterceptorTesting / SimpleEJB)

7.测试

您可以在Glassfish上部署您的应用程序并发出以下请求:

http://localhost:8080/InterceptorTesting/TestSerlvet?printMessage=Hello%20From%20JCG

如果您在控制台上观看Glassfish的输出,则会看到:

2014-01-09T17:43:14.356+0200|INFO: Hello from Servlet
2014-01-09T17:43:14.357+0200|INFO: Logging BEFORE calling method :printMessage
2014-01-09T17:43:14.357+0200|INFO: Executing method : printMessage : Hello From JCG
2014-01-09T17:43:14.357+0200|INFO: Logging AFTER calling method :printMessage

8.多个拦截器

继续,在com.javacodegeeks.enterprise.ejb.interceptor包下的InterceptorsEJB项目中创建另一个新的Interceptor。

这里是 :

SecondInterceptor.java:

package com.javacodegeeks.enterprise.ejb.interceptor;import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;public class SecondInterceptor {@AroundInvokepublic Object intercept(InvocationContext context) throws Exception {System.out.println("SecondInterceptor - Logging BEFORE calling method :"+context.getMethod().getName() );Object result = context.proceed();System.out.println("SecondInterceptor  -Logging AFTER calling method :"+context.getMethod().getName() );return result;}
}

这是SimpleEJB

SimpleEJB.java:

package com.javacodegeeks.enterprise.ejb;import javax.ejb.Stateless;
import javax.interceptor.Interceptors;import com.javacodegeeks.enterprise.ejb.interceptor.SecondInterceptor;
import com.javacodegeeks.enterprise.ejb.interceptor.SimpleInterceptor;@Stateless
@Interceptors({SimpleInterceptor.class, SecondInterceptor.class})
public class SimpleEJB {public String printMessage(String message) {System.out.println(" Executing method : printMessage" + message);return "Message is "+message;}}

现在,如果我们再次发出相同的请求:

http://localhost:8080/InterceptorTesting/TestSerlvet?printMessage=Hello%20From%20JCG

如果您在控制台上观看Glassfish的输出,则会看到:

2014-01-09T17:59:55.647+0200|INFO: Hello from Servlet
2014-01-09T17:59:55.659+0200|INFO: SimpleInterceptor - Logging BEFORE calling method :printMessage
2014-01-09T17:59:55.659+0200|INFO: SecondInterceptor - Logging BEFORE calling method :printMessage
2014-01-09T17:59:55.660+0200|INFO: Executing method : printMessageHello From JCG
2014-01-09T17:59:55.660+0200|INFO: SecondInterceptor  -Logging AFTER calling method :printMessage
2014-01-09T17:59:55.660+0200|INFO: SimpleInterceptor  -Logging AFTER calling method :printMessage

9.方法层拦截器

有时,您可能不希望所有的bean方法都被拦截。 您可以通过注释来选择要拦截的方法,而不是整个类。

让我们看看如何:

SimpleEJB.java:

package com.javacodegeeks.enterprise.ejb;import javax.ejb.Stateless;
import javax.interceptor.Interceptors;import com.javacodegeeks.enterprise.ejb.interceptor.SimpleInterceptor;@Stateless
public class SimpleEJB {@Interceptors(SimpleInterceptor.class)public String printMessage(String message) {System.out.println(" Executing method : printMessage : " + message);return "Message is " + message;}public String printSomething(String message) {System.out.println(" Executing method : printSomething :" + message);return "Message is " + message;}}

TestServlet.java:

package com.javacodegeeks.enterprise.servlet;import java.io.IOException;import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.javacodegeeks.enterprise.ejb.SimpleEJB;@WebServlet("/TestSerlvet")
public class TestSerlvet extends HttpServlet {private static final long serialVersionUID = 1L;public TestSerlvet() {super();}protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {System.out.println("Hello from Servlet");InitialContext ic;SimpleEJB bean;String message = request.getParameter("printMessage");if (message != null) {try {ic = new InitialContext();bean = (SimpleEJB) ic.lookup("java:global/EJBInterceptorEAR/InterceptorTesting/SimpleEJB!"+ "com.javacodegeeks.enterprise.ejb.SimpleEJB");bean.printMessage(message);bean.printSomething("This method is not intercepted");} catch (NamingException e) {e.printStackTrace();}}}}

现在,如果我们再次发出相同的请求:

http://localhost:8080/InterceptorTesting/TestSerlvet?printMessage=Hello%20From%20JCG

如果您在控制台上观看Glassfish的输出,则会看到:

2014-01-09T19:52:00.909+0200|INFO: Hello from Servlet
2014-01-09T19:52:00.920+0200|INFO: SimpleInterceptor - Logging BEFORE calling method :printMessage
2014-01-09T19:52:00.921+0200|INFO: Executing method : printMessage : Hello From JCG
2014-01-09T19:52:00.921+0200|INFO: SimpleInterceptor  -Logging AFTER calling method :printMessage
2014-01-09T19:52:00.921+0200|INFO: Executing method : printSomething :This method is not intercepted

下载Eclipse项目

这是EJB拦截器上的一个示例。 下载本教程的Eclipse项目: EJBInterceptor.zip

翻译自: https://www.javacodegeeks.com/2013/07/java-ee-ejb-interceptors-tutorial-and-example.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac python Tesseract 验证码识别

Tesseract 简介 Tesseract(/tesərkt/) 这个词的意思是"超立方体",指的是几何学里的四维标准方体,又称"正八胞体"。不过这里要讲的,是一款以其命名的开源 OCR(Optical Character Recognition, 光学字符识别) 软件。 所谓…

如何判断html页面停止滚动?

写在开始的话 查遍的文献,没有找到js或者jquery定义好的方法可用,最后迫不得已自己写了个方法。(如果哪位同学知道有其他方法,欢迎讨论) 代码 var count_index 0;$(window).scroll(function(e) {if(count_index 0) {…

php 打乱数组顺序_PHP实现大转盘抽奖算法

php中文网最新课程每日17点准时技术干货分享本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法,希望对大家学习PHP抽奖有所帮助。流程:1.拼装奖项数组;2.计算概率;3.返回中奖情况。代码如下:中奖概率 v 可以…

linux线程基础篇----线程同步与互斥

linux线程基础----线程同步与互斥 一、同步的概念 1.同步概念 所谓同步,即同时起步,协调一致。不同的对象,对“同步”的理解方式略有不同。如,设备同步,是指在两个设备 之间规定一个共同的时间参考;数据库同…

分布式系统开发注意事项

开发分布式软件系统时,要考虑许多因素。 如果您甚至不知道第一句话中我在说什么,那么让我为您提供一些见解,示例以及有关分布式系统的实例。 总览 分布式系统是指多个物理硬件设备与单独的离散用户交互并通过这些硬件设备协作以为这些离散的…

只需5步,轻松创建HTML5离线应用

1 – 添加 HTML5 doctype第一件要做的事情是创建一个符合规范的 HTML5 文档。HTML5 doctype 相比于 xhtml 版本的 doctype 而言&#xff0c;要简单明了得多&#xff1a; <!DOCTYPE html><html> ...创建一个名为 index.html 的文档&#xff0c;或者猛击这里下载这份…

Java EE 7发布–反馈和新闻报道

Java EE 7已经存在了几天。 我们所有人都有机会观看直播活动或可用的重播 。 最后的MR版本完成了将他们的工作推向JCP的过程&#xff0c;基本上是一个总结。 是时候反思发生的事情以及我对此的想法了。 启动活动中的社区参与 这不是一个大秘密。 即使Oracle的Java EE 7发行可以…

HTML5中的本地数据库-Web SQL Database

html5增加新的特性&#xff0c;那就是增加了本地存储&#xff01;改善用户体验&#xff0c;或许html5会带着我们走进新的互联网时代。 下面看看怎样操作web 数据库吧&#xff01;&#xff01;首先新建数据库&#xff01; var db window.openDatabase("mydata", &quo…

解决swiper-slide在ion-slide-box不滑动的问题(暂且这么描述)

1&#xff0c;开发环境ionic1angularjs1 嗯对的版本都是最低版本 页面结构想要完成的功能是这样的&#xff08;比较丑 &#xff0c;不接受批评&#xff0c;捂脸&#xff09; 大致如图 代码结构&#xff1a; <ion-slide-box><ion-slide> //列表 <div class"…

Win10 系统直接在目录下打开cmd

每次用cmd命令&#xff0c;就要定位到当前文件夹&#xff0c;很麻烦&#xff0c;于是想了下&#xff0c;可不可以直接定位到要操作的文件夹&#xff0c;百度了一下&#xff0c;果然&#xff0c;度娘没有让我失望&#xff0c; 美滋滋的试了下。真的可以。在此记录下&#xff0c;…

今日学到乱写

EXPLAIN 直接上图 一个个说&#xff1a; select_type 查询中每个select子句的类型&#xff08;简单OR复杂&#xff09; a. SIMPLE&#xff1a;查询中不包含子查询或者UNION b. 查询中若包含任何复杂的子部分&#xff0c;最外层查询则被标记为&#xff1a;PRIMARY c. 在SELECT或…

hash的算法 java_【数据结构与算法】一致性Hash算法及Java实践

追求极致才能突破极限一、案例背景1.1 系统简介首先看一下系统架构&#xff0c;方便解释&#xff1a;页面给用户展示的功能就是&#xff0c;可以查看任何一台机器的某些属性(以下简称系统信息)。消息流程是&#xff0c;页面发起请求查看指定机器的系统信息到后台&#xff0c;后…

Java EE CDI依赖关系消歧示例

在本教程中&#xff0c;我们将向您展示如何避免CDI bean中的依赖关系消除歧义。 在CDI中&#xff0c;我们可以为应用程序中不同客户端的接口的多个实现实现依赖项注入。 依赖关系消除歧义的问题是客户端如何在不同的实现中调用特定的实现&#xff0c;而不会发生任何错误。 为了…

linux java 安装配置_类Linux环境安装jdk1.8及环境变量配置详解

配置很简单&#xff0c;但是每次都要查一下&#xff0c;索性就记录下1. 安装前准备1.1 创建安装目录&#xff0c;习惯上通常安装在/usr/local/jdk8目录下mkdir /usr/local/jdk81.2 查看是否安装过jdk&#xff0c;安装前要把之前的删除干净# 通过jdk环境变量查看echo $JAVA_HOME…

Mac版Anaconda安装R语言iGraph包

Anaconda官网给出的R语言Igraph包安装方法&#xff1a;https://anaconda.org/r/r-igraph 查阅Anaconda官方文档&#xff0c;可以通过以下控制台命令安装R语言Igraph包。 conda install -c r r-igraph 在控制台执行后&#xff0c;系统可能会提示未找到conda指令&#xff0c; 所以…

Html5中Canvas(画布)的使用

什么是 Canvas&#xff1f;HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。画布是一个矩形区域&#xff0c;您可以控制其每一像素。canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。创建 Canvas 元素向 HTML5 页面添加 canvas 元素。规定元素的 id、宽…

多个动态包含一个JSF标签

每个JSF开发人员都知道ui&#xff1a;include和ui&#xff1a;param标签。 您可以包括一个facelet&#xff08;XHTML文件&#xff09;并传递一个对象&#xff0c;该对象将在包含的facelet中可用&#xff0c;如下所示&#xff1a; <ui:include src"/sections/columns.x…

[JLOI2014]松鼠的新家

嘟嘟嘟 这还是一道树链剖分板子题呀&#xff01; 从1到n - 1枚举a[i]&#xff0c;每一次使节点a[i]到a[i 1]的路径加1&#xff0c;但这样的话除a[1]&#xff0c;每一个点都多加了一个1&#xff0c;所以输出答案的时候减1即可。 1 #include<cstdio>2 #include<iostrea…

CSS3-背景(background-image、background-size、background-origin、background-clip)

CSS3中新的背景属性&#xff1a;background-image、background-size、background-origin、background-clip 背景图片&#xff1a;background-image CSS3中可以通过background-image属性添加背景图片。 不同的背景图像和图像用逗号隔开&#xff0c;所有的图片中显示在最顶端的为…

使用String.intern()减少内存使用

时不时地会有一个垂死的生产应用程序。 而且您知道您需要尽快对其进行修补。 我们也一样&#xff0c;并认为分享最近的一个战争故事将很有趣。 在这种情况下&#xff0c;我们就有机会使用String.intern&#xff08;&#xff09;之类的简单补丁来修补应用程序。 但是&#xff0c…