春季mvc百里香。如何将白标签错误页面显示为模式或弹出窗口或吐司

斯坦尼斯拉夫·滕

我在spring mvc应用程序中显示错误,但出现问题。因此,让我描述更多有关问题的细节。

如果我要显示自定义错误页面而不是默认的whitelabel错误页面,我已经知道该怎么办。在这里阅读了有关此内容并观看了youtube上的一些教程这很简单,但是问题在于用户将始终重定向到包含错误描述的新页面。

我想将所有后端异常以特定格式显示为模式窗口,警报消息或吐司,如此处所示但适用于百里香。最好的解决方案是模式页面,这使我可以更灵活地显示内容。但是模态可以使用前端的JavaScript来调用,如何使用控制器异常作为打开模态页面的触发器(如果可能,则不使用AJAX)?

这实际上是我想要的,当控制器中的某些方法可能引发异常时,调用该异常并引发异常

@GetMapping
public ModelAndView throwException() throws Exception {
    throw new Exception("Oops :( something went wrong");
}

像这样的东西会显示错误窗口

请帮助我找到解决方案。非常感谢您的关注。

PS,如果这很复杂或不可能,我想至少知道如何显示来自控制器的错误消息+与当前(同一)页面上的错误相关的一些按钮或输入字段,而无需重定向到新页面?

Jakub Ch。

TL; DR

没有捷径。如果您是我,我会坚持使用通用错误页面。您可以针对不同类型的错误自定义它们。

工具不足以解决您的问题。

IMO您所描述的问题将更适合在任何具有Java后端公开REST API的现代前端框架中编写的SPA(单页应用程序)。通常enpoint将返回包含实际请求数据的json。但是,如果发生任何错误,您可以简单地返回带有错误描述的4xx代码作为有效内容。然后,JavaScript中的表示逻辑可以在不重新加载页面的情况下显示任何内容。

由于您已决定使用作为模板引擎的百里香叶,因此您应该接受其局限性。对控制器的大多数调用是对视图的请求。Spring and Thymeleaf接收一个模板文件,用模型数据填充该文件,然后将整个页面发送回浏览器。如果此过程在收集数据时失败,则无法正确呈现页面。因此,最合理的做法是重定向到错误页面。

合理的出路

如果通用错误页面吓坏了您,则可以付出额外的努力。代替一般的错误处理,您可以处理每个Controller方法中的异常。如果出错,您可能会提供其他“错误”模型,这些模型将用于填充模板。它使您可以灵活地显示错误。这将取决于您如何准备模板。

例如

view.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <h1>Data:</h1>
    <div th:if="${actualData}">
        <p th:text="${actualData}"></p>
    </div>
    <!-- Instead of div below, you could supply a modal and pice of javascript opening it -->
    <div th:if="${errorData}">
        <h3>Error occurred:</h3>
        <p th:text="${errorData}"></p>
    </div>
</body>
</html>

MyController.java

@Controller
class MyController {

    @GetMapping("/view")
    public String view(Model model) {
        try {
            model.addAttribute("actualData", mayThrowExceptionDataFetch());
        } catch(Exception e) {
            model.addAttribute("errorData", e.getMessage());
        }
        return "view";
    }

    private String mayThrowExceptionDataFetch() {
        // Either return a value or throw an exception
    }
}

这样一来,视图将始终返回。即使发生错误,也可以对其进行处理和显示。

不合理的出路

重要说明:这仅是演示。当然,我不会在生产中尝试它。

我发现您的要求如此异常(控制器异常作为打开模式页面的触发器),我想检查是否有可能实现类似的要求。我想象过一个解决方案可能是这样的:

  1. 前端:订阅服务器发送事件的终结点(错误源)。
  2. 后端:在捕获异常时,请中止请求,以使服务器不返回任何内容。
  3. 后端:将包含错误描述的消息发送给适当的客户端。
  4. 前端:接收事件,以某种方式提醒它。

然后,我提出了这个有效的演示,它确实不会导致页面重新加载,但显示错误:

index.html

<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
</head>
<body>
    <a th:href="@{/exception}">Click for exception</a>
    <script>
        var sse = new EventSource('http://localhost:8080/sse');
        sse.onmessage = function (evt) {
            alert(evt.data);
        };
    </script>
</body>
</html>

MyService.java

@Service
public class MyService {

    private final SseEmitter emitter = new SseEmitter();

    public SseEmitter getEmitter() {
        return emitter;
    }
}

MyExceptionHandler.java

@ControllerAdvice
public class MyExceptionHandler {

    private final MyService service;

    @Autowired
    public MyExceptionHandler(MyService service) {
        this.service = service;
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.CONTINUE) // I don't figure out how to abort request
    public ResponseEntity<Void> handle(Exception ex) {
        try {
            service.getEmitter().send(SseEmitter.event().data(ex.getMessage()));
        } catch (IOException e) {
            // TODO
        }
    }
}

MyController.java

@Controller
public class MyController {

    private final MyService service;

    @Autowired
    public MyCtrl(MyService service) {
        this.service = service;
    }

    @GetMapping("/sse")
    public SseEmitter sse() {
        return service.getEmitter();
    }

    @GetMapping("/index")
    public String index() {
        return "index";
    }

    @GetMapping("/exception")
    public String exception() {
        throw new RuntimeException("Oops :o");
    }
}

上面的所有内容都是带有spring-boot-starter-thymeleafspring-boot-starter-web依赖项的spring-boot项目运行应用程序,转到localhost:8080/index然后单击链接。警报应出现而无需重新加载页面。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用百里香叶为html元素分配多个属性

来自分类Dev

如何将列表从控制器发送到百里香

来自分类Dev

百里香中的循环

来自分类Dev

如何将图像作为ResponseEntity <byte []>返回并使用百里香叶显示

来自分类Dev

如何从百里香html页面获取用户代理

来自分类Dev

如何使用百里香叶在div标签中呈现tinymce内容

来自分类Dev

春季和百里香以html为资源

来自分类Dev

如何将Spring控制器映射到其百里香视图(intellij14)

来自分类Dev

如何从百里香叶增加boostrap区域控制标签的增量

来自分类Dev

如何使用百里香在HTML5中显示地图值列表

来自分类Dev

如何用百里香绑定对象列表?

来自分类Dev

如何使用百里香叶将翻译成javascript

来自分类Dev

如何根据百里香中的条件将样式应用于div?

来自分类Dev

如何将变量传递给session.attribute.contains()百里香?

来自分类Dev

无法将变量设置为百里香模板

来自分类Dev

如何将百里香表单数据发布到Controller

来自分类Dev

如何用百里香产生序列

来自分类Dev

百里香eq与弹簧变量错误?

来自分类Dev

百里香中的循环

来自分类Dev

如何使用百里香叶在div标签中呈现tinymce内容

来自分类Dev

春季和百里香叶以html为资源

来自分类Dev

如何将多个表值放在百里香叶html文件中?

来自分类Dev

春季MVC 4 +百里香叶

来自分类Dev

百里香的隐藏输入值错误

来自分类Dev

如何使用百里香叶将翻译成javascript

来自分类Dev

如何使用百里香抓取textarea数据

来自分类Dev

当标签中的百里香为百里香时,标签中的文本是什么?

来自分类Dev

当 th:if 的条件为真时,百里香叶块不显示

来自分类Dev

如何将函数值传递给百里香叶

Related 相关文章

热门标签

归档