Spring MVC:通过打开和关闭网页上的开关来触发和终止后端方法

Spring MVC: triggering and terminating a backend method by turning on and off a switch on a web page

所以在前端主页面中,有一个开关,我可以打开和关闭。可以使用 Ajax 将开关的状态代码发送到后端。

现在,当开关打开时,我希望后端方法保持运行,我定义如下:

public static void foo {

    Thread thread = new Thread(new Runnable() {

        @Override
        public void run() {
            while(true) {
                try {
                    Thread.sleep(8000);
                    ArticleDAO.addNewArticles();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    });

    thread.start();
}

当开关关闭时,我希望方法或线程终止。

JSP 页面中的 Ajax 代码如下所示:

$("#switcher").on("switchChange.bootstrapSwitch", function(e, state) {
    if (state == true) {

        $(function() {
            $.ajax({
                type: "POST",
                url: "http://localhost:8080/wx/admin/toggle_state.html",
                data: {
                    stateCode: 1
                },
                success: function(data) {
                    alert("Switched to auto mode");
                },
                error: function() {
                    alert("Something went wrong!!");
                }
            });
        });

    } else if (state == false) {

        $(function() {
            $.ajax({
                type: "POST",
                url: "http://localhost:8080/wx/admin/toggle_state.html",
                data: {
                    stateCode: 0
                },
                success: function(data) {
                    alert("Switched to manual mode");
                },
                error: function() {
                    alert("Something went wrong!!");
                }
            });
        });

    } else {
        alert("Something went wrong!!");
    }
});

这里是 spring 控制器:

@RequestMapping(value = "admin/toggle_state.html", method = RequestMethod.POST)
@ResponseBody
public String toggleState(@RequestParam Integer stateCode) throws Exception {
    if (stateCode == 1) {
        /*

        EXECUTE THE FOO METHOD RIGHT HERE

        */
        System.out.println("Switched to auto mode.");
    } else if (stateCode == 0) {
        // TERMINATE THE METHOD / THREAD HERE
    }
    return "";
}

那么推荐的实现方式是什么?它实际上看起来并不太难,但我不知道如何在我的情况下启动和终止线程。我能想到的一种方法是将开关的状态代码存储到数据库中,并使方法在线程中每次运行时都检查数据库。但这似乎不是一个很好的解决方案。有任何想法吗?提前致谢!!

线程可以被中断,参见http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

添加一个 bean(应用程序范围)以保留对线程的引用。将 bean 自动连接到控制器。

检查 stateCode 值并使用 bean 的引用来启动 ()/停止 () 线程。

@Component
public ThreadHolderBean {
  Thread theThreadReference=new Thread();//init the thread properly
}

现在在你的控制器中添加

@Autowired 
private ThreadHolderBean threadHolder;

并在toggleState()方法中使用threadHolder

如果您需要多个线程,例如为每个会话更改 bean 范围或定义一个线程池。

既然您已经在使用 Spring,那么 TaskExecutor 非常适合此场景,您可以使用底层方法,如`ExecutorService.shutdown()、ExecutorService.shutdownNow()、awaitTerminationIfNecessary()

您可以通过控制器执行类似的操作...

public static void foo(int stateCodeFromFrontEnd) {

Thread thread = new Thread(new Runnable() {

    @Override
    public void run() {
        int stateCode = stateCodeFromFrontEnd;
        while(stateCode == 1) {
            try {
                Thread.sleep(8000);
                if(Thread.currentThread().isInterrupted()) {
                    stateCode = 0;
                }
                ArticleDAO.addNewArticles();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
});

thread.start();
}

当你的开关关闭时,调用 thread.interrupt()。