1、SpringBoot整合整合jsp、整合freemarker、整合Thymeleaf。
首先说明一下,这里使用的是Springboot2.2.6.RELEASE版本,由于Springboot迭代很快,所以要注意版本问题。
代码语言:javascript复制 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.2.6.RELEASE</version>
9 <relativePath/> <!-- lookup parent from repository -->
10 </parent>
11 <groupId>com.bie</groupId>
12 <artifactId>springboot-hello</artifactId>
13 <version>0.0.1-SNAPSHOT</version>
14 <name>springboot-hello</name>
15 <description>Demo project for Spring Boot</description>
16
17 <properties>
18 <java.version>1.8</java.version>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-web</artifactId>
25 </dependency>
26 <dependency>
27 <groupId>org.springframework.boot</groupId>
28 <artifactId>spring-boot-starter-test</artifactId>
29 <scope>test</scope>
30 <exclusions>
31 <exclusion>
32 <groupId>org.junit.vintage</groupId>
33 <artifactId>junit-vintage-engine</artifactId>
34 </exclusion>
35 </exclusions>
36 </dependency>
37 <!-- springboot默认不推荐使用jsp,所以在web启动器中未包含这两个依赖包 -->
38 <!-- jstl,使用jsp的时候导入jstl标签库的坐标依赖包 -->
39 <dependency>
40 <groupId>javax.servlet</groupId>
41 <artifactId>jstl</artifactId>
42 </dependency>
43 <!-- jasper,是tomcat当中对jsp处理的一个jsp引擎 -->
44 <dependency>
45 <groupId>org.apache.tomcat.embed</groupId>
46 <artifactId>tomcat-embed-jasper</artifactId>
47 <scope>provided</scope>
48 </dependency>
49 </dependencies>
50
51 <build>
52 <plugins>
53 <plugin>
54 <groupId>org.springframework.boot</groupId>
55 <artifactId>spring-boot-maven-plugin</artifactId>
56 </plugin>
57 </plugins>
58 </build>
59
60 </project>
2、SpringBoot整合jsp,SpringBoot的全局配置文件,application.properties,配置jsp的访问路径和后缀。
代码语言:javascript复制1 # 配置jsp的访问路径的前缀和后缀,springboot2.2.6.RELEASE版本使用的配置。
2 spring.mvc.view.prefix=/WEB-INF/jsp/
3 spring.mvc.view.suffix=.jsp
创建一个实体类User。
代码语言:javascript复制 1 package com.bie.springboothello.po;
2
3 public class User {
4
5 private int id;
6 private String name;
7 private int age;
8
9 public int getId() {
10 return id;
11 }
12
13 public void setId(int id) {
14 this.id = id;
15 }
16
17 public String getName() {
18 return name;
19 }
20
21 public void setName(String name) {
22 this.name = name;
23 }
24
25 public int getAge() {
26 return age;
27 }
28
29 public void setAge(int age) {
30 this.age = age;
31 }
32
33 public User(int id, String name, int age) {
34 this.id = id;
35 this.name = name;
36 this.age = age;
37 }
38 }
创建控制器类。
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import com.bie.springboothello.po.User;
4 import org.springframework.stereotype.Controller;
5 import org.springframework.ui.Model;
6 import org.springframework.web.bind.annotation.RequestMapping;
7
8 import java.util.ArrayList;
9 import java.util.List;
10
11 /**
12 * SpringBoot整合jsp
13 */
14 @Controller
15 public class UserController {
16
17 @RequestMapping(value = "/showUser")
18 public String showUser(Model model) {
19 List<User> list = new ArrayList<>();
20 list.add(new User(1, "张飒飒", 25));
21 list.add(new User(2, "李四四", 26));
22 list.add(new User(3, "王五五", 23));
23 list.add(new User(4, "赵六六", 24));
24
25 // 需要一个Model对象
26 model.addAttribute(list);
27 // 跳转视图,跳转都userList.jsp
28 return "userList";
29 }
30
31 }
创建jsp页面。jsp应该放到WEB-INF/jsp/,那么WEB-INF放到那里呢,WEB-INF默认需要放到ServletContext Path下面,此时将src/main下面创建webapp的目录,在webapp目录下面创建WEB-INF目录。
代码语言:javascript复制 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8" %>
3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5 <html>
6 <head>
7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
8 <title>用户信息</title>
9 </head>
10 <body>
11 <table border="1" align="center" width="50%">
12 <tr>
13 <th>用户编号</th>
14 <th>用户账号</th>
15 <th>用户年龄</th>
16 </tr>
17 <c:forEach items="${list }" var="user">
18 <tr border="1" align="center" width="50%">
19 <td>${user.id }</td>
20 <td>${user.name }</td>
21 <td>${user.age }</td>
22 </tr>
23 </c:forEach>
24 </table>
25 </body>
26 </html>
项目结构,如下所示:
访问http://127.0.0.1:8080/showUser,运行效果如下所示:
3、SpringBoot整合Freemarker。新增freemarker依赖启动器的坐标,注意freemarker也被封装成了一个启动器的。
代码语言:javascript复制1 <!-- freemarker启动器的坐标 -->
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-freemarker</artifactId>
5 </dependency>
SpringBoot整合Freemarker,SpringBoot的全局配置文件,application.properties,配置Freemarker的访问路径和后缀。
代码语言:javascript复制1 # 如果控制层Controller无法跳转到ftl界面,那么在application.properties配置文件里面配置后缀配置。
2 spring.freemarker.suffix=.ftl
注意:Springboot要求模板形式的视图层技术的文件,必须要放到 src/main/resources 目录下,必须要一个名称为templates的目录。注意Freemarker的后缀名称是.ftl后缀。
代码语言:javascript复制 1 <html>
2 <head><title>展示用户数据~Freemarker语法</title>
3 <meta charset="utf-9"></meta>
4 </head>
5 <body>
6 <table border="1" align="center" width="50%">
7 <tr>
8 <th>用户编号</th>
9 <th>用户账号</th>
10 <th>用户年龄</th>
11 </tr>
12 <#list list as user >
13 <tr border="1" align="center" width="50%">
14 <td>${user.id}</td>
15 <td>${user.name}</td>
16 <td>${user.age}</td>
17 </tr>
18 </#list>
19 </table>
20
21 </body>
22 </html>
创建控制器类。
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import com.bie.springboothello.po.User;
4 import org.springframework.stereotype.Controller;
5 import org.springframework.ui.Model;
6 import org.springframework.web.bind.annotation.RequestMapping;
7
8 import java.util.ArrayList;
9 import java.util.List;
10
11 /**
12 * SpringBoot整合jsp
13 */
14 @Controller
15 public class UserController {
16
17 @RequestMapping(value = "/showUser")
18 public String showUser(Model model) {
19 List<User> list = new ArrayList<>();
20 list.add(new User(1, "张飒飒", 25));
21 list.add(new User(2, "李四四", 26));
22 list.add(new User(3, "王五五", 23));
23 list.add(new User(4, "赵六六", 24));
24
25 // 需要一个Model对象
26 model.addAttribute("list", list);
27 // 跳转视图,跳转都userList.ftl
28 return "userList";
29 }
30
31 }
项目结构,如下所示:
访问http://127.0.0.1:8080/showUser,运行效果如下所示:
4、SpringBoot 整合Thymeleaf(重点掌握)。新增thymeleaf依赖启动器的坐标,注意thymeleaf也被封装成了一个启动器的。
代码语言:javascript复制1 <!-- springBoot 的启动器 -->
2 <dependency>
3 <groupId>org.springframework.boot</groupId>
4 <artifactId>spring-boot-starter-thymeleaf</artifactId>
5 </dependency>
注意:存放视图的目录,目录位置:src/main/resources/templates。templates表示该目录是安全的。意味着该目录下的内容是不允许外界直接访问的,可以通过Controller转化或者重定向进行访问。
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.ui.Model;
5 import org.springframework.web.bind.annotation.RequestMapping;
6
7 @Controller
8 public class ThymeleafController {
9
10 @RequestMapping(value = "/show")
11 public String showInfo(Model model) {
12 model.addAttribute("msg", "Thymeleaf的第一个案例!");
13 return "index";
14 }
15
16 }
Thymeleaf特点,Thymelaef是通过他特定语法对html的标记做渲染。
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- th:text向页面输出一个字符信息 -->
10 <span th:text="hello"></span>
11 <hr/>
12 <span th:text="${msg}"></span>
13
14 </body>
15 </html>
项目结构,如下所示:
运行效果,如下所示:
4.1、Thymeleaf 语法详解,变量输出与字符串操作。
1)、th:text,在页面中输出值。
2)、th:value,可以将一个值放入到input标签的value中。
3)、判断字符串是否为空,Thymeleaf内置对象,注意语法,第一点,调用内置对象一定要用#,第二点,大部分的内置对象都以s结尾,例如,strings、numbers、dates等等。
a、{#strings.isEmpty(key)},判断字符串是否为空,如果为空返回 true,否则返回 false。 b、{#strings.contains(msg,'T')},判断字符串是否包含指定的子串,如果包含返回 true,否则返回 false。 c、{#strings.startsWith(msg,'a')},判断当前字符串是否以子串开头,如果是返回 true,否则返回 false。 d、{#strings.endsWith(msg,'a')},判断当前字符串是否以子串结尾,如果是返回 true,否则返回 false。 e、{#strings.length(msg)},返回字符串的长度。 f、 {#strings.indexOf(msg,'h')},查找子串的位置,并返回该子串的下标,如果没找到则返回-1。 g、{#strings.substring(msg,13)},{#strings.substring(msg,13,15)},截取子串,用户与 jdk String 类下 SubString 方法相同。 h、{#strings.toUpperCase(msg)},{#strings.toLowerCase(msg)},字符串转大小写。
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- th:text向页面输出一个字符信息 -->
10 <span th:text="hello"></span>
11 <hr/>
12 <span th:text="${msg}"></span>
13 <hr/>
14 <!-- th:value可以将一个值放入到input标签的value中。-->
15 <input type="text" name="name" th:value="${msg}" style="width: 260px;"/>
16 <hr/>
17
18 <!-- ${#strings.isEmpty(key)},判断字符串是否为空,如果为空返回true,否则返回false。-->
19 <span th:text="${#strings.isEmpty(msg)}"></span>
20 <hr/>
21
22 <!-- ${#strings.contains(msg,'T')},判断字符串是否包含指定的子串,如果包含返回true,否则返回false。 -->
23 <span th:text="${#strings.contains(msg,'T')}"></span>
24 <hr/>
25
26 <!-- ${#strings.startsWith(msg,'a')},判断当前字符串是否以子串开头,如果是返回 true,否则返回 false。 -->
27 <span th:text="${#strings.startsWith(msg,'T')}"></span>
28 <hr/>
29
30 <!-- ${#strings.endsWith(msg,'!')},判断当前字符串是否以子串结尾,如果是返回 true,否则返回 false。 -->
31 <span th:text="${#strings.endsWith(msg,'!')}"></span>
32 <hr/>
33
34 <!-- ${#strings.length(msg)},返回字符串的长度。 -->
35 <span th:text="${#strings.length(msg)}"></span>
36 <hr/>
37
38 <!-- ${#strings.indexOf(msg,'h')},查找子串的位置,并返回该子串的下标,如果没找到则返回-1。 -->
39 <span th:text="${#strings.indexOf(msg,'h')}"></span>
40 <hr/>
41
42 <!-- ${#strings.substring(msg,13)},${#strings.substring(msg,13,15)},截取子串,用户与jdkString类下SubString方法相同。 -->
43 <span th:text="${#strings.substring(msg, 2)}"></span>
44 <hr/>
45
46 <!-- ${#strings.toUpperCase(msg)},${#strings.toLowerCase(msg)},字符串转大小写。 -->
47 <span th:text="${#strings.toUpperCase(msg)}"></span>
48 <span th:text="${#strings.toLowerCase(msg)}"></span>
49 <hr/>
50
51 </body>
52 </html>
运行效果,如下所示:
4.2、Thymeleaf 语法详解,日期格式化处理操作。
a、{#dates.format(key)},格式化日期,默认的以浏览器默认语言为格式化标准。 b、{#dates.format(key,'yyy/MM/dd')},按照自定义的格式做日期转换。 c、{#dates.year(key)},{#dates.month(key)},
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- ${#dates.format(key)},格式化日期,默认的以浏览器默认语言为格式化标准。 -->
10 <span th:text="${#dates.format(date)}"></span>
11 <hr/>
12
13 <!-- ${#dates.format(key,'yyy/MM/dd')},按照自定义的格式做日期转换。 -->
14 <span th:text="${#dates.format(date,'yyy/MM/dd')}"></span>
15 <hr/>
16
17 <!-- ${#dates.year(key)},${#dates.month(key)},${#dates.day(key)},注意,year代表取年、Month代表取月、Day代表取日。 -->
18 <span th:text="${#dates.year(date)}"></span>
19 <span th:text="${#dates.month(date)}"></span>
20 <span th:text="${#dates.day(date)}"></span>
21 <hr/>
22
23 </body>
24 </html>
运行效果,如下所示:
4.3、Thymeleaf 语法详解,条件判断。
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- th:if标签进行判断 -->
10 <span th:if="${sex == '男'}">
11 性别:男
12 </span>
13 <span th:if="${sex == '女'}">
14 性别:女
15 </span>
16 <hr/>
17
18 <!-- th:switch、th:case标签进行匹配判断 -->
19 <div th:switch="${id}">
20 <span th:case="1">id为1</span>
21 <span th:case="2">id为2</span>
22 <span th:case="3">id为2</span>
23 </div>
24
25
26 </body>
27 </html>
运行效果,如下所示:
4.4、Thymeleaf 语法详解,迭代遍历。
控制层代码,如下所示:
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import com.bie.springboothello.po.User;
4 import org.springframework.stereotype.Controller;
5 import org.springframework.ui.Model;
6 import org.springframework.web.bind.annotation.RequestMapping;
7
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.List;
11 import java.util.Map;
12
13 /**
14 * SpringBoot整合jsp
15 */
16 @Controller
17 public class UserController {
18
19 @RequestMapping(value = "/showUser")
20 public String showUser(Model model) {
21 List<User> list = new ArrayList<>();
22 list.add(new User(1, "张飒飒", 25));
23 list.add(new User(2, "李四四", 26));
24 list.add(new User(3, "王五五", 23));
25 list.add(new User(4, "赵六六", 24));
26
27 Map<String, Object> map = new HashMap<String, Object>();
28 map.put("user1", new User(1, "张飒飒", 25));
29 map.put("user2", new User(2, "李四四", 26));
30 map.put("user3", new User(3, "王五五", 23));
31 map.put("user4", new User(4, "赵六六", 24));
32
33 // 需要一个Model对象
34 model.addAttribute("list", list);
35 model.addAttribute("map", map);
36 // 跳转视图,跳转都userList.ftl
37 return "index";
38 }
39
40 }
页面代码,如下所示:
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- th:each遍历List集合 -->
10 <table border="1" align="center" width="50%">
11 <tr>
12 <th>用户编号</th>
13 <th>用户账号</th>
14 <th>用户密码</th>
15 </tr>
16 <tr th:each="user : ${list}" border="1" align="center" width="50%">
17 <td th:text="${user.id}"></td>
18 <td th:text="${user.name}"></td>
19 <td th:text="${user.age}"></td>
20 </tr>
21 </table>
22
23 <br/>
24 <hr/>
25 <br/>
26
27 <!--
28 状态变量属性var,名称任意。
29 1、index:当前迭代器的索引从0开始。
30 2、count:当前迭代对象的计数从1开始。
31 3、size:被迭代对象的长度。
32 4、even/odd:布尔值,当前循环是否是偶数/奇数从0开始。
33 5、first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false。
34 6、last:布尔值,当前循环的是否是最后一条,如果是则返回true否则返回false。
35 -->
36 <table border="1" align="center" width="100%">
37 <tr>
38 <th>用户编号</th>
39 <th>用户账号</th>
40 <th>用户密码</th>
41 <th>对象的索引</th>
42 <th>对象的计数</th>
43 <th>对象的长度</th>
44 <th>是否偶数</th>
45 <th>是否奇数</th>
46 <th>是否第一条</th>
47 <th>是否最后一条</th>
48 </tr>
49 <tr th:each="user,var : ${list}" border="1" align="center" width="100%">
50 <td th:text="${user.id}"></td>
51 <td th:text="${user.name}"></td>
52 <td th:text="${user.age}"></td>
53 <td th:text="${var.index}"></td>
54 <td th:text="${var.count}"></td>
55 <td th:text="${var.size}"></td>
56 <td th:text="${var.even}"></td>
57 <td th:text="${var.odd}"></td>
58 <td th:text="${var.first}"></td>
59 <td th:text="${var.last}"></td>
60 </tr>
61 </table>
62
63 <br/>
64 <hr/>
65 <br/>
66 <!-- th:each 迭代 Map -->
67 <table border="1" align="center" width="100%">
68 <tr>
69 <th>用户编号</th>
70 <th>用户账号</th>
71 <th>用户密码</th>
72 </tr>
73 <tr th:each="maps : ${map}" border="1" align="center" width="100%">
74 <td th:text="${maps}"></td>
75 </tr>
76 </table>
77
78 <br/>
79 <hr/>
80 <br/>
81
82 <table border="1" align="center" width="100%">
83 <tr>
84 <th>用户编号</th>
85 <th>用户账号</th>
86 <th>用户密码</th>
87 </tr>
88 <tr th:each="maps : ${map}" border="1" align="center" width="100%">
89 <td th:each="entry:${maps}" th:text="${entry.value.id}"></td>
90 <td th:each="entry:${maps}" th:text="${entry.value.name}"></td>
91 <td th:each="entry:${maps}" th:text="${entry.value.age}"></td>
92 </tr>
93 </table>
94
95 </body>
96 </html>
运行效果,如下所示:
4.5、Thymeleaf 语法详解,域对象操作,获取作用域对象中的数据。
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.ui.Model;
5 import org.springframework.web.bind.annotation.RequestMapping;
6
7 import javax.servlet.http.HttpServletRequest;
8
9 @Controller
10 public class ThymeleafController {
11
12 @RequestMapping(value = "/show")
13 public String showInfo(Model model, HttpServletRequest request) {
14 // HttpServletRequest
15 request.setAttribute("request", "HttpServletRequest");
16 // HttpSession
17 request.getSession().setAttribute("session", "HttpSession");
18 // ServletContext
19 request.getSession().getServletContext().setAttribute("application", "Application");
20
21 return "index";
22 }
23
24 }
页面代码,如下所示:
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 Request:<span th:text="${#httpServletRequest.getAttribute('request')}"></span><br/>
10
11 Session:<span th:text="${session.session}"></span><br/>
12
13 Application:<span th:text="${application.application}"></span><br/>
14
15 </body>
16 </html>
运行效果,如下所示:
4.6、Thymeleaf 语法详解,url表达式(th:href、th:src),url表达式语法,基本语法:@{}。
代码语言:javascript复制 1 package com.bie.springboothello.controller;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.web.bind.annotation.PathVariable;
5 import org.springframework.web.bind.annotation.RequestMapping;
6
7 @Controller
8 public class ThymeleafController {
9
10 @RequestMapping(value = "/{page}")
11 public String showInfo(@PathVariable String page, Integer id, String name) {
12 System.out.println("id: " id ", name:" name);
13 return page;
14 }
15
16 }
页面代码,如下所示:
代码语言:javascript复制 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html xmlns:th="http://www.w3.org/1999/xhtml">
4 <head>
5 <title>Thymeleaf 入门</title>
6 </head>
7 <body>
8
9 <!-- 1、URL类型,绝对路径 -->
10 <a th:href="@{http://www.baidu.com}">绝对路径</a><br/>
11
12 <!--
13 2、URL类型,相对路径。
14 第一种情况,相对于当前项目的根,相对于项目的上下文的相对路径。相当于去请求Controller的请求路径。去查找当前项目下可以处理show请求的url路径
15 第二种情况,相对于服务器路径的根,比如访问同一个tomcat下面的不同项目的访问路径。
16 -->
17 <a th:href="@{/show}">相对路径</a><br/>
18 <a th:href="@{~/springboot-hello/show}">相对于服务器的根</a><br/>
19 <!-- <a th:href="@{~/project2/resourcename}">相对于服务器的根</a> -->
20
21 <!-- 3、URL类型,在url 中实现参数传递 -->
22 <a th:href="@{/show(id=1,name=zhagnsan)}">相对路径-传参</a><br/>
23
24 <!-- 4、在url中通过restful风格进行参数传递 -->
25 <a th:href="@{/path/{id}/show(id=1,name=zhagnsan)}">相对路径-传参-restful</a><br/>
26
27 </body>
28 </html>
运行效果,如下所示: