当不请求视图时,将用户春季发送给视图

时间:2019-02-17 17:49:54

标签: spring-boot

我在春季写了一本书的目录。 它从目录中收集书籍(pdf,epub,mobi,ebook),从其中收集一些元数据,将它们存储在数据库中,然后将其放入可供我查看的列表中:

    @Slf4j
    @Controller
    public class BookCatalogController {
    // == Fields ==
    private final BookService bookService;

    @Autowired
    public BookCatalogController(BookService bookService){this.bookService = bookService; }


    // == Model attributes ==
    @ModelAttribute
    public List<Book> bookData(){ return bookService.getBooksFromMemory(); }

    public static final File bookDirectory= new File("D:\\edu_repo\\ebooks_test\\");

    .
    .
    .
// Catalog Simple View
    @GetMapping(Mappings.CATALOG_SIMPLE)
    public String catalogSimple(Model model){

        log.info("catalogSimple method called");

        // This is adding the entire BookManager book list into the model.
        model.addAttribute(AttributeNames.BOOK_DATA, bookData());

        return ViewNames.CATALOG_SIMPLE;
    }


    // Catalog Detail View
    @GetMapping(Mappings.CATALOG_DETAIL)
    public String catalogDetail(Model model){

        log.info("catalogDetail method called");

        // This is adding the entire BookManager book list into the model.

model.addAttribute(AttributeNames.BOOK_DATA, bookData());
        return ViewNames.CATALOG_DETAIL;
    }

.
.
.
    @GetMapping(Mappings.LOAD_BOOKS)
    public void loadBooks(Model model) {

        bookService.loadBooksFromDirectory(bookDirectory);
    }
}

很明显,我没有正确使用@GetMapping(Mappings.LOAD_BOOKS),如下面的错误所示:

错误:

There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template [load-books], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [load-books], template might not exist or might not be accessible by any of the configured Template Resolvers

一个人如何像我正在执行的那样调用一个方法,但是没有Spring尝试将用户重定向到另一个视图? 我根本不希望页面更新,因为我没有返回视图!

1 个答案:

答案 0 :(得分:1)

在浏览器中单击带有 load-books 锚点的链接时,浏览器会将其发送到服务器并等待结果,这将导致页面重新加载。一旦对 load-books 端点的请求到达服务器,Spring MVC就会处理此问题,并开始使用其方法查找适当的控制器。它会根据您的情况找到public void loadBooks(Model model)。当Spring MVC调用该方法时,它希望获得一个要解析的视图名称,然后返回到您的浏览器。
由于您尚未提供View或String作为返回类型,因此Spring MVC使用端点的路径作为视图名称(我没有看到您的Mappings.LOAD_BOOKS常量,但应该是 load-books )。 如果您不打算将任何视图返回给浏览器,则可以对方法进行注释:

@GetMapping(Mappings.LOAD_BOOKS)
@ResponseBody
public void loadBooks(Model model) {

告诉Spring将void当作响应主体。 但这并不能阻止页面刷新,单击链接后您只会看到一个空白页面。为了解决这个问题,您可以通过返回以下字符串(方法中没有ResponseBody注释)将用户重定向到另一页。

return "redirect:/path-to-redirect";

当Spring MVC看到此前缀时,它会将您重定向到另一个控制器,但用户也会注意到这一点。

如果您真的不想暂时看到空白页,则必须使用一些JavaScript才能在单击按钮时向服务器执行AJAX请求。

实际上,看来您想通过给定路径预加载服务中的某些文件。如果您只想做这些,则可以像这样使用Spring的跑步者:

@Component
class Preloader implements ApplicationRunner {

    private final BookCatalogService bookService;

    @Autowired
    public Preloader(BookCatalogService service) {
        this.bookService = service;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        bookService.loadBooksFromDirectory(BookCatalogController.bookDirectory);
    }
}

在应用程序准备就绪后,Spring会自动调用所有已注册的运行器,因此无需用户访问加载项端点即可执行您的代码。