WildFly:如何从位于另一个应用程序中的 EJB 调用 EJB

目录

创建 EJB 服务器项目

配置服务器依赖项(WildFly 18 及更高版本)

配置服务器依赖项(WildFly 11、12、13、14、15、16、17)

部署 EJB 服务器项目

创建 EJB 客户端项目

配置客户端依赖项(WildFly 18 及更高版本)

在 EJB 客户端项目中配置安全性

测试 EJB 客户端项目


本教程的目的是演示如何从位于另一个应用程序中的另一个EJB查找和调用部署在WildFly服务器实例上的EJB 。

这是我们的场景:

另一方面,如果您的场景需要从独立的远程客户端调用 EJB,请查看本教程:WildFly 远程 EJB 客户端教程

为了演示如何从远程 EJB 客户端调用 EJB,我们需要完成以下步骤:

  • 创建 EJB 服务器项目,其中包含 EJB 的接口和实现
  • 创建查找远程 EJB的 EJB 客户端项目
  • 在客户端项目中配置安全性,使其有权调用远程 EJB

创建 EJB 服务器项目

因此,假设您有一个简单的服务器项目,其中包括以下有状态和无状态 EJB:

package com.mastertheboss.ejb;

import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.mastertheboss.exception.InsufficientFundsException;
 
@Stateful
@Remote(Account.class)
public class AccountEJB implements Account {

    long money;
 
    
    @Override
    public long getMoney() {
        return money;

    }

    public void createAccount(long amount)  
    {
        this.money= amount;
         
    }

    @Override
    public void deposit(long amount)  
    {
         
            this.money+= amount;
             
        System.out.println("Money deposit. total is "+money);
    }
 
     
    @Override
    public void withdraw(long amount) throws InsufficientFundsException {
        
        long newAmount = money - amount;
        if (newAmount < 0) {
            throw new InsufficientFundsException("Unsufficient funds for account! ");
        }
        
        money = newAmount;     
        System.out.println("Money withdrawal. total is "+money);

    }
}

package com.mastertheboss.ejb;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(Calculator.class)
public class CalculatorEJB implements Calculator {
   
    float interest=5;
 
    @Override
    public float calculateInterest(long money) {
     
        return money * (1+ (interest/100));
           
   }
    
}

这两个类的接口是:

package com.mastertheboss.ejb;

import com.mastertheboss.exception.InsufficientFundsException;

public interface Account {

    public void deposit(long amount);
    public void withdraw(long amount) throws InsufficientFundsException;
    
    public long getMoney();
    public void createAccount(long amount);
}

package com.mastertheboss.ejb;

public interface Calculator {

    public float calculateInterest(long money);
     
}

配置服务器依赖项(WildFly 18 及更高版本)

服务器项目需要以下一组依赖项:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.wildfly.bom</groupId>
            <artifactId>wildfly-jakartaee8-with-tools</artifactId>
            <version>${version.server.bom}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
      <dependency>
         <groupId>org.jboss.spec.javax.annotation</groupId>
         <artifactId>jboss-annotations-api_1.3_spec</artifactId>
         <scope>provided</scope>
      </dependency>
      <dependency>
         <groupId>org.jboss.spec.javax.ejb</groupId>
         <artifactId>jboss-ejb-api_3.2_spec</artifactId>
         <scope>provided</scope>
      </dependency>
</dependencies>

属性version.server.bom包含应用程序服务器版本,例如:

<properties>
   <version.server.bom>18.0.0.Final</version.server.bom>
</properties>

配置服务器依赖项(WildFly 11、12、13、14、15、16、17)

如果您的 WildFly 版本仍未通过 Jakarta EE 认证,那么您需要应用的唯一更改是您的 BOM,这将是用于服务器和客户端应用程序的wildfly-javaee8-with-tools 。无需其他更改:

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.wildfly.bom</groupId>
         <artifactId>wildfly-javaee8-with-tools</artifactId>
         <version>${version.server.bom}</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>
   </dependencies>
</dependencyManagement>

部署 EJB 服务器项目

由于我们的 pom.xml 包含 WildFly 的 maven 插件,您可以简单地构建和部署 EJB Server 项目,如下所示:

mvn install wildfly:deploy

从服务器日志中检查 EJB 项目已部署并且 JNDI 绑定可用:

08:24:43,534 INFO  [org.jboss.as.ejb3.deployment] (MSC service thread 1-3) WFLYEJB0473: JNDI bindings for session bean named 'AccountEJB' in deployment unit 'deployment "ejb-client-basic.war"' are as follows:

    java:global/ejb-client-basic/AccountEJB!com.mastertheboss.ejb.Account
    java:app/ejb-client-basic/AccountEJB!com.mastertheboss.ejb.Account
    java:module/AccountEJB!com.mastertheboss.ejb.Account
    java:jboss/exported/ejb-client-basic/AccountEJB!com.mastertheboss.ejb.Account
    ejb:/ejb-client-basic/AccountEJB!com.mastertheboss.ejb.Account?stateful
    java:global/ejb-client-basic/AccountEJB
    java:app/ejb-client-basic/AccountEJB
    java:module/AccountEJB

创建 EJB 客户端项目

现在让我们编写一个 EJB 客户端应用程序。为了简单起见,我们的应用程序将仅由一个 Servlet FE 和一个调用 Account 和 Calculator EJB 的 EJB 组成。这是Servlet:

package com.mastertheboss.ejbclient;

import java.io.IOException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ejb.*;


@WebServlet(urlPatterns = "/ejbclient")
public class ServletFE extends HttpServlet {
    @EJB EJBClient ejb;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {

        response.setContentType("html");
        write(response, "Example Servlet to show how EJB can invoke an EJB in another application");

        try {
            long money= request.getParameter("money") != null ? Long.parseLong(request.getParameter("money")) : 100l;
            float moneyWithInterest = ejb.callRemoteEJBs(money);
            write(response, "Amount: " + moneyWithInterest);
            } catch (Exception n) {
                  write(response, "Failed to invoke Remote EJB");
                write(response, n.getMessage());

            }

    }

    private static void write(HttpServletResponse writer, String message) {

        try {
            writer.getWriter().write(message + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

如您所见,它只是我们 EJB 的一个小包装器,其中包含实际的 EJB 客户端交互:

package com.mastertheboss.ejbclient;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.mastertheboss.ejb.*;
import com.mastertheboss.exception.*;


import javax.naming.spi.NamingManager;
import javax.ejb.*;
@Stateless
public class EJBClient {

    @EJB(name="ejb:/ejb-server-basic/CalculatorEJB!com.mastertheboss.ejb.Calculator")
    Calculator calculator;

    @EJB(name="ejb:/ejb-server-basic/AccountEJB!com.mastertheboss.ejb.Account?stateful")
    Account account;

    public float callRemoteEJBs(long money) throws Exception {
        account.createAccount(money);
        System.out.println("Create Account with "+money);

        account.deposit(money/2);
        System.out.println("Deposit " +(money/2));

        try {
            account.withdraw(money/3);
            System.out.println("Withdraw "+(money/3));

        } catch (InsufficientFundsException e) {

            e.printStackTrace();
        }
        money = account.getMoney();
        System.out.println("Money left " + money);
        float totalMoney = calculator.calculateInterest(money);
        System.out.println("Money plus interests " + totalMoney);
        return totalMoney;
    }
}

请注意,由于我们将调用驻留在同一应用程序服务器中的 EJB,因此查找远程 EJB 所需的只是以下内容:

@EJB(name="ejb:/ejb-server-basic/CalculatorEJB!com.mastertheboss.ejb.Calculator")
Calculator calculator;

@EJB(name="ejb:/ejb-server-basic/AccountEJB!com.mastertheboss.ejb.Account?stateful")
Account account;

配置客户端依赖项(WildFly 18 及更高版本)

服务器项目需要以下一组依赖项:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.wildfly.bom</groupId>
            <artifactId>wildfly-jakartaee8-with-tools</artifactId>
            <version>${version.server.bom}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
<!-- We depend on the EJB remote business interfaces of this application -->
    <dependency>
     <groupId>com.itbuzzpress.chapter4</groupId>
     <artifactId>ejb-server-basic</artifactId>
     <type>ejb-client</type>
     <version>${project.version}</version>
    </dependency>
<!-- Include the ejb client jars -->
    <dependency>
     <groupId>org.wildfly</groupId>
     <artifactId>wildfly-ejb-client-bom</artifactId>
     <type>pom</type>
     <scope>compile</scope>
    </dependency>
</dependencies>

与此类似,Property version.server.bom包含 Application Server 版本,例如:

<properties>
   <version.server.bom>18.0.0.Final</version.server.bom>
</properties>

至于 EJB 服务器项目,如果您在 WildFly 11 和 WildFly 17 之间运行 WildFly 版本,请在您的依赖项管理部分中使用 artifactId wildfly-javaee8-with-tools 。

在 EJB 客户端项目中配置安全性

影响您的客户端的另一个更改是以前的jboss-ejb-client.properties文件已被弃用,因此我们鼓励您迁移到 Elytron wildfly-config.xml文件,该文件将所有客户端配置统一在一个地方。出于我们示例的目的,我们将只添加一个默认的 wildfly-confug.xml 文件,该文件使用任何可用的 SASL 机制选择器进行身份验证。

<configuration>
    <authentication-client xmlns="urn:elytron:1.0">
        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="#ALL" />
                <set-mechanism-properties>
                    <property key="wildfly.sasl.local-user.quiet-auth" value="true" />
                 </set-mechanism-properties>
                <providers>
                    <use-service-loader/>
                </providers>
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>

另一方面,如果您需要提供凭据,则可以将它们添加到 authentication-configurations 块中,如下例所示:

<configuration>
    <authentication-client xmlns="urn:elytron:1.0">
        <authentication-rules>
            <rule use-configuration="default"/>
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="DIGEST-MD5"/>
                <set-user-name name="ejbuser"/>
                <credentials>
                    <clear-password password="password1!"/>
                </credentials>
            </configuration>
        </authentication-configurations>
    </authentication-client>    
</configuration>

要在服务器上创建用户,只需执行 add-user.sh 脚本,如下所示:

$ ./add-user.sh -a -u ejbuser -p password1! 

测试 EJB 客户端项目

为了测试我们的应用程序,还要部署 Client 项目:

mvn clean install wildfly:deploy

您可以通过 Servlet URI 测试应用程序,即“/ejbclient”:

curl http://localhost:8080/ejb-client-basic/ejbclient?money=200

您可以在以下位置查看本教程的源代码: https ://github.com/fmarchioni/mastertheboss/tree/master/ejb/intra-server-remote-ejb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值