如何在Java Spring的html页面上实时显示循环结果



我想在html页面上实时显示循环结果。我使用Java,Spring,thymelaf,javascript。循环如下。我希望它显示在html页面上,而不是系统输出打印。

@GetMapping("/progress")
public String testProgress() {
for (int i = 1; i <= 100; i++) {
if(i==20){
System.out.println("20 %");
}else if (i==40){
System.out.println("40 %");
}else if (i==60){
System.out.println("60 %");
}else if (i==80){
System.out.println("80 %");
}else if (i==100){
System.out.println("100 %");
}
}
return null;
}

您可以使用服务器发送的事件和htmx来完成此操作。

首先,创建一个@GetMapping方法来公开SSE通道:

private SseEmitter sseEmitter;
@GetMapping("/progress-events")
public SseEmitter progressEvents() {
sseEmitter = new SseEmitter(Long.MAX_VALUE);

sseEmitter.onCompletion(() -> LOGGER.info("SseEmitter is completed"));
sseEmitter.onTimeout(() -> LOGGER.info("SseEmitter is timed out"));
sseEmitter.onError((ex) -> LOGGER.info("SseEmitter got error:", ex));
return sseEmitter;
}

接下来,使用您的方法启动要监视的进程。这可以是任何方法。在这个例子中,我使用了POST:

@PostMapping
public String generatePdf() {
for(int progress = 0; progress <=100;progress++) {
int progress = 0
String html = """
<div id="progress-container" class="progress-container"> 
<div class="progress-bar" style="width:%s%%"></div> 
</div>
""".formatted(value);
sseEmitter.send(html);
}
return "index";
}

在您的百里香模板中:

<body>
<h1>Demo</h1>
<div hx-sse="connect:/progress-events">
<button hx-post="/" hx-swap="none">Show progress</button>
<div style="margin-bottom: 2rem;"></div>
<div id="progress-wrapper" hx-sse="swap:message">
</div>
</div>
<script type="text/javascript" th:src="@{/webjars/htmx.org/dist/htmx.min.js}"></script>
</body>
  • hx-sse(在外部div上(:告诉要连接的SSE通道上的htmx
  • hx-post:单击按钮时告诉htmx执行POST
  • hx-swap:告诉htmx POST的响应不应使用来替换按钮的innerHTML
  • hx-sse(在内部div上(:告诉htmx将progress-wrapper的innerHTML与通过服务器发送的事件发送的HTML交换

一个棘手的问题是HTML不能包含换行符,这就是为什么文本块在每行的末尾都有反斜杠。

您可以在上看到完整的示例https://github.com/wimdeblauwe/blog-example-code/tree/feature/htmx-sse/htmx-sse.它稍微复杂一些,因为它使用Spring Security,并跟踪每个用户的SseEmitters,以便将进度发送到用户登录的所有打开的浏览器选项卡

最新更新