我有一个复杂的场景,对此我不知道如何处理:
我的ejbs在远程服务器上运行。
我的Web应用程序在另一台服务器上运行。
我有一个ApplicationContext,根据域,语言,国家等而有所不同。
我希望以匿名方式将此应用程序上下文传递给远程EJB,以使开发人员不必使用ApplicationContext作为参数来调用其所有后端请求。
这是场景,可以说我有一个远程无状态EJB:
@Stateless
public class MyStateless implements MyStatelessRemote{
//The application context that needs to be supplied form the front-end
@Inject //probably define a producer method to always supply a new one.
private ApplicationContext applicationContext;
public void doCheckSomething(final MySomethingData data){}
}
在前端:
@SessionScoped
@Named
public class MyController implements Serializable{
@EJB
private MyStatelessRemote statelessRemote
//The current application/session context to be passed to the Stateless ejb on every invocation.
@Inject
private ApplicationContext executionContext;
public void doSomeOrderOrSomethingSimilar(){
//At this point, the current application context needs to be supplied to the remote EJB
//Which it may use to check on order validity based on configurations such as country
//language etc.
statelessRemote.doCheckSomething(mySomething);
}
}
如果有20个以上的EJBS,每个EJBS平均有8到10个方法,并且考虑到几乎每个ejb都可能需要知道调用者的执行上下文的可能性,那么是否有可能通过配置或其他方式来解析当前执行上下文。
ejb在调用任何方法?
编辑:
我正在寻找类似于Web服务的入站和出站拦截器的东西。
在jboss / wildfly服务器上工作了几个月后,我终于找到了实现此功能的途径:
客户端代码:(基于jboss ejbclient)
package com.mycompany.view.service.wildfly.invocationcontext;
import com.mycompany.ejb.internal.MyCompanyAccount;
import com.mycompany.view.service.account.LoggedInAccount;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import org.jboss.ejb.client.AttachmentKey;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.EJBClientInterceptor;
import org.jboss.ejb.client.EJBClientInvocationContext;
import static com.mycompany.management.wildfly.invocationcontext.MyCompanyInvocationContextKey.MYCOMPANY_ACCOUNT_NUMBER;
/**
* Registers itself as a jboss client interceptor.
* @author marembo
*/
@Singleton
@Startup
public class MyCompanyInvocationContextInterceptor implements EJBClientInterceptor {
private static final Logger LOG = Logger.getLogger(MyCompanyInvocationContextInterceptor.class.getName());
private static final AttachmentKey<Long> MYCOMPANY_ACCOUNT_NUMBER_KEY = new AttachmentKey<>();
@Inject
@LoggedInAccount
private Instance<MyCompanyAccount> loggedInAccount;
@PostConstruct
void registerSelf() {
EJBClientContext.requireCurrent().registerInterceptor(0, this);
}
@Override
public void handleInvocation(final EJBClientInvocationContext ejbcic) throws Exception {
LOG.log(Level.INFO, "Intercepting invocation on: {0}", ejbcic.getInvokedMethod());
final EJBClientContext clientContext = ejbcic.getClientContext();
if (!loggedInAccount.isUnsatisfied()) {
final MyCompanyAccount mycompanyAccount = loggedInAccount.get();
if (mycompanyAccount != null) {
final Long accountNumber = mycompanyAccount.getAccountNumber();
clientContext.putAttachment(MYCOMPANY_ACCOUNT_NUMBER_KEY, accountNumber);
}
}
ejbcic.getContextData().put(MYCOMPANY_ACCOUNT_NUMBER, "348347878483");
ejbcic.sendRequest();
}
@Override
public Object handleInvocationResult(final EJBClientInvocationContext ejbcic) throws Exception {
return ejbcic.getResult();
}
}
在服务器端,我注册了一个全局拦截器:
package com.mycompany.management.wildfly.extension;
import com.mycompany.management.facade.account.MyCompanyAccountFacade;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
/**
* Default interceptor does not require @Interceptor
* @author marembo
*/
public class MyCompanyInvocationContextReceiver {
private static final Logger LOG = Logger.getLogger(MyCompanyInvocationContextReceiver.class.getName());
@Resource
private EJBContext ejbContext;
@EJB
private MyCompanyInvocationContext mycompanyInvocationContext;
@EJB
private MyCompanyAccountFacade mycompanyAccountFacade;
@AroundInvoke
public Object setMyCompanyAccount(final InvocationContext invocationContext) throws Exception {
final Map<String, Object> contextData = ejbContext.getContextData();
LOG.log(Level.INFO, "EJBContext data: {0}", contextData);
LOG.log(Level.INFO, "InvocationContext data: {0}", invocationContext.getContextData());
return invocationContext.proceed();
}
}
和ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
version = "3.1"
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_1.xsd">
<interceptors>
<interceptor>
<interceptor-class>com.mycompany.management.wildfly.extension.MyCompanyInvocationContextReceiver</interceptor-class>
</interceptor>
</interceptors>
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>com.mycompany.management.wildfly.extension.MyCompanyInvocationContextReceiver</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
</ejb-jar>
如服务器端拦截器上所示,您可以从InvocationContext或EJBContext获得客户端发送的数据。
我有一个aws设置,它要求我承担角色并获得相应的凭据,以便写入s3。例如,要使用aws cli编写,我需要使用标志。如果我自己用boot编写代码,我将通过扮演角色,获取凭据,并创建新会话。 但是,有许多应用程序和包依赖于boto3的配置,例如,内部代码运行如下: 从文档中,boto3可以设置为使用默认配置文件,使用(除其他外)env变量,并且它显然“工作”在与变量匹配,但应用程序仍然不会写入s3。
问题内容: 我正在这样运行我的JavaFX应用程序: 类扩展。在特殊的FX线程中启动JavaFX窗口,但是在我的main方法中,我什至没有类的实例。 如何将非字符串参数(在我的情况下为 控制器 )传递给实例?它是有缺陷的设计吗? 问题答案: 通常,除了传递给您的主程序的程序参数外,无需将参数传递给主应用程序。想要这样做的唯一原因是创建一个可重用的对象。但这并不需要是可重用的,因为这是组装您的应用程
我有在Tomcat 8服务器上运行的应用程序。应用程序使用log4j2进行内部日志记录。我想有一个application.war和两个不同的日志配置文件,如:log4j2_dev.xml和log4j2_prod.xml取决于环境。 在生产环境中,我希望部署应用程序。war并使用log4j2_prod.xml,在开发环境中部署应用程序。war并使用log4j2_dev.xml 那么,我如何指定在应用
问题内容: 在通过构造函数传递给匿名类的最终变量中,Jon Skeet提到了变量是通过自动生成的构造函数传递给匿名类实例的。在这种情况下,为什么我看不到使用反射的构造函数: } 输出为: 问题答案: 这是您的程序在我的系统上输出的内容: 因此,构造函数在那里。但是,它是无参数的。从反汇编来看,发生的事情是编译器发现它不需要传递给它,因为它的值在编译时就知道了。 如果我这样更改代码: 现在生成的构造
本文向大家介绍C#程序将参数传递给线程,包括了C#程序将参数传递给线程的使用技巧和注意事项,需要的朋友参考一下 要使用线程,请在代码中添加以下命名空间- 首先,您需要在C#中创建一个新线程- 上面,threadDemo是我们的线程函数。 现在将参数传递给线程- 上面设置的参数是- 示例 让我们看完整的代码,以将参数传递给C#中的线程。 输出结果
问题内容: 我有一个运行自定义gradle任务的Java应用程序,该应用程序在被调用时需要一些参数。这些是: Gradle任务如下所示: 我已尝试运行,但无法正常工作。 问题答案: 从Gradle 4.9开始,可以使用–args传递命令行参数。例如,如果要使用命令行参数启动应用程序,则可以使用 gradle run –args =’foo –bar’ 另请参阅Gradle应用程序插件 如何升级Gr