この回答を提供することで、一部の人々が何をするようになるのでしょうか、しかし概念の証明として、そして何らかの理由で(おそらく、彼らはこれが必要ないくつかの打ち砕かれたアプリケーションを継承している可能性がありますか?) 、通常のリクエスト コンテキスト外で Struts2 アクションを実行する必要があります。
ただし、これは生の (最適な実装ではなく、開始点として提供されている) が、機能するソリューションです。
まず、次の 3 つのクラスを 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);
以上です。このコードにより、アクションが毎秒無期限に実行され、インターセプターがすべて起動し、依存関係が注入されます。もちろん、HttpServletRequest のようなサーブレット オブジェクトに依存するロジックやインターセプターは適切に動作しませんが、サーブレット コンテキストの外部でこれらのアクションをスケジュールすることは意味がありません。