目录
1、简单功能分析
1.1、静态资源访问
静态资源目录:
只要静态资源放在类路径下: resources /static
or /public
or /resources
or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名
1.2、欢迎页支持
静态资源路径下 index.html
1.3、自定义 Favicon——网站访问项目时的小图标
静态资源路径下favicon.ico
2、数据响应与内容协商
2.1、响应JSON
json,是一种数据格式,前后端交互时,我们经常需要进行数据传输,给数据一个统一的格式有利于我们编写和解析数据
我们通过导入starter-web依赖,给前端自动返回json数据
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.2、内容协商
根据客户端接收能力不同,返回不同媒体类型的数据
引入xml依赖(响应XML)
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
在controller文件下建立ResponseTestController类,添加以下代码
@Controller
public class ResponseTestController {
@ResponseBody
@GetMapping(value = "/test/person")
public Person getPerson(){
Person person = new Person();
person.setAge(28);
person.setBirth(new Date());
person.setUserName("zhangsan");
return person;
}
}
为了方便内容协商,在application.yaml文件中开启基于请求参数的内容协商功能
spring:
mvc:
contentnegotiation:
favor-parameter: true #开启请求参数内容协商模式
浏览器发请求:
3、模板引擎-Thymeleaf
3.1、基本语法
表达式
表达式名字 | 语法 | 用途 |
变量取值 | ${...} | 获取请求域、session域、对象等值 |
选择变量 | *{...} | 获取上下文对象值 |
消息 | #{...} | 获取国际化等值 |
链接 | @{...} | 生成链接 |
片段表达式 | ~{...} | jsp:include 作用,引入公共页面片段 |
3.2、thymeleaf使用
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
因为thymeleaf的默认路径在 "classpath:/templates/" 下,所以在该路径下新建 success.html 文件
<!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/>
<a href="www.atguigu.com" th:href="@{link}">去百度2</a>
</h2>
</body>
</html>
在controller文件下新建ViewTestController类
@Controller
public class ViewTestController {
@GetMapping("/view")
public String view(Model model){
//model中的数据会被放在请求域中 request.setAttribute("a",aa)
model.addAttribute("msg","你好!!");
model.addAttribute("link","http://www.baidu.com");
return "success";
}
}
测试
查看网页源代码
4、拦截器
4.1、HandlerInterceptor 接口
/**
* 登录检查
* 1、配置好拦截器要拦截哪些请求
* 2、把这些配置放在容器中
*/
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 {
//登录检查逻辑
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if(loginUser != null){
//放行
return true;
}
//拦截住。未登录。跳转到登录页
request.setAttribute("msg","请先登录");
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 {
}
/**
* 页面渲染以后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4.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/**"); //放行的请求
}
}
5、文件上传
在controller文件下新建FormTestController类,添加以下代码
@Controller
public class FormTestController {
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestPart("headerImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
//上传一张图片
if(!headerImg.isEmpty()){
//保存到文件服务器,OSS服务器
String originalFilename = headerImg.getOriginalFilename();
headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
}
//上传多张图片
if(photos.length > 0){
for (MultipartFile photo : photos) {
if(!photo.isEmpty()){
String originalFilename = photo.getOriginalFilename();
photo.transferTo(new File("H:\\cache\\"+originalFilename));
}
}
}
return "main";
}
}