一、简单功能分析
1、静态资源访问
(1).静态资源目录
只要静态资源放在类路径下:called /static(or /public or /resources or /META-INF/resources)
访问:当前项目根路径/+静态资源名
原理:静态映射/**
请求进来先去找Controller看能不能处理,不能处理的所有请求又都交给静态资源处理器。静态资源也找到404
改变默认的静态资源路径
spring: web: resources: static-locations: classpath:/haha/
(2).静态资源访问前缀
spring: mvc: static-path-pattern: /res/**
当前项目+scatic-path-pattern+静态资源名 = 在静态资源文件夹下找
2.欢迎页支持
· 静态资源路径下:index.html
· 可以配置静态资源路径
· 但是不可以配置静态资源的访问前缀,否则导致index.html不能被默认访问
#spring: ## mvc: ## static-path-pattern: /res/** 这个会导致welcome page功能失效 # web: # resources: # static-locations: classpath:/haha/
· controller能处理/index
3.自定义Favicon
static目录下放一个名字为favicon.ico的图片文件就可以识别
#spring: ## mvc: ## static-path-pattern: /res/** 这个会导致favicon功能失效 # web: # resources: # static-locations: classpath:/haha/
二、请求参数处理
1.普通参数与基本注解
· 注解:
@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、
@CookieValue
· Servlet API:
WebRequest、ServletRequest、MultipartRequest、HttpSession、java.servlet.http.PushBuilder等
· 复杂参数:
Map、Model、RedirectAttributes等
· 自定义对象参数:
可以自动类型转换与格式化,可以级联封装
2、POJO封装过程
3、参数处理原理
4、响应数据与内容协商
5、视图解析与模板引擎
视图解析:SpringBoot默认不支持JSP,需要引入第三方模板引擎技术实现页面渲染
(1)thymeleaf使用
1.引入Starter
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
2.自动配置好了thymeleaf
@EnableConfigurationProperties({ThymeleafProperties.class}) @ConditionalOnClass({TemplateMode.class, SpringTemplateEngine.class}) @AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class}) @Import({ReactiveTemplateEngineConfiguration.class, DefaultTemplateEngineConfiguration.class}) public class ThymeleafAutoConfiguration {
自动配好的策略:
· 所有thymeleaf的配置值都在ThymeleafProperties
· 配置好了SpringTemplateEngine
· 配置好了ThymeleafViewResolver
· 我们只需要直接开发页面
<!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}">HaHa</h1> <h2> <a href="www.hao123.com" th:href="${link}">去百度</a> <a href="www.hao123.com" th:href="@{/link}">去百度2</a> </h2> </body> </html>
@Controller public class ViewTestController { @GetMapping("/z") public String zzz(Model model){ //model中的数据会被放在请求域中 request.setAttribute("a",aa) model.addAttribute("msg","你好 zz"); model.addAttribute("link","http://www.baidu.com"); return "success"; } }
6、拦截器
interceptor:
/** * 拦截器的作用:登陆检查 * 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 requestURL=request.getRequestURI(); log.info("拦截的请求路径是{}",requestURL); //登陆检查逻辑 HttpSession session=request.getSession(); Object loginUser = session.getAttribute("loginUser"); if (loginUser!=null){ //放行 return true; } //拦截住,未登录跳转到登录页 //session.setAttribute("msg","请先登录"); request.setAttribute("msg","请先登录"); //response.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 { } /** * 页面渲染之后 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
config文件:
/** * 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/**"); //放行的请求 } }
7、文件上传
package com.z.boot04admin.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.support.MultipartFilter; import java.io.File; import java.io.IOException; /** *文件上传测试 */ @Slf4j @Controller public class FormTestController { @GetMapping("/form_layouts") public String form_layouts(){ return "form/form_layouts"; } /** * MultipartFile自动封装上传过来的文件 * @param email * @param username * @param headerImg * @param photos * @return */ @PostMapping("/upload") public String upload(@RequestParam("email") String email, @RequestParam("username") String username, @RequestParam("headerImg") MultipartFile headerImg, @RequestParam("photos") MultipartFile[] photos) throws IOException { log.info("上传的信息:email={},username={},headerImg={},photos={}",email,username,headerImg.getSize(),photos.length); if(!headerImg.isEmpty()){ //保存到文件服务器,OSS服务器 String originalFilename = headerImg.getOriginalFilename(); headerImg.transferTo(new File("D:\\QQ\\"+originalFilename)); if(photos.length>0){ for(MultipartFile photo:photos){ String originalFilename1 = photo.getOriginalFilename(); photo.transferTo(new File("D:\\QQ\\"+originalFilename1)); } }else { System.out.println("111"); } } return "main"; } }
8、异常处理
(1)默认规则
· 默认情况下,SpringBoot提供/error处理所有错误的映射
· 对于机器客户端,他将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“whitelabel”错误视图,以HTML格式呈现相同的数据
· 要对其进行自定义,添加View解析为error
· 要完全替换默认行为,可以实现ErrorController并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容
· error下的4xx,5xx页面会被自动解析
(2)制定错误处理逻辑
· 自定义错误页
例如: error/404.html
· @ControllerAdvice+@ExceptionHandler处理异常
· 实现HandlerExceptionResolver处理异常
9、Web原生组件注入(Servlet、Filter、Listener)
1、使用Servlet API
@ServletComponentScan(basePackages = "com.z.boot04admin") 指定原生Servlet组件都放在哪里@WebServlet(urlPatterns = "/my");效果:直接响应,没有经过Spring的拦截器@WebFilter(urlPatterns = {"/css/*","/images/*"})@WebListener
2、使用RegistrationBean
ServletRegistrationBean,FileRegistrationBean,and ServletListenerRegistrationBean
package com.z.boot04admin.servlet; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Controller; import javax.imageio.spi.ServiceRegistry; import java.util.EventListener; @Configuration public class MyRegistConfig { @Bean public ServletRegistrationBean myServlet(){ MyServiet myServiet = new MyServiet(); return new ServletRegistrationBean(myServiet,"/my","/my02"); } @Bean public FilterRegistrationBean myFilter(){ MyFilter myFilter = new MyFilter(); return new FilterRegistrationBean(myFilter,myServlet()); } @Bean public ServletListenerRegistrationBean myListener(){ MyServletContextListener myServletContextListener = new MyServletContextListener(); return new ServletListenerRegistrationBean(myServletContextListener); } }
10、嵌入式容器
1、切换嵌入式Servlet容器
· 默认支持的webServer
Tomcat,Jetty,or Undertow
ServletWebServerApplicationContext容器启动寻找ServletWebServerFactory并引导创建服务器
· 切换服务器
2、定制Servlet容器
· 实现WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
把配置文件的值和ServletWebServerFactory进行绑定
· 修改配置文件server.xx
` 直接自定义ConfigurableServletWebServerFactory
11、定制化原理
1、定制化的常见方式
· 修改配置文件
· 编写自定义的配置类 xxxConfiguration;+@Bean替换、增加容器中默认组件;视图解析器
· web应用 实现WebMvcConfigurer,即可制定化Web功能