五、视图解析与模板引擎

本文详细介绍了Thymeleaf模板引擎的使用,包括基本语法、文本操作、数学和布尔运算、条件判断等。接着,展示了如何构建后台管理系统,涉及项目创建、静态资源处理、路径构建、页面跳转和数据遍历。同时,讲解了Spring MVC中的拦截器原理和配置,以及文件上传的实现和限制。最后,提到了错误处理的默认规则。
摘要由CSDN通过智能技术生成

1、模板引擎-Thymeleaf

1)thymeleaf简介

现代化、服务端Java模板引擎

2)基本语法

在这里插入图片描述

3)字面量

文本值: ‘one text’ , ‘Another one!’
数字: 0 , 34 , 3.0 , 12.3
布尔值: true , false
空值: null
变量: one,two,变量不能有空格

4)文本操作

字符串拼接: +

变量替换: |The name is ${name}|

5)数学运算

运算符: + , - , * , / , %

6)布尔运算

运算符: and , or

一元运算: ! , not

7)比较运算

比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )

8)条件运算

If-then: (if) ? (then)

If-then-else: (if) ? (then) : (else)

Default: (value) ?: (defaultvalue)

9)thymeleaf使用

引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

页面开发

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<h1 th:text="${msg}">哈哈</h1>
<h2>
    <a href="www.atguigu.com" th:href="${link}">去百度</a>  <br/>
</h2>
</body>
</html>

2、构建后台管理系统

1)项目创建

thymeleaf、web-starter、devtools、lombok

2)静态资源处理

自动配置好,我们只需要把所有静态资源放到 static 文件夹下

3)路径构建

th:action=“@{/login}”

4)模板抽取

th:insert/replace/include

So an HTML fragment like this:

<footer th:fragment="copy">
  &copy; 2011 The Good Thymes Virtual Grocery
</footer>
…included three times in host <div> tags, like this:

<body>
  <div th:insert="footer :: copy"></div>
  <div th:replace="footer :: copy"></div>
  <div th:include="footer :: copy"></div>
</body>
…will result in:

<body>
  <div>
    <footer>
      &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
  </div>

  <footer>
    &copy; 2011 The Good Thymes Virtual Grocery
  </footer>

  <div>
    &copy; 2011 The Good Thymes Virtual Grocery
  </div>
  
</body>

5)页面跳转

    @PostMapping("/login")
    public String main(User user, HttpSession session, Model model){
 
        if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
            //把登录成功的用户保存起来
            session.setAttribute("loginUser",user);
            //登录成功重定向到main.html;  重定向防止表单重复提交
            return "redirect:/main";
        }else {
            model.addAttribute("msg","账号密码错误");
            //回到登录页面
            return "login";
        }
 
    }

6)遍历数据

        <table class="display table table-bordered" id="hidden-table-info">
        <thead>
        <tr>
            <th>#</th>
            <th>用户名</th>
            <th>密码</th>
        </tr>
        </thead>
        <tbody>
        <tr class="gradeX" th:each="user,stats:${users}">
            <td th:text="${stats.count}">Trident</td>
            <td th:text="${user.userName}">Internet</td>
            <td >[[${user.password}]]</td>
        </tr>
        </tbody>
        </table>

3、拦截器

1)HandlerInterceptor 接口

/**
 * 登录检查
 * 1、配置好拦截器要拦截哪些请求
 * 2、把这些配置放在容器中
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
 
    /**
     * 控制器方法执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
        String requestURI = request.getRequestURI();
        log.info("preHandle拦截的请求路径是{}",requestURI);
 
        //登录检查逻辑
        HttpSession session = request.getSession();
 
        Object loginUser = session.getAttribute("loginUser");
 
        if(loginUser != null){
            //放行
            return true;
        }
 
        //拦截住,未登录,跳转到登录页
        request.setAttribute("msg","请先登录");
//        re.sendRedirect("/");
        request.getRequestDispatcher("/").forward(request,response);
        return false;
    }
 
    /**
     * 控制器方法执行完成以后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("postHandle执行{}",modelAndView);
    }
 
    /**
     * 页面渲染以后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("afterCompletion执行异常{}",ex);
    }
}

2)配置拦截器

/**
 * 1、编写一个拦截器实现HandlerInterceptor接口
 * 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
 * 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 */
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")  //所有请求都被拦截包括静态资源
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的请求
    }
}

3)拦截器原理

1、根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有拦截器】

2、先顺序执行所有拦截器的 preHandle方法

a>如果当前拦截器prehandler返回为true,则执行下一个拦截器的preHandle
b>如果当前拦截器返回为false,直接倒序执行所有已经执行了的拦截器的 afterCompletion

3、如果任何一个拦截器返回false,直接跳出不执行目标方法

4、所有拦截器都返回True,执行目标方法

5、倒序执行所有拦截器的postHandle方法

6、前面的步骤有任何异常都会直接倒序触发 afterCompletion

7、页面成功渲染完成以后,也会倒序触发 afterCompletion
在这里插入图片描述

4、文件上传

1)页面表单

<form method="post" th:action="@{/upload}" enctype="multipart/form-data">
   用户名: <input type="text" name="username"><br>
    头像:  <input type="file" name="headerImg"><br>
   生活照: <input type="file" name="photos" multiple><br>
           <input type="submit" value="提交">
</form>

2)文件上传代码

    /**
     * MultipartFile 自动封装上传过来的文件
     * @param username
     * @param headerImg
     * @param photos
     * @return
     */
    @PostMapping("/upload")
    public String upload(
                         @RequestParam("username") String username,
                         @RequestPart("headerImg") MultipartFile headerImg,
                         @RequestPart("photos") MultipartFile[] photos) throws IOException {
 
        log.info("上传的信息:username={},headerImg={},photos={}",
                username,headerImg.getSize(),photos.length);
 
        if(!headerImg.isEmpty()){
            //保存到文件服务器,OSS服务器
            String originalFilename = headerImg.getOriginalFilename();
            headerImg.transferTo(new File("D:\\Study\\"+originalFilename));
        }
 
        if(photos.length > 0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    photo.transferTo(new File("D:\\Study\\"+originalFilename));
                }
            }
        }
        return "main";
    }

3)文件上传大小设置

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-request-size=100MB

5、异常处理

错误处理
1、默认规则

默认情况下,Spring Boot提供/error处理所有错误的映射
对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据

2、error/下的4xx,5xx页面会被自动解析

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间邮递员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值