4

SpringBoot+Htmx全局错误处理程序案例

 8 months ago
source link: https://www.jdon.com/71269.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SpringBoot+Htmx全局错误处理程序案例 - 极道

htmx -spring-boot 库 3.2.0刚刚发布,现在支持用作HtmxResponse错误处理程序的返回类型。这篇博文展示了如何使用它。

错误处理是任何应用程序的重要组成部分。它确保用户始终了解应用程序发生了什么并且可以采取行动。按下按钮却没有任何反应总是比看到错误消息出现更糟糕。显然,我们应该努力避免它们,但是有一个全局错误回退以防万一出现问题肯定是一个好主意。

让我们创建一个小示例来展示新功能。使用ttcli并选择“NPM Based with TailwindCSS”、“htmx”和“DaisyUI”。

我们添加 2 条路线HomeController:

    @GetMapping("/test")
    @HxRequest
    public String test() {
        return "fragments :: message";
    }

@GetMapping("/test-exception")
    @HxRequest
    public String testException() {
        throw new RuntimeException("Fake exception");
    }

第一个返回一个简单的结果<div>,第二个则模拟发生异常。

src/main/resources/templates/fragments.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<div th:fragment="message">
    Button clicked!
</div>

在 index.html中,我们放置了两个按钮来触发我们的两条路线:

<div layout:fragment="content">
    <div class="m-4">
        <button class="btn btn-neutral"
                hx:get="@{/test}"
                hx-swap="outerHTML"
        >Do something</button>
    </div>
    <div class="m-4">
        <button class="btn btn-neutral"
                hx:get="@{/test-exception}"
                hx-swap="outerHTML"
        >Do something</button>
    </div>
</div>

在 中index.html,添加一个空字符div作为占位符来放置错误消息:

<div layout:fragment="content">
    <div class="mx-8 mt-4">
        <div id="global-error"></div>
    </div>
    ...

我们创建一个可用于带外交换的片段:

src/main/resources/templates/fragments.html

<div th:fragment="error-message(message)" id="global-error" role="alert" class="alert alert-error" hx-swap-oob="true">
    <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
    <span th:text="${message}">Error!</span>
</div>

这两件事很重要:

  • hx-swap-oob="true" 允许 htmx 使用带外交换。
  • 片段的 id 必须与 index.html 模板中占位符 div 的 id 一致。

最后一块拼图是在 HomeController 中添加异常处理程序:
HomeController.java

@ExceptionHandler(Exception.class
    public HtmxResponse handleError(Exception ex) {
        return HtmxResponse.builder()
                           .reswap(HtmxReswap.none()) 
                           .view(new ModelAndView("fragments :: error-message", Map.of("message", ex.getMessage()))) 
                           .build();
    }
  •     处理异常Exception 和异常的所有子类。
  • 将交换行为设置为 "无",这样我们就不会意外地交换我们不想交换的东西。我们只希望通过带外交换来显示错误信息。
  • 使用 error-message 片段,并将捕获的异常信息传递给该片段。

如果希望错误处理适用于应用程序的所有控制器,可以使用 @ControllerAdvice 来实现:

import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponse;
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxReswap;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@ControllerAdvice
public class GlobalErrorHandler {

@ExceptionHandler(Exception.class)
    public HtmxResponse handleError(Exception ex) {
        return HtmxResponse.builder()
                           .reswap(HtmxReswap.none())
                           .view(new ModelAndView("fragments :: error-message", Map.of("message", ex.getMessage())))
                           .build();
    }
}

结论
确保回退错误处理程序并不那么困难,随着 htmx-spring-boot 3.2.0 版本的发布,这变得更加容易。
请参阅GitHub 上的htmx-global-error-handler以获取此示例的完整源代码。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK