如何将对象列表与百里香咖啡绑定?
我在将表单POS回控制器时遇到了很多困难,控制器应该只包含用户可以编辑的对象数组列表。
表单正确加载,但是当它发布时,它似乎从未真正发布任何内容。
这是我的表格:
<form action="#" th:action="@{/query/submitQuery}" th:object="${clientList}" method="post">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Select</th>
<th>Client ID</th>
<th>IP Addresss</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr th:each="currentClient, stat : ${clientList}">
<td><input type="checkbox" th:checked="${currentClient.selected}" /></td>
<td th:text="${currentClient.getClientID()}" ></td>
<td th:text="${currentClient.getIpAddress()}"></td>
<td th:text="${currentClient.getDescription()}" ></td>
</tr>
</tbody>
</table>
<button type="submit" value="submit" class="btn btn-success">Submit</button>
</form>
上面工作正常,它正确地加载了列表。但是,当我开机自检时,它返回一个空对象(大小为0)。我相信这是由于缺乏,但无论如何这里是控制器POST方法:th:field
...
private List<ClientWithSelection> allClientsWithSelection = new ArrayList<ClientWithSelection>();
//GET method
...
model.addAttribute("clientList", allClientsWithSelection)
....
//POST method
@RequestMapping(value="/submitQuery", method = RequestMethod.POST)
public String processQuery(@ModelAttribute(value="clientList") ArrayList clientList, Model model){
//clientList== 0 in size
...
}
我尝试过添加一个,但无论我做什么,它都会导致异常。th:field
我试过了:
...
<tr th:each="currentClient, stat : ${clientList}">
<td><input type="checkbox" th:checked="${currentClient.selected}" th:field="*{}" /></td>
<td th th:field="*{currentClient.selected}" ></td>
...
我无法访问currentClient(编译错误),我甚至不能选择 clientList,它给了我像 ,等选项,所以它应该有一个数组,但是,我不能传入数组。get()
add()
clearAll()
我也尝试过使用类似的东西,这会导致运行时异常th:field=${}
我试过了
th:field = "*{clientList[__currentClient.clientID__]}"
但也编译错误。
有什么想法吗?
更新 1:
托比亚斯建议我需要把我的清单包装成一个捕食者。这就是我所做的:
ClientWithSelectionWrapper:
public class ClientWithSelectionListWrapper {
private ArrayList<ClientWithSelection> clientList;
public List<ClientWithSelection> getClientList(){
return clientList;
}
public void setClientList(ArrayList<ClientWithSelection> clients){
this.clientList = clients;
}
}
我的页面:
<form action="#" th:action="@{/query/submitQuery}" th:object="${wrapper}" method="post">
....
<tr th:each="currentClient, stat : ${wrapper.clientList}">
<td th:text="${stat}"></td>
<td>
<input type="checkbox"
th:name="|clientList[${stat.index}]|"
th:value="${currentClient.getClientID()}"
th:checked="${currentClient.selected}" />
</td>
<td th:text="${currentClient.getClientID()}" ></td>
<td th:text="${currentClient.getIpAddress()}"></td>
<td th:text="${currentClient.getDescription()}" ></td>
</tr>
然后我的控制器:
@RequestMapping(value="/submitQuery", method = RequestMethod.POST)
public String processQuery(@ModelAttribute ClientWithSelectionListWrapper wrapper, Model model){
...
}
页面正确加载,数据按预期显示。如果我在没有任何选择的情况下发布表单,我得到这个:
org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'clientList' cannot be found on null
不知道为什么在抱怨
(在GET方法中,它具有:model.addAttribute("wrapper", wrapper);
)
如果我随后进行选择,即勾选第一个条目:
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='clientWithSelectionListWrapper'. Error count: 1
我猜我的POST控制器没有获得客户端WithSelectionListWrapper。不知道为什么,因为我已经设置了包装器对象通过FORM标头回发。th:object="wrapper"
更新 2:
我取得了一些进展!最后,控制器中的POST方法正在拾取提交的表单。但是,所有属性似乎都为 null,但项目是否已勾选。我做了各种更改,这就是它的外观:
<form action="#" th:action="@{/query/submitQuery}" th:object="${wrapper}" method="post">
....
<tr th:each="currentClient, stat : ${clientList}">
<td th:text="${stat}"></td>
<td>
<input type="checkbox"
th:name="|clientList[${stat.index}]|"
th:value="${currentClient.getClientID()}"
th:checked="${currentClient.selected}"
th:field="*{clientList[__${stat.index}__].selected}">
</td>
<td th:text="${currentClient.getClientID()}"
th:field="*{clientList[__${stat.index}__].clientID}"
th:value="${currentClient.getClientID()}"
></td>
<td th:text="${currentClient.getIpAddress()}"
th:field="*{clientList[__${stat.index}__].ipAddress}"
th:value="${currentClient.getIpAddress()}"
></td>
<td th:text="${currentClient.getDescription()}"
th:field="*{clientList[__${stat.index}__].description}"
th:value="${currentClient.getDescription()}"
></td>
</tr>
我还向我的包装类添加了一个默认的无参数构造函数,并向 POST 方法添加了一个参数(不确定是否需要)。bindingResult
public String processQuery(@ModelAttribute ClientWithSelectionListWrapper wrapper, BindingResult bindingResult, Model model)
当然,systemInfo 应该是空的(在这个阶段),但是 clientID 总是 0,而 ipAddress/Description 总是空的。所选布尔值对于所有属性都是正确的。我确信我在某个地方的某个属性上犯了一个错误。回到调查。
更新 3:
好的,我已经设法正确填写了所有值!但是我不得不改变我的,以包括一个这不是我想要的...尽管如此,这些值正在正确填充,这表明spring寻找输入标记可能是用于数据映射?td
<input />
以下是我如何更改 clientID 表数据的示例:
<td>
<input type="text" readonly="readonly"
th:name="|clientList[${stat.index}]|"
th:value="${currentClient.getClientID()}"
th:field="*{clientList[__${stat.index}__].clientID}"
/>
</td>
现在我需要弄清楚如何将其显示为纯数据,理想情况下没有任何输入框...