这里简述下thymeleaf发送post请求的两种方式。
场景分析
我们知道,html不支持通过链接发送post请求,默认只能通过表单方式发送。不过这里我们使用的是thymeleaf
,它还提供了一种通过方言(Dialect)、自定义tag处理器(AbstractProcessorDialect)
的方式,我们可以通过就可以实现以链接的方式来发送post请求。下面我们来看具体实现:
我们先定义目标页面和对应的Controller:
post-request.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<script th:src="@{/webjars/jquery/3.1.1/jquery.min.js}"></script>
<script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script>
<title>这是普通的post请求</title>
</head>
<body>
<div>
<p>Post请求响应:</p>
<p th:text="${response}"></p>
<p th:text="${post111}"></p>
</div>
<script>
</script>
</body>
</html>
post-request.html对应的Controller:
@Controller
public class WebController {
/**
* 普通的post请求
* 本地访问内容地址 :http://localhost:8201/request-methods
*
* @param map
* @return
*/
@PostMapping("/post-request")
public String postRequest(Model model, HashMap<String, Object> map, @RequestParam(value = "name", required = false, defaultValue = "猫了个咪") String name) {
model.addAttribute("response", name);
model.addAttribute("post111", "我是post方法");
return "post-request";
}
}
form表单方式发送post请求
在html中使用表单即可:
<div>
<h3>post请求</h3>
1、使用表单发送post请求:html不支持通过链接发送post请求,只能通过表单方式发送。
<form method="POST" th:action="@{/post-request}">
<input type="text" name="name" id="nameId"/>
<button type="submit" name="submit" value="value" class="button">发起普通post请求</button>
</form>
</div>
通过方言(Dialect)、自定义tag处理器(AbstractProcessorDialect)
的方法来发送post请求
我们先自定义tag处理器:
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", "#");
}
}
然后将它添加进方言(Dialect)
:
public class CustomDialect extends AbstractProcessorDialect {
//定义方言名称
private static final String DIALECT_NAME = "Custom Dialect";
public CustomDialect() {
//设置自定义方言与"方言处理器"优先级相同
super(DIALECT_NAME, "custom", StandardDialect.PROCESSOR_PRECEDENCE);
}
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
Set<IProcessor> processors = new HashSet<IProcessor>();
processors.add(new LinkMethodAttrProcessor(dialectPrefix));
processors.add(new StandardXmlNsTagProcessor(TemplateMode.HTML, dialectPrefix));
return processors;
}
}
接着在html标签中使用:
<div>
2、使用thymeleaf提供的方言,自定义标签处理来实现。
<p>
<!-- custom 跟 CustomDialect 中定义的 prefix 名称对应 -->
<a th:href="@{/post-request}" custom:linkMethod="post">发起普通post请求</a>
</p>
</div>
大功告成。
项目地址
tinytongtong / spring-thymeleaf
参考:
Can I make HTTP POST request from Thymeleaf table in Spring Boot application