将名单从Thymeleaf传递给Spring Controller

时间:2018-06-07 09:05:16

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

我尝试在更改选项后将我的Thymeleaf HTML中已提供的List传回控制器。我已经尝试了一个隐藏的输入,但不幸的是,它还没有工作。

我的表单看起来像这样(列表"电影"已由控制器提供)



<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>
&#13;
&#13;
&#13;

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

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";
    }
}

期待有人帮助我!

4 个答案:

答案 0 :(得分:1)

由于您的表单已发送电影列表,因此它将在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";
}

答案 1 :(得分:0)

如果我理解你的问题,你想在点击选择字段时调用电影列表,并将电影添加到某个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;
  }
    });
}

答案 2 :(得分:0)

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

1。)在您发送电影的控制器上创建表单对象(需要在表单提交后再向控制器发送): -

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

2。)使用相同的名称在表单上创建Thymeleaf对象 - &#34; some_value&#34;在这种情况下: -

<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&amp;创建Request类。 getter方法。 :---

  public class YourDesiredJavaClass{

       private List<String> movies;

      //setter & getter methods

    }

答案 3 :(得分:0)

@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";
    }
}

,然后在每种方法中填充或读取列表。