maven
该项目为maven项目,在我的一台电脑上配置好的项目copy到另一台电脑上,maven貌似需要重新下载maven依赖,maven项目必须联网吗?
参考1:Maven installation and using in project without Internet conncetion,该文表示如果在offline状态下用本地的库使用maven,就背离了maven的原则,maven在原则下就是需要联网的,这样才能精确和更好地控制版本。
参考2:How do I configure Maven for offline development?
参考3:maven联网问题,如果真的需要使用本地仓库就这样做。
Thymeleaf
在学习新技术之前,首先需要明白的问题是:
1.它解决了什么问题?
2.它跟与它类似的技术有什么优劣?
学习的一个重大途径是看FAQ!从经常问的问题中寻找答案!
参考thymeleaf FAQ,一些精华:
1.Is Thymeleaf a web framework?:
No, it isn’t. It is a template engine.
Template engines play a key role in web frameworks, though, and are one of its most important components as they are in charge of producing the user interface or view layer (usually in XHTML or HTML form).
Spring MVC, Struts or Apache Wicket are examples of web frameworks, whereas JSP, Velocity or FreeMarker are examples of template engines.
2.What types of templates can Thymeleaf process?:
Thymeleaf templates can be:
1.HTML (HTML5, XHTML 1.0/1.1, HTML 4)
2.XML
3.TEXT (plain text)
4.JAVASCRIPT (.js files)
5.CSS (.css files)
3.I don’t use Spring at all. Can I still use Thymeleaf?:
Absolutely. Thymeleaf offers nice integration with Spring MVC through its SpringStandard dialect (included in the thymeleaf-spring3, thymeleaf-spring4 and thymeleaf-spring5 packages), but Spring integration is completely optional and the Standard dialect is in fact meant to be used without Spring.
4.How does Thymeleaf compare with other template engines like Velocity or FreeMarker?:
Both Velocity and FreeMarker are terrific pieces of software, but they approach the templating problem with a philosophy quite different to that of Thymeleaf.
Thymeleaf makes a strong stress on natural templating —allowing templates to be working prototypes, which the other two do not allow—, and its syntax tries to be (arguably) cleaner and more in tune with the current trends in web development. Also, from an architectural standpoint, both Velocity and FreeMarker work as sequential text processors whereas Thymeleaf is based on markup parsing techniques. This allows Thymeleaf to take advantage of interesting features specific to markup-based environments, especially the web.
Anyway, the best way to compare these technologies is to use them yourself and feel which one suits you best.
带着上述问题,我们来看thymeleaf:
首先,它解决什么问题?从FAQ中可以很清楚地看出来,它是一款后端的模板引擎,那么它的大部分功能应该是实现动态填值的功能!
之前的jsp也能实现相应的功能,那么它与jsp比较有哪些优劣呢?
参考:Spring MVC view layer: Thymeleaf vs. JSP:
thymeleaf的标签都是以th开头的,如th:href
。
比较重点可以看看4.Let’s change the page style!
这一节:
1.对于jsp:需要先将jsp部署到服务器上然后启动,没有服务器,jsp是不能正常工作的。打开浏览器的dev tools,然后一个一个颜色试,将最终颜色写入css,完成。
2.对于thymeleaf:直接浏览器打开该html文件,打开浏览器的dev tools,然后一个一个颜色试,然后存入css,完成。
上述是跟jsp的优势。
接下来我们来了解下thymeleaf的基础:
一、Thymeleaf is very, very extensible, and it allows you to define your own sets of template attributes (or even tags) with the names you want, evaluating the expressions you want in the syntax you want and applying the logic you want. It’s more like a template engine framework.
二、五种Standard Expressions:
1.${…} : Variable expressions.
2.*{…} : Selection expressions.
3.#{…} : Message (i18n) expressions.
4.@{…} : Link (URL) expressions.
5.~{…} : Fragment expressions.
Variable expressions
Variable expressions are executed on the context variables — also called model attributes in Spring jargon.
And you will find them as attribute values or as a part of them, depending on the attribute:
<span th:text="${book.author.name}">
The expression above is equivalent (both in OGNL and SpringEL) to:
((Book)context.getVariable("book")).getAuthor().getName()
当然还有可能有一些高级的用法,比如:
<li th:each="book : ${books}">
Here ${books} selects the variable called books from the context, and evaluates it as an iterable to be used at a th:each loop.
Selection expressions
Selection expressions跟variable expressions很相似,不同点是,Selection expressions作用在a previously selected object,而不是the whole context variables map(variable expressions应该是作用在其上的)。
The object they act on is specified by a th:object
attribute,用法:
<div th:object="${book}">
...
<span th:text="*{title}">...</span>
...
</div>
上述写法相当于:
{
// th:object="${book}"
final Book selection = (Book) context.getVariable("book");
// th:text="*{title}"
output(selection.getTitle());
}
Message (i18n) expressions
Message expressions主要是用来国际化的。
it allows us to retrieve locale-specific messages from external sources (.properties files), referencing them by a key and (optionally) applying a set of parameters.
Link (URL) expressions
Link expressions are meant to build URLs and add useful context and session info to them (a process usually called URL rewriting).
举例来说:
1.So for a web application deployed at the /myapp context of your web server, an expression such as:
<a th:href="@{/order/list}">...</a>
也就是:
<a href="/myapp/order/list">...</a>
2.URL也可以带上参数:
<a th:href="@{/order/details(id=${orderId},type=${orderType})}">...</a>
也就是:
<!-- Note ampersands (&) should be HTML-escaped in tag attributes... -->
<a href="/myapp/order/details?id=23&type=online">...</a>
3.当然,链接也可以是绝对的:
<a th:href="@{http://www.mycompany.com/main}">...</a>
Fragment expressions
Fragment expressions are an easy way to represent fragments of markup and move them around templates. Thanks to these expressions, fragments can be replicated, passed to other templates are arguments, and so on.
The most common use is for fragment insertion using th:insert or th:replace,比如:
1.
<div th:insert="~{commons :: main}">...</div>
2.
<div th:with="frag=~{footer :: #main/text()}">
<p th:insert="${frag}">
</div>
Literals and operations
三、Some basic attributes
th:text
的作用是just replaces the body of a tag:
<p th:text="#{msg.welcome}">Welcome everyone!</p>
th:each
的用法是做循环嘛:
<li th:each="book : ${books}" th:text="${book.title}">En las Orillas del Sar</li>
在thymeleaf中进行引用时,比如上面的books,我们怎样往里面赋值,然后html界面才能够引用呢?我们可以这样写:
@ModelAttribute("allTypes")
public List<Type> populateTypes() {
return Arrays.asList(Type.ALL);
}
@ModelAttribute("allFeatures")
public List<Feature> populateFeatures() {
return Arrays.asList(Feature.ALL);
}
@ModelAttribute("allVarieties")
public List<Variety> populateVarieties() {
return this.varietyService.findAll();
}
@ModelAttribute("allSeedStarters")
public List<SeedStarter> populateSeedStarters() {
return this.seedStarterService.findAll();
}
这样我们就可以在界面中引用了,当然也可以使用model.add方法
:
<tr th:each="sb : ${allSeedStarters}">
更多请参考:Tutorial: Thymeleaf + Spring
关于程序与view的数据交互
参考:Spring MVC and Thymeleaf: how to access data from templates
In a typical Spring MVC application, @Controller classes are responsible for preparing a model map with data and selecting a view to be rendered. This model map allows for the complete abstraction of the view technology and, in the case of Thymeleaf, it is transformed into a Thymeleaf context object (part of the Thymeleaf template execution context) that makes all the defined variables available to expressions executed in templates.
在SpringMVC项目中,通常情况下,@Controller类负责将data传入给model,然后由model将数带入view中。
1.Spring model attributes
Spring MVC calls the pieces of data that can be accessed during the execution of views model attributes . 注意,是在views运行期间能够获取的数据! 也即model数据是跟views相关的。
The equivalent term in Thymeleaf language is context variables.相似术语。
有三种方式向model中加入内容:
1.Add attribute to Model via its addAttribute method:
@RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("messages", messageRepository.findAll());
return "message/list";
}
2.Return ModelAndView with model attributes included:
@RequestMapping(value = "message", method = RequestMethod.GET)
public ModelAndView messages() {
ModelAndView mav = new ModelAndView("message/list");
mav.addObject("messages", messageRepository.findAll());
return mav;
}
3.Expose common attributes via methods annotated with @ModelAttribute:
@ModelAttribute("messages")
public List<Message> messages() {
return messageRepository.findAll();
}
In Thymeleaf, these model attributes (or context variables in Thymeleaf jargon) can be accessed with the following syntax: ${attributeName}, where attributeName in our case is messages,比如:
<tr th:each="message : ${messages}">
<td th:text="${message.id}">1</td>
<td><a href="#" th:text="${message.title}">Title ...</a></td>
<td th:text="${message.text}">Text ...</td>
</tr>
2.Request parameters
比如一个网址:https://example.com/query?q=Thymeleaf+Is+Great!
可以通过param来获取q:
<p th:text="${param.q}">Test</p>
如果q有多值,比如:
https://example.com/query?q=Thymeleaf%20Is%20Great!&q=Really%3F
可以采用数组这样得到:
<p th:text="${param.q[0] + ' ' + param.q[1]}" th:unless="${param.q == null}">Test</p>
3.Session attributes
In the below example we add mySessionAttribute to session:
@RequestMapping({
"/"})
String index(HttpSession session) {
session.setAttribute("mySessionAttribute", "someValue");
return "index";
}
获取方法:
//方法1
<p th:text="${session.mySessionAttribute}" th:unless="${session == null}">[...]</p>
//方法2
${
#session.getAttribute('mySessionAttribute')}
4.ServletContext attributes
The ServletContext attributes are shared between requests and sessions. In order to access ServletContext attributes in Thymeleaf you can use the #servletContext. prefix:
<table>
<tr>
<td>My context attribute</td>
<!-- Retrieves the ServletContext attribute 'myContextAttribute' -->
<td th:text="${#servletContext.getAttribute('myContextAttribute')}">42</td>
</tr>
<tr th:each="attr : ${#servletContext.getAttributeNames()}">
<td th:text="${attr}">javax.servlet.context.tempdir</td>
<td th:text="${#servletContext.getAttribute(attr)}"<