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 {

	@AroundInvoke
	public 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 {

	@AroundInvoke
	public 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值