试图将使用的自定义对象从View传递到th:value
到Controller,但只能通过th:value
传递Java的原始数据类型。有什么办法可以通过th:value
我是新来的春天,正在尝试一些随机的东西。 这是一个简单的Web应用程序。
我有一个创建团队的表格。该表单包括一个用于团队名称的文本字段和一堆用于选择团队成员的复选框。对于每个选中的复选框,应将相应的成员添加到团队列表中。
我尝试使用thymeleaf的th:value
属性将对象从View传递到Controller。但是我只能使用th:value
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Create your Team</title>
</head>
<body>
<h1>Create your dream team</h1>
<form method="post" th:object="${team}">
<span>Name of the team</span>
<input type="text" th:field="*{name}">
<div th:each="player : ${playersList}">
<input type="checkbox" name="players" th:value="${player}" th:valueType="com.example.kkvamshee.Cricket.Player">
<span th:text="${player.name}">Player Name</span>
</div>
<button type="submit">Submit your team</button>
</form>
</body>
</html>
CreateTeamController.java
package com.example.kkvamshee.Cricket.web;
import com.example.kkvamshee.Cricket.Player;
import com.example.kkvamshee.Cricket.Team;
import com.example.kkvamshee.Cricket.data.JdbcPlayerRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
import java.util.List;
@Slf4j
@Controller
@RequestMapping("/create-your-team")
public class CreateTeamController {
....
@GetMapping
public String showSelectTeamPage(Model model) {
List<Player> playersList = playerRepo.findAll();
model.addAttribute("playersList", playersList);
model.addAttribute("team", new Team());
return "teamCreationForm";
}
.....
}
Team.java
package com.example.kkvamshee.Cricket;
import lombok.Data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
@Data
public class Team {
@NotNull private String name;
@Size(min = 3, max = 3, message = "You can only have 3 members on the team")
private List<Player> players;
}
Field error in object 'team' on field 'players': rejected value [Player(name=vamshee, age=20, exp=1),Player(name=messi, age=32, exp=18),Player(name=ronaldo, age=34, exp=18)]; codes [typeMismatch.team.players,typeMismatch.players,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [team.players,players]; arguments []; default message [players]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'players'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.kkvamshee.Cricket.Player' for property 'players[0]': no matching editors or conversion strategy found]
在此错误日志的末尾,“没有找到匹配的编辑器或转换策略”。
我尝试将th:valueType
更改为Integer
,并成功将对应的文本转换为Integer值。但是我在使用Team对象或任何其他自定义对象执行相同操作时遇到此强制转换错误。
答案 0 :(得分:1)
答案 1 :(得分:0)
模板引擎必须将<input ... th:value="${player}">
标记转换为HTML(浏览器可以理解的HTML),转换后的标记看起来像<input ... value="string returned by player.toString()">
。
因此,视图不了解对象Player
。该值只是视图的简单字符串。 Spring需要一些转换器才能将字符串转换为适当的Player对象。
这可以通过实现Converter<String, Player>
接口,然后在我们的应用程序中注册Converter来完成。
package com.example.kkvamshee.cricket.config;
import com.example.kkvamshee.cricket.Player;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.converter.Converter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
public class StringToPlayerConverter implements Converter<String, Player> {
@Override
public Player convert(String source) {
String pattern = "Player\\(name=([a-zA-z0-9]+), age=([1-9]+), exp=([1-9]+)\\)";
Matcher matcherResult = Pattern.compile(pattern).matcher(source);
log.info("regex result : " + matcherResult.find());
String name = matcherResult.group(1);
int age = Integer.parseInt(matcherResult.group(2));
int exp = Integer.parseInt(matcherResult.group(3));
return new Player(name, age, exp);
}
}
package com.example.kkvamshee.cricket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToPlayerConverter());
}
}
有多种方法可以实现这种类型转换。
有关更多详细信息,请参见documentation