简体   繁体   English

将自定义对象从thymeleaf视图传递到控制器

[英]Passing Custom Objects from thymeleaf View to a Controller

Trying to pass Custom made objects using to th:value from View to Controller but only able to pass Java's primitive Data types through th:value . 尝试使用Custom对象将View中的th:value传递给Controller,但只能通过th:value传递Java的原始数据类型。 Is there any way I can send complex objects through th:value 有什么办法可以通过th:value发送复杂的对象

I am new to spring and trying out some random things. 我是新来的春天,正在尝试一些随机的东西。 It is a simple web application. 这是一个简单的Web应用程序。

What I'm trying to do: 我正在尝试做的是:

I have a form for creating a team. 我有一个创建团队的表格。 The form includes a text field for a team name and a bunch of checkboxes to select the team members. 该表单包括一个用于团队名称的文本字段和一堆用于选择团队成员的复选框。 For each selected checkbox the corresponding member should be added into the team list. 对于每个选中的复选框,应将相应的成员添加到团队列表中。

I tried using thymeleaf's th:value attribute to pass objects from View to Controller. 我尝试使用thymeleaf的th:value属性将对象从View传递到Controller。 But I can only pass String values using th:value 但是我只能使用th:value传递字符串值

teamCreationForm.html teamCreationForm.html
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;
}

CreateTeamController.java 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 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; } 

Error Log 错误记录

 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] 

At the end of thid error log, there is "no matching editors or conversion strategy found". 在此错误日志的末尾,“没有找到匹配的编辑器或转换策略”。

I tried changing the th:valueType to Integer and it successfully casted corresponding text into Integer values. 我尝试将th:valueType更改为Integer ,并成功将对应的文本转换为Integer值。 But i get this casting error doing the same thing with Team object or any other custom made object for instance. 但是我在使用Team对象或任何其他自定义对象执行相同操作时遇到此铸造错误。

Thymeleaf can know which object you are working with especially if you have it mapped correctly and accepting it appropriately. Thymeleaf可以知道您正在使用哪个对象,特别是如果您正确地映射了它并正确接受了它。 Look at the test I did with your code. 查看我对您的代码所做的测试。

Please watch how the action is introduced in the form. 请注意如何在表单中介绍操作。

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

Template engine has to convert the <input ... th:value="${player}"> tag into HTML(something a browser can understand) and the converted tag looks like <input ... value="string returned by player.toString()"> . 模板引擎必须将<input ... th:value="${player}">标记转换为HTML(浏览器可以理解的标记),并且转换后的标记类似于<input ... value="string returned by player.toString()">

So, the view has no idea of the Object Player . 因此,视图不了解Object Player The value is just a simple string to the view. 该值只是视图的简单字符串。 Spring needs some converter to convert the string to an appropriate Player Object. Spring需要一些转换器将字符串转换为适当的Player对象。

This can be done by implementing Converter<String, Player> Interface and then registering the Converter in our application. 这可以通过实现Converter<String, Player>接口,然后在我们的应用程序中注册Converter来完成。

Implementation of Converter Interface : 转换器接口的实现:

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

Registering the above Converter Object : 注册上述Converter对象:

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());
    }
}

There are various methods to acheive this type conversion. 有多种方法可以实现这种类型转换。

For more details refer to the documentation 有关更多详细信息,请参阅文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM