【问题标题】:Spring MVC (text field and button) using CrudRepository and Thymeleaf使用 CrudRepository 和 Thymeleaf 的 Spring MVC(文本字段和按钮)
【发布时间】:2019-02-28 14:46:02
【问题描述】:

我需要使用 CrudRepository 通过自定义方法创建一个简单的搜索按钮,并在网站上显示搜索结果。

Event.java

@Entity
@Table(name = "events")
public class Event {
    private String name;
}

EventRepository.java

public interface EventRepository extends CrudRepository<Event, Long>{
    public Iterable<Event> findByName(String name);
}

EventService.java

public interface EventService {
    public Iterable<Event> findByName(String name);
}

EventServiceImpl.java

@Service
public class EventServiceImpl implements EventService {

    @Override
    public Iterable<Event> findByName(String name) {
        return eventRepository.findByName(name);
    }
}

EventsController.java

@Controller
@RequestMapping(value = "/events", produces = { MediaType.TEXT_HTML_VALUE })
public class EventsController {

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public String showEventsByName(@ModelAttribute Event event, @RequestParam (value = "search", required = false) String name, Model model) {
        model.addAttribute("event", event);
        model.addAttribute("searchResult", eventService.findByName(name));

        return "events/index";
}

index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layouts/default}">
<head>
  <title>All events</title>
</head>
<body>
  <div layout:fragment="content">
    <h3>Search for an event by name</h2>
    <form th:object="${event}" th:action="@{/events/search}" method="get">
        <input type="text" name="search" id="search" th:value="${search}"/>
        <input type="submit" value="Search"/>
        <div th:if="${not #lists.isEmpty(search)}">
            <h2>Events search results</h2>
            <table class="table table-striped table-hover">
                <thead>
                    <tr>
                      <th><i class="fa fa-bolt"></i> Event</th>
                      <th><i class="fa fa-map-marker"></i> Venue</th>
                      <th><i class="fa fa-calendar"></i> Date</th>
                      <th><i class="fa fa-clock-o"></i> Time</th>
                    </tr>
                </thead>
                <tbody>
                    <tr th:each="event: ${searchResult}">
                      <td th:text="${event.name}"><a href="/event/${event.name}">My Event</a></td>
                      <td th:text="${event.venue.getName()}">Event venue</td>
                      <td th:text="${{event.date}}">Event date</td>
                      <td th:text="${{event.time}}">Event time</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </form>
    <h1>All events</h1>

    <table class="table table-striped table-hover">
      <thead>
        <tr>
          <th><i class="fa fa-bolt"></i> Event</th>
          <th><i class="fa fa-map-marker"></i> Venue</th>
          <th><i class="fa fa-calendar"></i> Date</th>
          <th><i class="fa fa-clock-o"></i> Time</th>
        </tr>
      </thead>
      <tbody>
        <tr th:each="e : ${events}">
          <td th:text="${e.name}">My Event</td>
          <td th:text="${e.venue.getName()}">Event venue</td>
          <td th:text="${{e.date}}">Event date</td>
          <td th:text="${{e.time}}">Event time</td>
        </tr>
      </tbody>
    </table>

  </div>

</body>
</html>

我正在使用自定义 CrudRepository 方法的命名约定,这意味着接口应该已经提供了实现。 当我运行 Web 应用程序并在表单中提交一些输入时,会显示所需的 html 视图,但搜索结果从不显示任何事件。 Picture 1 Picture 2

我尝试删除@ModelAttribute Event 事件和model.addAttribute("event", event);,因为this post which addresses the same issue 没有使用,但结果是一样的。

我知道已经有类似的帖子,但是那里建议的解决方案对我不起作用,我尝试了不同的方法,但结果不如预期。

【问题讨论】:

  • 您是否检查过您的 DAO 是否真正返回任何结果?
  • 我想我发现了问题:你的 div 依赖于 search 变量,但你从未设置它。尝试将其替换为searchResult
  • 如果您正在处理这一行 &lt;div th:if="${not #lists.isEmpty(search)}"&gt;,如果我将搜索更改为 searchResult 它不会改变结果。如果我将th:value="${search}" 更改为th:value="${searchResult}",我只会在我最初的帖子中图片2 的文本字段中看到那个奇怪的“[]”。
  • 另外,我发现了一些很奇怪的东西。我观看了一个 youtube 教程,其中作者实际上使用 POST 而不是 GET 方法,但是如果我在提交表单时将方法更改为 POST,我会被重定向到localhost:8080/sign-in,尽管我返回了,但它位于安全文件夹中我在控制器中的函数中的“事件/索引”。我认为我将控制器与 html 页面链接的方式有问题。
  • 搜索会得到数据,所以应该使用GET。如果你必须使用 POST 来保存数据什么的,那么你必须在客户端处理重定向,Ajax.onSuccess 重定向窗口 href 到新的重定向。

标签: java spring model-view-controller thymeleaf


【解决方案1】:
eventService.findByName(name);

将寻找完全匹配的名称

创建新的搜索方法

服务接口

public interface EventService {
    public Iterable<Event> findByName(String name);
    public Iterable<Event> searchForName(String name);
}

存储库

public interface EventRepository extends CrudRepository<Event, Long>{
    public Iterable<Event> findByName(String name);
    public Iterable<Event> findByNameContainingIgnoreCase(String name);
}

服务类

@Service
public class EventServiceImpl implements EventService {

    @Override
    public Iterable<Event> findByName(String name) {
        return eventRepository.findByName(name);
    }

    @Override
    public Iterable<Event> searchForName(String name) {
        return eventRepository.findByNameContainingIgnoreCase(name);
    }

}

更新:

当什么都不搜索时,你想什么都不显示还是什么都显示?我更喜欢后者。如果您不想显示任何内容,请在调用服务之前检查搜索参数。

@RequestMapping(value = "/search", method = RequestMethod.GET)
public String showEventsByName(@RequestParam (value = "search", required = false) String name, Model model) {
    if(name!=null && !name.isEmpty()){
       model.addAttribute("searchResult", eventService.searchForName(name));
    } // else{ } create an empty list or handle null in view
    // ...
}

如果您想在没有结果的情况下隐藏表头,请使用

th:if="${searchResult !=null and !searchResult.isEmpty()}" <!-- For Both -->

【讨论】:

  • 感谢您提出的解决方案,它奏效了!但是,我首先必须删除 div 块中的 if 条件,因为它会阻止显示其中包含的 html 内容。一切正常,但现在如果我提交一个空表单,它将显示搜索结果中的所有事件。
  • 我删除了thymeleaf条件并检查了控制器中的字符串是否为空,所以它可以工作。
猜你喜欢
  • 2017-05-09
  • 1970-01-01
  • 2021-06-02
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
相关资源
最近更新 更多