Как передать id в th: value и получить данные типа List <Ingredient>? - PullRequest
0 голосов
/ 12 июня 2019

Я изучаю загрузку Spring из Spring в действиях 5, глава 3, JDBC.

У меня есть класс Тако:

@Data
public class Taco {

    private Long id;
    private Date createdAt;

    @NotBlank
    @Size(min = 5, message = "Name must be at least 5 characters long")
    private String name;

    @Size(min = 1, message = "You must choose at least 1 ingredient")
    @NotNull(message = "You must choose at least 1 ingredient")
    private List<Ingredient> ingredients;   
}

И класс ингредиентов:

@Data
@AllArgsConstructor
public class Ingredient {

    private String id;
    private String name;
    private Type type;

    public static enum Type{
        WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
    }
}

Я использую Thymeleaf в передней части, вот так:

<form method="POST" th:object="${design}">

    <span class="validationError"
              th:if="${#fields.hasErrors('ingredients')}"
              th:errors="*{ingredients}">Ingredients Error</span>                                                

    <div class="grid">

        <!-- WRAP -->
        <div class="ingredient-group" id="wraps">
            <h3>Designate your WRAP:</h3>
            <div th:each="ingredient : ${wrap}" >
                <input name="ingredients" type="checkbox" th:value="${{ingredient.id}}" />
                <span th:text="${ingredient.name}">INGREDIENT</span>
            </div>
        </div>

        <!-- PROTEIN -->
        <div class="ingredient-group" id="proteins">
            <h3>Designate your PROTEIN:</h3>
            <div th:each="ingredient : ${protein}" >
                <input name="ingredients" type="checkbox" th:value="${{ingredient.id}}" />
                <span th:text="${ingredient.name}">INGREDIENT</span>
            </div>
        </div>  

И мой контроллер

@GetMapping
public String showDesignForm(Model theModel) {

    List<Ingredient> ingredients = new ArrayList<>();

    ingredientRepository.findAll().forEach(i -> ingredients.add(i));

    Type[] types = Ingredient.Type.values();

    for(Type type : types) {
        theModel.addAttribute(
                type.toString().toLowerCase(), 
                filterByType(ingredients, type));
    }

    theModel.addAttribute("design", new Taco());

    return "design";
}

Мой JdbcIngredientRepository

@Repository
public class JdbcIngredientRepository implements IngredientRepository, RowMapper<Ingredient>{

    private JdbcTemplate jdbc;

    @Autowired
    public JdbcIngredientRepository(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    @Override
    public Iterable<Ingredient> findAll() {

        String sqlQuery = "select id, name, type from Ingredient";

        return jdbc.query(sqlQuery, this::mapRow);
    }

Проблема в том, что при отправке я получаю сообщение об ошибке: Can't convert from List<String> to List<Ingredient>.

Я могу решить эту проблему, изменив private List<Ingredient> ingredients; на private List<String> ingredients;. Но я думаю, что это плохая практика? У кого-нибудь есть лучший способ прямой передачи данных, выбранных из th: value, в List?

1 Ответ

1 голос
/ 12 июня 2019

Вы можете просто преобразовать строки из репозитория в ингредиенты, сопоставив результат ingredientRepository.findAll().

@GetMapping
public String showDesignForm(Model theModel) {

    List<Ingredient> ingredients = 
        ingredientRepository.findAll()
            .stream()
            .map(ingredientName -> new Ingredient(ingredientName))
            .collect(Collectors.toList());

    Type[] types = Ingredient.Type.values();

    for(Type type : types) {
        theModel.addAttribute(
                type.toString().toLowerCase(), 
                filterByType(ingredients, type));
    }

    theModel.addAttribute("design", new Taco());

    return "design";
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...