WildFly - 创建具有长 运行 应用程序的应用程序
WildFly - create app with long running application
我是 JavaEE 的新手,正在尝试创建一个 WAR 包含一个应用程序,该应用程序每 30 分钟执行一次任务(并在部署应用程序时启动),以及一个允许客户端的 servlet使用 WildFly 连接并获取状态信息。
这可能吗?如果是这样,我如何让 WildFly 启动漫长的 运行 进程,以及如何让它将该对象注入 servlet?
长 运行 应用程序位于 class ProcessData() 中,它使用 ScheduledExecutorService 按计划生成线程以执行数据管理任务,并具有返回字符串的 getStatus() 方法关于处理。
这是 servlet:
@WebServlet("/procStat")
public class processorServlet extends HTTPServlet {
@Inject
ProcessData processData;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<p>" + processData.getStatus() + "</p>");
writer.close();
}
}
为什么要注射?您可以初始化它并使用静态方法或其他方法使用它吗?这是我的例子:
public class HelloWorld extends HttpServlet
{
private static final long serialVersionUID = -1L;
ProcessData processData;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Set response content type
response.setContentType("text/html");
// Actual logic goes here.
PrintWriter out = response.getWriter();
out.println("<h1>" + ProcessData.getStatus() + "</h1>");
}
}
在此之后实现 javax.servlet.ServletContextListener 的 ProcessData class
该侦听器具有将在 Web 应用程序初始化过程开始时执行的方法。
public class ProcessData implements ServletContextListener
{
private static String message;
private int counter = 0;
Runnable run = new Runnable()
{
@Override
public void run()
{
message = "counter: " + (counter++);
System.out.println(message);
}
};
@Override
public void contextInitialized(ServletContextEvent arg0)
{
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(run, 0, 1, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
// Empty method
}
public static String getStatus()
{
return message;
}
}
然后 web.xml 添加 servlet 和 ServletContextListener,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>TestTask</display-name>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
<listener>
<listener-class>schedule.ProcessData</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
我之前问过为什么你需要注入它,因为如果你有一个与特定用户无关的任务(比如你的任务无论用户是否登录都会执行)那么你最终会遇到很多用户的情况需要访问单个数据。您需要某种单例,是的,您可以使用 CDI bean 或其他注入技术来完成它,但您也可以在没有这种开销的情况下使其工作。在我的示例中,我使用静态方法和静态字段来完成。
我是 JavaEE 的新手,正在尝试创建一个 WAR 包含一个应用程序,该应用程序每 30 分钟执行一次任务(并在部署应用程序时启动),以及一个允许客户端的 servlet使用 WildFly 连接并获取状态信息。
这可能吗?如果是这样,我如何让 WildFly 启动漫长的 运行 进程,以及如何让它将该对象注入 servlet?
长 运行 应用程序位于 class ProcessData() 中,它使用 ScheduledExecutorService 按计划生成线程以执行数据管理任务,并具有返回字符串的 getStatus() 方法关于处理。
这是 servlet:
@WebServlet("/procStat")
public class processorServlet extends HTTPServlet {
@Inject
ProcessData processData;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
resp.setContentType("text/html");
PrintWriter writer = resp.getWriter();
writer.println("<p>" + processData.getStatus() + "</p>");
writer.close();
}
}
为什么要注射?您可以初始化它并使用静态方法或其他方法使用它吗?这是我的例子:
public class HelloWorld extends HttpServlet
{
private static final long serialVersionUID = -1L;
ProcessData processData;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Set response content type
response.setContentType("text/html");
// Actual logic goes here.
PrintWriter out = response.getWriter();
out.println("<h1>" + ProcessData.getStatus() + "</h1>");
}
}
在此之后实现 javax.servlet.ServletContextListener 的 ProcessData class 该侦听器具有将在 Web 应用程序初始化过程开始时执行的方法。
public class ProcessData implements ServletContextListener
{
private static String message;
private int counter = 0;
Runnable run = new Runnable()
{
@Override
public void run()
{
message = "counter: " + (counter++);
System.out.println(message);
}
};
@Override
public void contextInitialized(ServletContextEvent arg0)
{
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(run, 0, 1, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent arg0)
{
// Empty method
}
public static String getStatus()
{
return message;
}
}
然后 web.xml 添加 servlet 和 ServletContextListener,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>TestTask</display-name>
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>servlet.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
<listener>
<listener-class>schedule.ProcessData</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
我之前问过为什么你需要注入它,因为如果你有一个与特定用户无关的任务(比如你的任务无论用户是否登录都会执行)那么你最终会遇到很多用户的情况需要访问单个数据。您需要某种单例,是的,您可以使用 CDI bean 或其他注入技术来完成它,但您也可以在没有这种开销的情况下使其工作。在我的示例中,我使用静态方法和静态字段来完成。