gpt4 book ai didi

java - 如何从 Quartz 作业内部执行 Struts 2 Action。如何获取容器?

转载 作者:行者123 更新时间:2023-11-30 04:46:29 27 4
gpt4 key购买 nike

我正在尝试从 Quartz 作业内部执行 Struts2 操作——泛化,从任何不处理 HTTP 请求的上下文。

我从这里开始http://struts.apache.org/2.0.6/docs/how-can-we-schedule-quartz-jobs.html但该文档似乎已经过时了。

我相信(但我可能是错的)我已经将其归结为需要获取 Container 对象:

import java.util.HashMap;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.DefaultActionProxyFactory;

...

HashMap ctx = new HashMap();
DefaultActionProxyFactory factory= new DefaultActionProxyFactory();
factory.setContainer(HOW DO I GET THE CONTAINER??);
ActionProxy proxy = factory.createActionProxy("", "scheduled/myjob", ctx);

一种解决方案是针对本地主机发出 http 请求(通过 TCP)。我宁愿避免这种情况。

最佳答案

我有点担心提供这个答案可能会鼓励某些人这样做,但作为概念证明,并实际上为任何可能的人提供解决方案,无论出于何种原因(也许他们正在继承一些破烂的应用程序,这是需要吗?),需要在正常请求上下文之外执行 Struts2 操作。

但是,这是一个原始的(它是作为起点提供的,而不是最佳实现),但有效的解决方案:

首先,将这三个类添加到名为 com.stackoverflow.struts2.quartz 的包中:

一个简单的作业,只需为给定的作业上下文请求代理并执行它:

package com.stackoverflow.struts2.quartz;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class ActionJob implements Job {

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {

try {
QuartzActionProxyFactory.getActionProxy(context).execute();
} catch (Exception e) {
e.printStackTrace();
throw new JobExecutionException(e);
}

}

}

用于传递操作详细信息的一些常量:

package com.stackoverflow.struts2.quartz;

public class QuartzActionConstants {

public static final String NAMESPACE = "struts.action.namespace";
public static final String NAME = "struts.action.name";
public static final String METHOD = "struts.action.method";

}

可以从 ActionJob 静态访问的自定义 ActionProxyFactory:

package com.stackoverflow.struts2.quartz;

import java.util.HashMap;
import java.util.Map;

import org.apache.struts2.impl.StrutsActionProxyFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionProxyFactory;

public class QuartzActionProxyFactory extends StrutsActionProxyFactory {

private static ActionProxyFactory actionProxyFactory;

public QuartzActionProxyFactory() {
actionProxyFactory = this;
}

public static ActionProxy getActionProxy(JobExecutionContext context) throws JobExecutionException {

ActionProxy actionProxy = null;

try {
@SuppressWarnings("unchecked")
Map<String, Object> actionParams = context.getJobDetail().getJobDataMap();
Map<String, Object> actionContext = new HashMap<String, Object>();
actionContext.put(ActionContext.PARAMETERS, actionParams);

actionProxy = actionProxyFactory.createActionProxy(
(String) actionParams.get(QuartzActionConstants.NAMESPACE),
(String) actionParams.get(QuartzActionConstants.NAME),
(String) actionParams.get(QuartzActionConstants.METHOD),
actionContext,
false, //set to false to prevent execution of result, set to true if this is desired
false);

} catch (Exception e) {
throw new JobExecutionException(e);
}

return actionProxy;
}

}

然后,在 struts.xml 中添加:

<bean name="quartz" type="com.opensymphony.xwork2.ActionProxyFactory" class="com.stackoverflow.struts2.quartz.QuartzActionProxyFactory"/>
<constant name="struts.actionProxyFactory" value="quartz"/>

然后您可以使用一些简单的代码来安排操作执行:

SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
scheduler.start();
JobDetail jobDetail = new JobDetail("someActionJob", Scheduler.DEFAULT_GROUP, ActionJob.class);

@SuppressWarnings("unchecked")
Map<String, Object> jobContext = jobDetail.getJobDataMap();
jobContext.put(QuartzActionConstants.NAMESPACE, "/the/action/namespace");
jobContext.put(QuartzActionConstants.NAME, "theActionName");
jobContext.put(QuartzActionConstants.METHOD, "theActionMethod");

Trigger trigger = new SimpleTrigger("actionJobTrigger", Scheduler.DEFAULT_GROUP, new Date(), null, SimpleTrigger.REPEAT_INDEFINITELY, 1000L);
scheduler.deleteJob("someActionJob", Scheduler.DEFAULT_GROUP);
scheduler.scheduleJob(jobDetail, trigger);

就是这样。此代码将导致该操作无限期地每秒执行一次,并且拦截器将全部触发并注入(inject)依赖项。当然,任何依赖于 Servlet 对象(例如 HttpServletRequest)的逻辑或拦截器都不会正常运行,但是无论如何,在 servlet 上下文之外安排这些操作也是没有意义的。

关于java - 如何从 Quartz 作业内部执行 Struts 2 Action。如何获取容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10843550/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com