Day57.表述层(MVC)、Thymeleaf: 逻辑视图、对象图

Day57.表述层(MVC)、Thymeleaf: 逻辑视图、对象图,第1张

目录

一、MVC概念

二、Thymeleaf

1. HelloThymeleaf、逻辑视图

2. th表达式基本语法   th:?="? {?}" 

3. 在Thymeleaf中 *** 作域对象

域对象在Thymeleaf中的使用

4. 设置首页(index.html)的thymeleaf的渲染

5. 获取请求参数  ${param.参数名}

6. 内置对象   th:?="${#?.?}"

7. 对象图导航语言(OGNL)   th:text="${list[1].obj.name}"

8. 分支 (th:if、th:switch | th:case)

9. 迭代    th:each="e : ${ list }"

10. 代码片段     th:fragment  th:insert


一、MVC概念

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写

  • Model(模型)表示应用程序核心(用来存储数据供视图层渲染)。
  • View(视图)显示数据,而本篇使用的就是Thymeleaf作为视图。
  • Controller(控制器)处理输入请求,将模型和视图分离。

务必理解:三层架构。Thymeleaf 在表述层内,对视图层进行封装。目的是为了让各个组件可以单独维护,解耦合,动态的向网页传递数据。 

二、Thymeleaf

Thymeleaf 3 ten-minute migration guide - Thymeleaf

作用:它的主要作用是在静态页面上渲染显示动态数据,简化视图层(MVC) *** 作。

1. HelloThymeleaf、逻辑视图

逻辑视图:

视图前缀 + 逻辑视图 + 视图后缀 ==> 物理视图

1、导入Jar包,建立依赖关系

2、创建视图基础类 (笔记复制即可)

重点关注前缀后缀设置,后期会使用框架替代该类。


//视图基础类 继承了HttpServlet, 本质还是一个Servlet
public class ViewBaseServlet extends HttpServlet {

    private TemplateEngine templateEngine;

    @Override//在初始化中 读取全局上下文参数
    public void init() throws ServletException {

        // 1.获取ServletContext对象
        ServletContext servletContext = this.getServletContext();

        // 2.创建Thymeleaf解析器对象
        ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);

        // 3.给解析器对象设置参数
        // ①HTML是默认模式,明确设置是为了代码更容易理解
        templateResolver.setTemplateMode(TemplateMode.HTML);

        // ②设置前缀 (重要)
        String viewPrefix = servletContext.getInitParameter("view-prefix");

        templateResolver.setPrefix(viewPrefix);

        // ③设置后缀 (重要)
        String viewSuffix = servletContext.getInitParameter("view-suffix");

        templateResolver.setSuffix(viewSuffix);

        // ④设置缓存过期时间(毫秒)
        templateResolver.setCacheTTLMs(60000L);

        // ⑤设置是否缓存
        templateResolver.setCacheable(true);

        // ⑥设置服务器端编码方式
        templateResolver.setCharacterEncoding("utf-8");

        // 4.创建模板引擎对象
        templateEngine = new TemplateEngine();

        // 5.给模板引擎对象设置模板解析器
        templateEngine.setTemplateResolver(templateResolver);

    }

    /**
     * 进行视图解析(渲染)的方法
     * @param templateName 逻辑视图
     * @param req 请求
     * @param resp 响应
     * @throws IOException
     */
    protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 1.设置响应体内容类型和字符集
        resp.setContentType("text/html;charset=UTF-8");

        // 2.创建WebContext对象
        WebContext webContext = new WebContext(req, resp, getServletContext());

        // 3.处理模板数据
        templateEngine.process(templateName, webContext, resp.getWriter());
    }
}

3、web.xml中通过全局初始化参数 ,配置视图前缀后缀

    
        
        view-prefix 
        /pages/
    
         
        view-suffix
        .html
    

4、创建HelloServlet 继承视图基础类,调用processTemplate()方法跳转访问的页面

processTemplate("逻辑视图",请求对象,响应对象);
底层为请求转发 (连接不会发生改变,可以访问WEB-INF) getRequestDispatcher("路径").forward()

public class Thy01HelloServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("------ Thy01HelloServlet ------");
        //1.解决乱码
        request.setCharacterEncoding("utf-8");
        //调用业务层方法...
        
        //请求域传递参数,修改msg所渲染的值
        request.setAttribute("msg","一行白鹭上青天"); 

        //2.processTemplate("逻辑视图",请求对象,响应对象),底层是请求转发
        processTemplate("hello",request,response);
    }

5、在对应的页面中 html 标签内引入命名空间,使用 thymeaf 将动态数据渲染到静态页面上。

hello.html




    
    hello


Hello


等待渲染  
index首页

HelloThymeleaf 

 

 注:1.如果此处500报错,前缀 后缀没有问题,就是逻辑视图问题,请检查web.xml配置文件与视             图基础类对象中的参数名是否匹配,前后缀与processTemplate()传入的参数是否正确。
        2.如果出现其他未知问题,可能是Toncat、Jar包、jdk版本兼容性问题。

2. th表达式基本语法   th:?="? {?}" 

1、th名称空间:

  • 不经过服务器解析,直接用浏览器打开HTML文件,看到的是『标签体原始值』
  • 经过服务器解析, Thymeleaf引擎根据th:text属性指定的 标签体新值 去替换 标签体原始值

2、修改标签文本值:th:text="${key}"  

等待渲染

3、修改标签属性值:th:属性名="${key}" 

4、解析url

   4.1. 动态获取应用名:@{/}:

应用名(上下文路径)

   4.2. 附加参数发起请求:th:href= "${/资源名(参数名=参数值,.....)}"

   4.3. 携带动态数据作为参数发起请求: th:href="${/资源名(参数名=${key},.....)}"

3. 在Thymeleaf中 *** 作域对象

在Servlet中将数据存储到域对象中,在Thymeleaf 前端页面中取出域对象中的数据并展示

processTemplate 底层是请求转发。(连接不会发生改变,可以访问WEB-INF)

Servlet  (继承了视图基础类)
//请求域传递参数,修改msg所渲染的值
request.setAttribute("msg","一行白鹭上青天"); 

//processTemplate("逻辑视图",请求对象,响应对象),底层是请求转发
processTemplate("hello",request,response);
hello.html

等待渲染  

域对象在Thymeleaf中的使用

域对象是在服务器中有一定作用域范围的对象,在这个范围内的所有动态资源都能够共享域对象中保存的数据

① 请求域

在请求转发的场景下,我们可以借助HttpServletRequest对象内部给我们提供的存储空间,帮助我们携带数据,把数据发送给转发的目标资源 (request.setAttribute("msg","一行白鹭上青天"))。

② 会话域(后面学)
会话域的范围是一次会话

 

 ③ 应用域(后面学)
可用于统计在线人数

4. 设置首页(index.html)的thymeleaf的渲染

访问首页时,需要展示项目数据,而数据一般是存在于数据库的。因此在访问前要先执行Servlet 获取数据,再将数据渲染到首页上


    IndexServlet
    com.atguigu.servlet.IndexServlet


    IndexServlet
    服务器启动会自动加载 当前项目下index.html 然后直接访问 IndexServlet
    /index.html

5. 获取请求参数  ${param.参数名}

根据参数名 获取对应参数值 (ker -> value)

getParameter.thml


获取请求参数1

获取请求参数2

获取请求参数3

获取请求参数4

url: http://localhost:8080/day09Thymeleaf/thy05?uname=zs&pwd=123&hobby=swim&hobby=read&hobby=run
index.html

访问Thy05 
public class Thy05ParameterServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("------ Thy05 ------");


        //注意此处,hello02为逻辑视图,  视图前缀 + 逻辑视图 + 视图后缀 ==> 物理视图
        // 转发到getParameter.thml
        processTemplate("getParameter", request, response);
    }
6. 内置对象   th:?="${#?.?}"

内置对象:在Thymeleaf的表达式中可以直接使用的对象

基本内置对象:


内置对象1:

内置对象2:

内置对象3:

内置对象3:

内置对象4:

内置对象3:

公共内置对象:

request:
lists:     
strings:

公共的内置对象list1

公共的内置对象list2

公共的内置对象list2

公共的内置对象string

7. 对象图导航语言(OGNL)   th:text="${list[1].obj.name}"

OGNL:Object-Graph Navigation Language对象-图 导航语言

从根对象触发,通过特定的语法,逐层访问对象的各种属性。  快速访问对象属性值。

底层调用了对象的 get()方法 

${对象名.属性名}
${listkey[下标].属性名}
${map.key.属性名}
${map[map集合的key].属性名}


    简单对象
    

获取对象的属性值:

获取对象的属性值:

获取对象的属性值:


复杂对象

复杂对象

复杂对象

复杂对象

复杂对象


集合对象

集合对象

集合对象

集合对象

集合对象

集合对象

集合对象??


Map

Map

Map

Map

Map

Map

public class Thy06ObjectServlet extends ViewBaseServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("------ Thy06Object ------");
        //1.解决乱码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //创建Person 对象
        Person p1 = new Person("李白", 20, "男");
        request.setAttribute("p", p1);

        //复杂对象
        Computer c1 = new Computer("联想", 6666.6, "黑色");
        Person p2 = new Person("安琪拉", 20, "女", c1);

        request.setAttribute("p2", p2);

        //复杂对象2 List
        ArrayList list = new ArrayList<>();
        Computer c3 = new Computer("华硕", 9999.9, "金色");
        Person p3 = new Person("伊娃", 200, "女", c3);
        list.add(p2);
        list.add(p3);

        request.setAttribute("list", list);

        //复杂对象3 Map
        Map map = new HashMap<>();

        Computer c4 = new Computer("华硕", 9999.9, "金色");
        Person p4 = new Person("妲己", 300, "女", c3);

        map.put("p1", p3);//"伊娃",
        map.put("p-2", p4);//"妲己",
        request.setAttribute("map", map);

        processTemplate("object",request,response);
    }
8. 分支 (th:if、th:switch | th:case)

 ① if 和 unless 、not

if配合not关键词和unless配合原表达式效果是一样的,看自己的喜好。




    无数据 th:if



    有数据 th:unless



    有数据 th:if="${not


th:if="${1==2}" 
th:if="${1!=2}"
th:if="${not 1==2}"
th:unless="${1==2}"

② switch


    联想666
    华硕666
    宏碁666

9. 迭代    th:each="e : ${ list }"

th:each="e :${list1}">                 e:集合中的元素
th:each="e,status :${list1}">      status:在进行遍历时的状态信息

list集合遍历
品牌 价格 颜色
迭代状态 status
品牌 价格 颜色 下标 第几个元素 总数量 当前元素 奇数 偶数 是不是第一个 是不是最后一个

10. 代码片段     th:fragment  th:insert

th:fragment="片段名"   th:insert="逻辑视图::片段名"

作用:抽取各个页面的公共部分,解耦合
例如:

① 创建页面的公共代码片段

使用th:fragment来给这个片段命名:


    

被抽取出来的头部内容

② 在需要的页面中进行包含

语法效果特点
th:insert把目标的代码片段整个插入到当前标签内部它会保留页面自身的标签
th:replace用目标的代码替换当前标签它不会保留页面自身的标签
th:include把目标的代码片段去除最外层标签,然后再插入到当前标签内部(只替换内容)它会去掉片段外层标记,同时保留页面自身标记

代码:

创建页面的公共代码片段

    

头部样式1

头部样式2

使用: th: *** 作="代码片段的逻辑视图::代码片段的名字"

使用公共代码片段

    

标题头

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/883491.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-14
下一篇 2022-05-14

发表评论

登录后才能评论

评论列表(0条)

保存