【问题标题】:Spring mvc Ajax search Form with Thymeleaf带有 Thymeleaf 的 Spring mvc Ajax 搜索表单
【发布时间】:2016-03-13 23:54:42
【问题描述】:

我正在尝试在我的 spring mvc web 应用程序的每个页面的导航栏中添加一个搜索表单,就像 stackoverflow 上的那个一样,我遇到了问题。现在我在我的几个页面上有一个可用的搜索功能,使用典型的 mvc 表单。我获取输入的字符串并将一个名为“searchString”的变量存储在我创建的名为“searchForm.java”的对象中。然后我尝试使用 spring data 的 findbycontaing 方法在数据库中查询输入的字符串,然后将该结果放在模型上,然后使用 thymeleaf 将其表示在视图上。但是我认为导航栏应该使用 ajax 来完成,因为它在每个页面和其他表单的页面上。

所以我想我正在将提交给导航栏中搜索表单的字符串发送到控制器,在那里我在存储库中查询它以带回搜索结果,然后我尝试将搜索结果放在模型上,但我什么也没得到,它所做的只是将我重定向到搜索页面。我可能没有多大意义,但我会展示我的代码,如果有人可以让我知道我是否以正确的方式解决我的问题,以及你们是否在我的代码中看到任何错误。提前致谢。

所以这是我提交表单的 ajax 和 jquery。

<script th:inline="javascript">

    /*<![CDATA[*/

    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");

    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });

    $(document).ready(function(){
    $("#searchButton").on("click", function(ev) {
        $.ajax({
            url : "navSearch",
            type : "post",
            data : {
                "newSearch" : $("#newSearch").val()
            },
            success : function(data) {
                console.log(data);
            },
            error : function() {
                console.log("There was an error");
            }

        });
    });
  });
/*]]>*/
</script>

这里可能存在问题,因为在 chrome 开发人员工具的控制台中,在重定向之前,会很快弹出一条消息,上面写着uncaught TypeError: Cannot read property 'toLowerCase' of undefined,它来自jquery.min.js:5,所以这可能是我的问题,但我不知道如何解决这个问题,到目前为止我一直在寻找答案,但没有运气。

这是我的html表单,我认为这应该不是问题,但谁知道呢,所以我还是把它放上去。我在这个视图中使用百里香。

<form action = "setSearch" class="navbar-form navbar-right">
            <div class="form-group">
            <input type="text" class="form-control" placeholder="Search" id="newSearch"></input>
            <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
            </div>
            <button type="submit" class="btn btn-default" id="searchButton">Search</button>
        </form>

这是我的 searchForm.java 类,我将要查询的字符串临时存储在数据库中。

public class SearchForm {

private String searchString;

public String getSearchString()
{
    return searchString;
}

public void setSearchString(String searchString)
{
    this.searchString = searchString;
}
}

这是我的控制器,我正在尝试处理 ajax 提交并将其作为 setSearch.html 页面上的搜索结果返回。我在这里想的是,表单中的字符串“newSearch”可以使用 Spring Data 查询方法进行匹配,然后能够将其返回并将其添加到模型中,但它不起作用,它只是将我重定向到没有数据的 /searchSet 页面,因为这是表单操作所在的位置,这就是我告诉它返回的内容。所以老实说,我不确定是否有任何数据达到这一点。

@RequestMapping(value="setSearch/navSearch", method=RequestMethod.POST)
public @ResponseBody String navSearch (@RequestParam String newSearch, ModelMap model)
{   
    List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
    model.put("searchResult", questionAnswerSetByQuestion);

    return "setSearch";
}

这是我在控制器中使用的有效搜索方法的示例,我在 /searchSet 页面上的常规表单上使用它,没有 ajax。

    @RequestMapping(value="/setSearch", method=RequestMethod.GET)
public String searchGet(ModelMap model) {

    SearchForm searchForm = new SearchForm();
    model.put("searchForm", searchForm);

    return "setSearch";
}

@RequestMapping(value="/setSearch", method=RequestMethod.POST)
public String searchPost(@ModelAttribute SearchForm searchForm, ModelMap model) {

    List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(searchForm.getSearchString());
    model.put("searchResult", questionAnswerSetByQuestion);

    return "setSearch";
}

更新

我已将表单中的代码从&lt;button type="submit" class="btn btn-default" id="searchButton"&gt;Search&lt;/button&gt; 更改为&lt;button type="button" class="btn btn-default" id="searchButton"&gt;Search&lt;/button&gt;,现在我得到了之前的Uncaught TypeError: Cannot read property 'toLowerCase' of undefined,页面没有任何反应。

更新

我现在可以毫无问题地提交 ajax 表单,我在标头中缺少元标记,所以 csrf 没有正确提交,所以现在我在 chrome 开发人员工具控制台中收到此错误XHR Loaded (navSearch - 405 Method Not Allowed - 7.265999971423298ms - 634B)

更新

现在一切都在 Ajax 端运行,我需要调整我的 url 以匹配我在控制器上的请求映射中的 url,它可以很好地运行所有代码。但是整体搜索功能还是不行,这是我更新的控制器。

我知道我的问题是我返回的是字符串而不是对象,但我不确定如何返回对象然后将 url 重定向到 /setSearch 页面。它正在运行代码并在控制台中返回一个字符串“setSearch”,因为我在控制器的末尾告诉它。

@RequestMapping(value="/setSearch/search", method=RequestMethod.POST)
public @ResponseBody String search (@RequestParam String newSearch, ModelMap model)
{   
    List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
    model.put("searchResult", questionAnswerSetByQuestion);

    return "setSearch";
}

这是我的工作 ajax

    <script th:inline="javascript">

    /*<![CDATA[*/

    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");

    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });

    $(document).ready(function(){
    $("#searchButton").on("click", function(ev) {
        $.ajax({
            url : "/setSearch/search",
            type : "post",
            data : {
                "newSearch" : $("#newSearch").val()
            },
            success : function(data) {
                console.log(data);
            },
            error : function() {
                console.log("There was an error");
            }

        });
    });
  });
/*]]>*/
</script>

【问题讨论】:

  • 几件事,搜索应该是 GET 而不是 POST 请求(坚持 Restfull 原则)。接下来单击控制台本身的错误并查看它的来源。它来自javascript还是您的服务器代码?然后把有问题的代码部分复制下来放到题中。
  • 错误来自jquery.min.js:5
  • 请求发布了吗?我在您发布的代码中没有发现任何问题。可能是由其他代码引起的。
  • 这很奇怪,但现在它说它在第9026行,当我点击它时它与这个部分有关setRequestHeader: function( name, value ) { var lname = name.toLowerCase(); if ( !state ) { name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; requestHeaders[ name ] = value; }
  • 我明白了,所以问题出在xhr.setRequestHeader(header, token);。可能没有定义名为 _csrf 和 csrf_header 的元数据?

标签: ajax spring-mvc spring-data thymeleaf


【解决方案1】:

但它不起作用,它只是将我重定向到 /searchSet 页面 没有数据,因为那是表单操作的地方,那就是 我告诉它返回的内容

您是对的,这是因为您正在提交表单并在操作中指定将其提交到setSearch,这就是页面被重定向到同一页面的原因。只需将button type="submit" 替换为button type="button",这样点击searchButton 时不会提交表单。

【讨论】:

  • 好的,我改变了它,现在它不再重定向,但我仍然在控制台中收到错误uncaught TypeError: Cannot read property 'toLowerCase' of undefined。
猜你喜欢
  • 2016-03-14
  • 2017-11-13
  • 2014-06-17
  • 2023-03-25
  • 2014-01-25
  • 1970-01-01
  • 2015-07-06
  • 2017-05-23
  • 1970-01-01
相关资源
最近更新 更多