我可以在 Spring 引导应用程序中从 Thymeleaf table 发出 HTTP POST 请求吗
Can I make HTTP POST request from Thymeleaf table in Spring Boot application
我在一个简单的 Spring 引导应用程序中有一个 Thymeleaf 模板。该模板在 table 中包含一个列表,如下所示:
<p>There are <span th:text="${#lists.size(persons)}"></span> people:</p>
<table th:if="${not #lists.isEmpty(persons)}" border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Address</th>
<th>Telephone</th>
<th>Email</th>
<th>Actions</th>
</tr>
<tr th:each="person : ${persons}">
<td th:text="${person.personId}"></td>
<td th:text="${person.name}"></td>
<td th:text="${person.address}"></td>
<td th:text="${person.telephone}"></td>
<td th:text="${person.email}"></td>
<td>
<a href="#" data-th-href="@{/edit(personId=${person.personId})}">Edit</a> |
<a href="#" data-th-href="@{/delete(personId=${person.personId})}">Delete</a>
</td>
</tr>
</table>
我想根据 table 中的最后一个单元格启用编辑和删除功能。但目前这两个请求都是针对 HTTP GET 的。这对于从服务器获取个人详细信息进行编辑的编辑来说很好,但是由于服务器上的数据更改,删除应该触发 POST 请求。
有谁知道 Thymeleaf 是否允许 POST 每行 table 请求?还是我必须每行写一个简单的 HTML 表格?
GET 表单当前为:
<td>
<a href="#" data-th-href="@{/edit(personId=${person.personId})}">Edit</a>
<!--a href="#" data-th-href="@{/delete(personId=${person.personId})}">Delete</a></td-->
<form method="get" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value">Edit</button>
</form>
</td>
我有 link 和测试表格。
要调用的控制器方法是:
// Gets a Person.
@RequestMapping(value="/edit", method=RequestMethod.GET)
public String getEditPerson(@RequestParam("personId") String personId, Model model) {
logger.info(PersonController.class.getName() + ".getEditPerson() method called.");
Person person = personDAO.get(Integer.parseInt(personId));
model.addAttribute("person", person);
// Set view.
return "/edit";
}
调用按钮版GET时报错为:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Jul 24 00:26:16 BST 2016
There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'personId' is not present`
我正在使用 GET 触发编辑,因为除了 personId 之外,这里没有数据发送到服务器。未执行任何数据库操作,因此它应该是 GET。
您正在使用链接,但我认为这是不可能的,您需要使用一个表格来指定要使用的方法 POST。
在下面的示例中,我使用 <button>
而不是 <a>
元素,但它会起作用,您唯一需要做的就是使用 CSS 设置按钮样式看起来像您的链接
<form method="POST" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">This is a link that sends a POST request</button>
</form>
现在你的代码应该是这样的
<tr th:each="person : ${persons}">
<td th:text="${person.personId}"></td>
<td th:text="${person.name}"></td>
<td th:text="${person.address}"></td>
<td th:text="${person.telephone}"></td>
<td th:text="${person.email}"></td>
<td>
<form method="POST" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">EDIT</button>
</form> |
<form method="POST" th:action="@{/delete(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">DELETE</button>
</form>
</td>
</tr>
编辑
正如您刚刚分享的 Java 代码,在控制器中您希望 personId 不是 PathVariable,而是 RequestParam,
在这种情况下,您的表单应该具有该值...
编辑您的表单并添加人员 ID,如下所示。
<form method="POST" th:action="@{/edit}">
<input type="hidden" name="personid" id="personId" th:value="${person.personId}" />
<button type="submit" name="submit" value="value" class="link-button">This is a link that sends a POST request</button>
</form>
另请注意,我将表单的操作更改为 /edit,因为它是您的控制器的样子
Does anyone know if Thymeleaf allow a POST request per row of a table? Or do I have to write a simple HTML form per row?
HTML 不支持带链接的 POST 请求,您必须使用表单(如 Rayweb_on 所解释)。但是 Thymeleaf 允许您定义自定义标签,这很有帮助:
<a th:href="@{/edit(personId=${person.personId})}" custom:linkMethod="post">Edit</a>
... 将生成以下 HTML(假设 jQuery 可用):
<a href="#" onclick="$('<form action="/edit/personId=123456" method="post"></form>').appendTo('body').submit(); return false;">Edit</a>
自定义标签定义(没有错误检查以保持简单):
/**
* Custom attribute processor that allows to specify which method (get or post) is used on a standard link.
*/
public class LinkMethodAttrProcessor extends AbstractAttributeTagProcessor {
private static final String ATTR_NAME = "linkMethod";
private static final int PRECEDENCE = 10000;
public LinkMethodAttrProcessor(final String dialectPrefix) {
super(
TemplateMode.HTML, // This processor will apply only to HTML mode
dialectPrefix, // Prefix to be applied to name for matching
null, // No tag name: match any tag name
false, // No prefix to be applied to tag name
ATTR_NAME, // Name of the attribute that will be matched
true, // Apply dialect prefix to attribute name
PRECEDENCE, // Precedence (inside dialect's own precedence)
true); // Remove the matched attribute afterwards
}
@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag,
final AttributeName attributeName, final String attributeValue,
final IElementTagStructureHandler structureHandler) {
// get the method name (tag parameter)
final IEngineConfiguration configuration = context.getConfiguration();
final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
final IStandardExpression expression = parser.parseExpression(context, attributeValue);
final String method = (String) expression.execute(context);
// add custom javascript to change link method
final String link = tag.getAttribute("href").getValue();
final String action = "$('<form action="" + link + "" method="" + method + ""></form>').appendTo('body').submit(); return false;";
structureHandler.setAttribute("onclick", action);
structureHandler.setAttribute("href", "#");
}
}
有关如何注册此自定义属性的示例,请参阅 the Thymelead documentation。
我在一个简单的 Spring 引导应用程序中有一个 Thymeleaf 模板。该模板在 table 中包含一个列表,如下所示:
<p>There are <span th:text="${#lists.size(persons)}"></span> people:</p>
<table th:if="${not #lists.isEmpty(persons)}" border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Address</th>
<th>Telephone</th>
<th>Email</th>
<th>Actions</th>
</tr>
<tr th:each="person : ${persons}">
<td th:text="${person.personId}"></td>
<td th:text="${person.name}"></td>
<td th:text="${person.address}"></td>
<td th:text="${person.telephone}"></td>
<td th:text="${person.email}"></td>
<td>
<a href="#" data-th-href="@{/edit(personId=${person.personId})}">Edit</a> |
<a href="#" data-th-href="@{/delete(personId=${person.personId})}">Delete</a>
</td>
</tr>
</table>
我想根据 table 中的最后一个单元格启用编辑和删除功能。但目前这两个请求都是针对 HTTP GET 的。这对于从服务器获取个人详细信息进行编辑的编辑来说很好,但是由于服务器上的数据更改,删除应该触发 POST 请求。
有谁知道 Thymeleaf 是否允许 POST 每行 table 请求?还是我必须每行写一个简单的 HTML 表格?
GET 表单当前为:
<td>
<a href="#" data-th-href="@{/edit(personId=${person.personId})}">Edit</a>
<!--a href="#" data-th-href="@{/delete(personId=${person.personId})}">Delete</a></td-->
<form method="get" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value">Edit</button>
</form>
</td>
我有 link 和测试表格。
要调用的控制器方法是:
// Gets a Person.
@RequestMapping(value="/edit", method=RequestMethod.GET)
public String getEditPerson(@RequestParam("personId") String personId, Model model) {
logger.info(PersonController.class.getName() + ".getEditPerson() method called.");
Person person = personDAO.get(Integer.parseInt(personId));
model.addAttribute("person", person);
// Set view.
return "/edit";
}
调用按钮版GET时报错为:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Jul 24 00:26:16 BST 2016
There was an unexpected error (type=Bad Request, status=400).
Required String parameter 'personId' is not present`
我正在使用 GET 触发编辑,因为除了 personId 之外,这里没有数据发送到服务器。未执行任何数据库操作,因此它应该是 GET。
您正在使用链接,但我认为这是不可能的,您需要使用一个表格来指定要使用的方法 POST。
在下面的示例中,我使用 <button>
而不是 <a>
元素,但它会起作用,您唯一需要做的就是使用 CSS 设置按钮样式看起来像您的链接
<form method="POST" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">This is a link that sends a POST request</button>
</form>
现在你的代码应该是这样的
<tr th:each="person : ${persons}">
<td th:text="${person.personId}"></td>
<td th:text="${person.name}"></td>
<td th:text="${person.address}"></td>
<td th:text="${person.telephone}"></td>
<td th:text="${person.email}"></td>
<td>
<form method="POST" th:action="@{/edit(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">EDIT</button>
</form> |
<form method="POST" th:action="@{/delete(personId=${person.personId})}">
<button type="submit" name="submit" value="value" class="link-button">DELETE</button>
</form>
</td>
</tr>
编辑
正如您刚刚分享的 Java 代码,在控制器中您希望 personId 不是 PathVariable,而是 RequestParam, 在这种情况下,您的表单应该具有该值...
编辑您的表单并添加人员 ID,如下所示。
<form method="POST" th:action="@{/edit}">
<input type="hidden" name="personid" id="personId" th:value="${person.personId}" />
<button type="submit" name="submit" value="value" class="link-button">This is a link that sends a POST request</button>
</form>
另请注意,我将表单的操作更改为 /edit,因为它是您的控制器的样子
Does anyone know if Thymeleaf allow a POST request per row of a table? Or do I have to write a simple HTML form per row?
HTML 不支持带链接的 POST 请求,您必须使用表单(如 Rayweb_on 所解释)。但是 Thymeleaf 允许您定义自定义标签,这很有帮助:
<a th:href="@{/edit(personId=${person.personId})}" custom:linkMethod="post">Edit</a>
... 将生成以下 HTML(假设 jQuery 可用):
<a href="#" onclick="$('<form action="/edit/personId=123456" method="post"></form>').appendTo('body').submit(); return false;">Edit</a>
自定义标签定义(没有错误检查以保持简单):
/**
* Custom attribute processor that allows to specify which method (get or post) is used on a standard link.
*/
public class LinkMethodAttrProcessor extends AbstractAttributeTagProcessor {
private static final String ATTR_NAME = "linkMethod";
private static final int PRECEDENCE = 10000;
public LinkMethodAttrProcessor(final String dialectPrefix) {
super(
TemplateMode.HTML, // This processor will apply only to HTML mode
dialectPrefix, // Prefix to be applied to name for matching
null, // No tag name: match any tag name
false, // No prefix to be applied to tag name
ATTR_NAME, // Name of the attribute that will be matched
true, // Apply dialect prefix to attribute name
PRECEDENCE, // Precedence (inside dialect's own precedence)
true); // Remove the matched attribute afterwards
}
@Override
protected void doProcess(final ITemplateContext context, final IProcessableElementTag tag,
final AttributeName attributeName, final String attributeValue,
final IElementTagStructureHandler structureHandler) {
// get the method name (tag parameter)
final IEngineConfiguration configuration = context.getConfiguration();
final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
final IStandardExpression expression = parser.parseExpression(context, attributeValue);
final String method = (String) expression.execute(context);
// add custom javascript to change link method
final String link = tag.getAttribute("href").getValue();
final String action = "$('<form action="" + link + "" method="" + method + ""></form>').appendTo('body').submit(); return false;";
structureHandler.setAttribute("onclick", action);
structureHandler.setAttribute("href", "#");
}
}
有关如何注册此自定义属性的示例,请参阅 the Thymelead documentation。