如何将JavaScript字符串数组提交至Spring Boot/Thymeleaf的VenueForm对象
如何将原生JS数组绑定到Thymeleaf表单的Spring List字段
问题背景
我正在使用Spring Boot + Thymeleaf + 原生JavaScript开发,JS中定义了一个可动态增删的字符串数组:
var tags = ["ramen", "japanese"];
需要通过HTML表单将这个数组提交到后端,后端使用VenueForm的List<String> tags字段接收数据。之前尝试阻止表单提交后给输入框赋值,但没有成功,想知道怎么实现JS数组到Thymeleaf表单List字段的绑定。
相关代码:
- 表单结构:
<form id="tag-form" class="form" method="POST" th:object="${venueForm}" th:action="/venue/tag">
- VenueForm.java:
public class VenueForm { private List<String> tags; private Object otherStuff; // Getters and Setters }
- VenueController.java:
@Controller @RequestMapping("/venue/tag") public class VenueController { @PostMapping public String createVenue(@ModelAttribute VenueForm venueForm){ List<String> tags = venueForm.getTags(); System.out.println(tags); return "tags"; } }
解决方案
方法一:动态生成隐藏输入框(推荐)
Spring MVC支持通过参数名[索引]的格式自动绑定List集合,我们可以在表单提交前,根据JS数组动态生成对应数量的隐藏输入框,让后端自动接收。
实现步骤:
- 在表单内添加一个容器,用于存放动态生成的隐藏输入:
<form id="tag-form" class="form" method="POST" th:object="${venueForm}" th:action="/venue/tag"> <!-- 其他表单字段 --> <div id="tags-container"></div> <input type="submit" value="Submit" onclick="submitForm(event)"> </form>
- 修改JS的提交函数:
var tags = ["ramen", "japanese"]; function submitForm(event) { event.preventDefault(); const form = document.getElementById('tag-form'); const container = document.getElementById('tags-container'); // 清空容器内旧的输入框 container.innerHTML = ''; // 遍历JS数组,生成对应隐藏输入 tags.forEach((tag, index) => { const input = document.createElement('input'); input.type = 'hidden'; input.name = `tags[${index}]`; // 关键:name格式匹配Spring List绑定规则 input.value = tag; container.appendChild(input); }); // 手动提交表单 form.submit(); }
后端代码无需修改,Spring会自动将这些参数绑定到VenueForm的tags List中。
方法二:通过JSON字符串传递(需后端解析)
如果不想生成多个输入框,可以将JS数组转为JSON字符串,通过单个隐藏输入传递,后端再解析为List。
实现步骤:
- 在表单内添加一个隐藏输入:
<form id="tag-form" class="form" method="POST" th:object="${venueForm}" th:action="/venue/tag"> <!-- 其他表单字段 --> <input type="hidden" id="tags-input" name="tagsJson"> <input type="submit" value="Submit" onclick="submitForm(event)"> </form>
- 修改JS提交函数:
var tags = ["ramen", "japanese"]; function submitForm(event) { event.preventDefault(); const input = document.getElementById('tags-input'); input.value = JSON.stringify(tags); document.getElementById('tag-form').submit(); }
- 修改后端代码:
- 更新
VenueForm,添加接收JSON字符串的字段:
- 更新
public class VenueForm { private List<String> tags; private String tagsJson; private Object otherStuff; // Getters and Setters }
- 在控制器中解析JSON字符串为List:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/venue/tag") public class VenueController { @PostMapping public String createVenue(@ModelAttribute VenueForm venueForm){ ObjectMapper objectMapper = new ObjectMapper(); try { List<String> tags = objectMapper.readValue(venueForm.getTagsJson(), new TypeReference<List<String>>() {}); venueForm.setTags(tags); System.out.println(tags); } catch (JsonProcessingException e) { e.printStackTrace(); } return "tags"; } }
内容的提问来源于stack exchange,提问作者grayliam
相关产品推荐
相关产品推荐

