📑打牌 : da pai ge的个人主页
🌤️个人专栏 : da pai ge的博客专栏
☁️宝剑锋从磨砺出,梅花香自苦寒来
🌤️动态页面的渲染方式
动态页面需要通过服务器根据客户端传来的参数 , 动态计算得到一些结果 , 并且把这些结果显示到页面上 .
所谓的 " 渲染 " (render) 就是把数据和页面结合起来 .
🌤️服务器渲染
数据和页面结合的工作 , 通过服务器完成 .
🌤️客户端渲染
服务器把数据返回给浏览器 , 由浏览器把数据和页面结合起来 .
浏览器和服务器之间的数据往往交互通过 ajax 进行 , 数据的格式往往使用 JSON.
之前咱们写的 带服务器的表白墙 , 就是通过客户端渲染实现的 .
🌤️字符串拼接 HTML
之前我们的代码中直接通过 resp.getWritter().write() 的方式 , 直接在参数中拼接一个 HTML 格式
的字符串 .
如果是返回一个简单的页面 , 可以按照上述方式拼接字符串完成 .
但是如果是一个复杂的页面呢 ? 我们通过一个简单的程序先初步感受一下 .
🌤️代码示例: 服务器版猜数字
之前我们实现的猜数字游戏 , 是一个纯粹的网页版本的程序 . 现在我们实现一个服务器版本的程序 .
创建 GuessNumServlet 类
其中的成员 toGuess 表示要猜的数字 , count 表示已经猜了的次数 .
doGet 方法用于处理游戏的初始化 . doPost 用于实现每一次 " 猜 " 的过程 .
服务器直接通过字符串拼接的方式构造 HTML, 返回给浏览器 .
@WebServlet("/html")
public class HtmlServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {String name = (String) req.getParameter("name");resp.setContentType("text/html; charset=utf-8");resp.getWriter().write(String.format("<h3>name: %s</h3>", name));}
}
@WebServlet("/guessNum")
public class GuessNumServlet extends HttpServlet {// 要猜的数字private int toGuess = 0;// 已经猜了几次private int count = 0;private Random random = new Random();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {resp.setContentType("text/html; charset=utf-8");// get 方法返回一个初始页面, 并且在服务器中存一个随机数// 1. 构造随机数, 并清空 counttoGuess = random.nextInt(100) + 1;System.out.println("toGuess = " + toGuess);count = 0;// 2. 返回页面内容String html = "<form action=\"guessNum\" method=\"GET\">\n" +" <input type=\"submit\" value=\"重新开始游戏\">\n" +"</form>\n" +"\n" +"<form action=\"guessNum\" method=\"POST\">\n" +" <input type=\"text\" name=\"num\">\n" +" <input type=\"submit\" value=\"猜\">\n" +"</form>";resp.getWriter().write(html);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {// post 方法处理猜数字的动作.resp.setContentType("text/html; charset=utf-8");// 1. 读取请求中用户猜的数字int num = Integer.parseInt(req.getParameter("num"));// 2. 比较大小String result = "";if (num < toGuess) {result = "猜低了";} else if (num > toGuess) {result = "猜高了";} else {result = "猜对了";}count++;// 3. 构造返回的页面内容String html = String.format("<form action=\"guessNum\"
method=\"GET\">\n" +" <input type=\"submit\" value=\"重新开始游戏\">\n" +"</form>\n" +"\n" +"<form action=\"guessNum\" method=\"POST\">\n" +" <input type=\"text\" name=\"num\">\n" +" <input type=\"submit\" value=\"猜\">\n" +"</form>\n" +"\n" +"<div>已经猜了: %d 次</div>\n" +"<div>结果: %s </div>", count, result);resp.getWriter().write(html);}
}
在 字符串 中直接编写 HTML , 这个是非常麻烦的 ( 尤其是有很多转义字符 ). 可以在其他编辑器直接把
HTML 写好 , 然后复制粘贴进去 .
IDEA 会自动加入转义字符 .
部署程序 , 通过浏览器访问 http://127.0.0.1:8080/ServletHelloWorld/guessNum
🌤️小结:
在这个代码中我们可以看到 , 当前页面其实并不复杂 , 但是直接拼装字符串的方式却让代码非常臃肿 .
尤其是 HTML 和 Java 代码混在一起 , 非常不利于开发维护 .
🌤️使用模板引擎
🌤️什么是模板引擎
<form action="guessNum" method="GET"><input type="submit" value="重新开始游戏">
</form>
<form action="guessNum" method="POST"><input type="text" name="num"><input type="submit" value="猜">
</form>
<div>已经猜了: 次</div>
<div>结果: </div>
模板引擎就是为了解决上面遇到的 , HTML 和 Java 混在一起的问题 .
我们可以把 HTML 的内容提取出来 , 放到单独的文件中 , 称为 模板 .
对于一些 " 动态 " 的部分 , 比如猜数字的结果 , 猜数字的次数 , 这些可以内容在 模板 中使用 占位符 ( 一些特
殊的符号 ) 占位 , 当服务器把这些 " 动态 " 的部分计算好了之后 , 就可以把 模板 中的 占位符 替换成动态计
算的结果 , 然后把这个组装好的 HTML 格式的字符串再返回给浏览器 .
模板就类似于考试中的 " 填空题 " 一样 . 试卷上把一句话的一些核心信息挖掉 . 然后由考生填写其中
缺少的部分 . 不同的考生 , 就可能填出完全不同的内容 .
这些表情包其实都是通过 " 一个模板 " 来生成出来的 .
Java 中的模板引擎有很多 . JSP, FreeMarker, Velocity, XMLTemplate 等 . 使用风格大同小异 .
荐的模板引擎 .
官网 : https://www.thymeleaf.org/
官方文档 : https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
快速入门 : https://www.thymeleaf.org/doc/articles/thymeleaf3migration.html