【问题标题】:Passing List from Thymeleaf to Spring Controller将列表从 Thymeleaf 传递到 Spring 控制器
【发布时间】:2018-11-17 03:11:46
【问题描述】:

我试图在更改选项后将我的 Thymeleaf HTML 中已提供的列表传递回控制器。我用隐藏的输入试过了,但不幸的是,它还没有工作。

我的表单看起来像这样(控制器已经提供了一个列表“电影”)

<form action="/movies" method="POST">
    <input type="hidden" th:field="*{movies}" name="movies"/>
    <select name="myselect" id="myselect" onchange="this.form.submit()">
        <option value="1">Sort by Name (A-Z)</option>
        <option value="2">Sort by Name (Z-A)</option>
        <option value="3">Newest First</option>
        <option value="4">Oldest First</option>
    </select>
</form>

我的控制器看起来像这样:

package at.spengergasse.omdbspring.controller;

import at.spengergasse.omdbspring.domain.Movie;
import at.spengergasse.omdbspring.service.MovieService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@RequiredArgsConstructor

@Controller
public class MoviesController {
    private final MovieService movieService;

    @GetMapping("/")
    public String greeting(Model model) {
        model.addAttribute("movies", movieService.findAll());
        return "movies";
    }

    @PostMapping("/movies")
    public String getMoviesOrdered(@RequestAttribute List<Movie> movies, @RequestParam String myselect, Model model){
        model.addAttribute(movieService.findCustomListSorted(movies,myselect));
        return "movies";
    }
}

期待你能帮助我的人!

【问题讨论】:

    标签: java spring spring-boot parameter-passing thymeleaf


    【解决方案1】:

    我在我的项目中遇到了同样的问题,其中隐藏列表值已由控制器提供,然后需要将相同的值进一步传递给控制器​​。 我已经使用 @ModelAttribute 注释解决了它(我根据您的要求粘贴了我的相同代码):---

    1.) 在您发送电影的控制器上创建表单对象(需要在表单提交后进一步发送到控制器):-

        model.addAttribute("some_value", new YourDesiredJavaClass());
    

    2.) 在表单上以相同的名称创建 Thymeleaf 对象 - 在本例中为“some_value”:--

    <form action="/movies" th:object="${some_value}" method="POST">
        <input th:field="${movies}" type="hidden" ></input>
    </form>
    

    3.) 从 Thymleaf 获取 List 到控制器。 :--

     @PostMapping("movies")
             public String getMovies(@ModelAttribute("some_value") YourDesiredJavaClass requestClass, Model model) {
    

    // 进一步的代码..

    }


    4.) 使用 setter 和 getter 方法创建 Request 类。 :---

      public class YourDesiredJavaClass{
    
           private List<String> movies;
    
          //setter & getter methods
    
        }
    

    【讨论】:

    • 非常感谢
    • 当然我会根据自己的需要稍微调整一下,但概念是这样的。谢谢
    【解决方案2】:

    当您的电影列表通过您的表单发送时,它将在 HTTP POST 正文中可用。所以你必须使用@RequestBody 而不是@RequestAttribute

    @PostMapping("/movies")
    public String getMoviesOrdered(@RequestBody List<Movie> movies, @RequestParam String myselect, Model model){
        model.addAttribute(movieService.findCustomListSorted(movies,myselect));
        return "movies";
    }
    

    【讨论】:

    • 感谢您的帮助,如果这样做,我会收到错误:Resolved exception caused by Handler execution: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
    • 您的请求映射必须指定它使用application/x-www-form-urlencoded;charset=UTF-8。您可以通过添加consumes="application/x-www-form-urlencoded;charset=UTF-8" 来实现。例如:@PostMapping("/movies", consumes="application/x-www-form-urlencoded;charset=UTF-8")
    • 我现在更改了它,但仍然出现错误。我的控制器现在看起来像这样:@PostMapping(value="/movies", consumes="application/x-www-form-urlencoded;charset=UTF-8") public String getMoviesOrdered(@RequestBody List&lt;Movie&gt; movies, @RequestParam String myselect, Model model){ model.addAttribute(movieService.findCustomListSorted(movies,myselect)); return "movies"; }
    • 您可能需要将其更改为"application/json; charset=utf-8"
    • 还是... html中的表格可能有问题?
    【解决方案3】:

    如果我正确理解您的问题,您想在单击选择字段时调用电影列表并将电影添加到某个 div 吗?这可以通过对控制器的 AJAX 调用来完成,这样在完成后,它将用内容填充 div,如果这有意义的话:

        function getMoviesOrdered(myselect){
        var prep = {};
        prep['movies'] = myselect;
    
        var data = JSON.stringify(prep);
        $.ajax({
      url:"/movies",
      type:"POST",
      data:data,
      contentType:"application/json; charset=utf-8",
      dataType:"json",
      error:function(){},
      complete:function(data){
      document.getElementById("#someDivId").innerHTML = data;
      }
        });
    }
    

    【讨论】:

    • 感谢您的回复!是的,如果我想立即将 div 从 HTML 中更改出来,这可能是正确的。在这种情况下,我不想使用 AJAX,而是我的目标是将列表传递回 Java @Controller 并在那里处理它。
    【解决方案4】:
    @RequestBody List<Movie> movies
    

    仅在我添加时才为我工作

    consumes="application/json; charset=utf-8"
    

    这并不总是您想要做的。包装器对象的公认答案也有效,但只为所有控制器方法声明全局变量会更简单:

    @RequiredArgsConstructor
    @Controller
    public class MoviesController {
        private final MovieService movieService;
        private final Set<Movie> movieSet = new HashSet<>();
    
        @GetMapping("/")
        public String greeting(Model model) {
            movieSet.addAll("movies", movieService.findAll());
            model.addAttribute("movies", movieSet);
            return "movies";
        }
    
        @PostMapping("/movies")
        public String getMoviesOrdered(@RequestParam String myselect, Model model){
            model.addAttribute(movieService.findCustomListSorted(movieSet, myselect));
            return "movies";
        }
    }
    

    并在每个方法中填充或读取列表。

    【讨论】:

      猜你喜欢
      • 2019-07-05
      • 2017-03-06
      • 2022-08-23
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      • 2012-11-16
      相关资源
      最近更新 更多