当前位置:网站首页>五、视图解析与模板引擎
五、视图解析与模板引擎
2022-07-30 04:33:00 【时间邮递员】
文章目录
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">
© 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>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 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页面会被自动解析
边栏推荐
- swagger使用教程——快速使用swagger
- Become a qualified cybersecurity, do you know this?
- Image stitching (registration) case based on OpenCV
- [Redis Master Cultivation Road] Jedis - the basic use of Jedis
- Code open source design and implementation ideas
- Install MySQL Database on Kylin V10 Operating System
- 【Untitled】
- SQLSERVER merges subquery data into one field
- 数据库概论 - MySQL的简单介绍
- JQ source code analysis (environment)
猜你喜欢
Thinkphp 5.0.24 Variable Override Vulnerability Causes RCE Analysis
golang八股文整理(持续搬运)
MYSQL 唯一约束
Shanxi group (enterprises) in the second network security skills competition part problem WP (7)
sqlmap use tutorial Daquan command Daquan (graphics)
精品MySQL面试题,备战八月99%必问!过不了面试算我的
cnpm installation steps
MYSQL unique constraint
图像视角矫正之透视变换矩阵(单应矩阵)/findHomography 与 getPerspectiveTransformd的区别
05 Detailed explanation of the global configuration file application.properties
随机推荐
A brief introduction to the SSM framework
2.6 Radix sort (bucket sort)
The difference between forward and redirect
2021山东省网络搭建与应用赛项试题
C. Travelling Salesman and Special Numbers (二进制 + 组合数)
Go 学习笔记(84)— Go 项目目录结构
The Azure developer news 丨 memorabilia in July
Install MySQL Database on Kylin V10 Operating System
The 2nd Shanxi Province Network Security Skills Competition (Enterprise Group) Partial WP (10)
state space representation
Excellent MySQL interview questions, 99% must ask in preparation for August!I can't pass the interview
Discourse Custom Header Links
MySQL String Concatenation - Various String Concatenation Practical Cases
Chapter8 Support Vector Machines
@WebServlet注解(Servlet注解)
共建共享数字世界的根:阿里云打造全面的云原生开源生态
MySQL data query (subtotal and sorting)
05 Detailed explanation of the global configuration file application.properties
Become a qualified cybersecurity, do you know this?
数据库概论 - MySQL的简单介绍