【Spring Boot】8.Web基础

目录

1.SpringMVC自动配置概览

https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-developing-web-applications
在这里插入图片描述
link
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景我们都无需自定义配置)
The auto-configuration adds the following features on top of Spring’s defaults:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
    • 内容协商视图解析器和BeanName视图解析器
  • Support for serving static resources, including support for WebJars (covered later in this document)).
    • 静态资源(包括webjars)
  • Automatic registration of Converter, GenericConverter, and Formatter beans.
    • 自动注册 Converter,GenericConverter,Formatter
  • Support for HttpMessageConverters (covered later in this document).
    • 支持 HttpMessageConverters (后来我们配合内容协商理解原理)
  • Automatic registration of MessageCodesResolver (covered later in this document).
    • 自动注册 MessageCodesResolver (国际化用)
  • Static index.html support.
    • 静态index.html 页支持
  • Custom Favicon support (covered later in this document).
    • 自定义 Favicon
  • Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).
    • 自动使用 ConfigurableWebBindingInitializer ,(DataBinder负责将请求数据绑定到JavaBean上)
    • 不用@EnableWebMvc注解。使用 @Configuration + WebMvcConfigurer 自定义规则
    • 声明 WebMvcRegistrations 改变默认底层组件
    • 使用 @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC

2.简单分析

2.1 静态资源访问

2.1.1 静态资源目录

只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources
访问 : 当前项目根路径/ + 静态资源名
在这里插入图片描述
在这里插入图片描述
原理: 静态映射/**。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

在这里插入图片描述
在这里插入图片描述

2.1.2改变默认的静态资源路径(以后静态资源都在这里面)

  resources:
    static-locations: [classpath:/haha/]

在这里插入图片描述

2.1.3 静态资源访问前缀

spring:
  mvc:
    static-path-pattern: /res/**
    这样可以区分开静态资源和动态资源

2.2 webjar

导入前端开发组件工具
自动映射 :/webjars/**
https://www.webjars.org/
在这里插入图片描述

2.2.1 导入jQuery

<dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.5.1</version>
        </dependency>

访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径
在这里插入图片描述

2.2 自定义 Favicon(页面图标)

在这里插入图片描述

2.3 静态资源配置原理

在这里插入图片描述

  • SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)
  • SpringMVC功能的自动配置类 WebMvcAutoConfiguration,生效

在这里插入图片描述
看见enable(启动)可知给容器配置了什么
置文件的相关属性和xxx进行了绑定。WebMvcProperties=spring.mvc、ResourceProperties=spring.resources
在这里插入图片描述

//有参构造器所有参数的值都会从容器中确定
//ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath  
//ServletRegistrationBean   给应用注册Servlet、Filter....

2.3.1 资源处理的默认规则

在这里插入图片描述

yaml: resources:
add-mappings: false 禁用所有静态资源规则
在这里插入图片描述

3. 请求参数处理

3.1 请求映射

Rest风格:(使用HTTP请求方式动词来表示对资源的操作)

  • 不使用:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户

  • 使用:/user GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户

  • 核心Filter:WebMvcAutoConfiguration下的HiddenHttpMethodFilter
    在这里插入图片描述
    在这里插入图片描述

  • 用法: 表单method=post,隐藏域 _method=put

  • SpringBoot中手动开启
    在这里插入图片描述

在这里插入图片描述

3.1.1测试(只是表单提交时使用rest风格)

3.1.1.1 Controller
package com.node.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/1.jpg")
    public String hello(){
        return "2";
    }
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public String getUser(){
        return "GET-张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String saveUser(){
        return "POST-张三";
    }


    @RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String putUser(){
        return "PUT-张三";
    }

    @RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
        return "DELETE-张三";
    }
}

3.1.1.2 静态资源
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
测试REST风格:
<form action="/user" method="get">
    <input value="REST-GET 提交" type="submit">
</form>
<form action="/user" method="post">
    <input value="REST-POST 提交" type="submit">
</form>
<form action="/user" method="post">
<!--因为没有method没有delete提交方法,所以需要隐藏域_method-->
    <input name="_method" type="hidden" value="DElETE">
    <input value="REST-DELETE 提交" type="submit">
</form>
<form action="/user" method="post">
    <input name="_method" type="hidden" value="PUT">
    <input value="REST-PUT 提交" type="submit">
</form>
</body>
</html>

3.1.2 Rest原理(表单提交要使用REST的时候)

表单提交会带上_method=PUT
请求过来被HiddenHttpMethodFilter拦截

  • 请求是否正常,并且是POST
    • 获取到_method的值。
    • 兼容以下请求;PUT.DELETE.PATCH
    • 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
    • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。

Rest使用客户端工具,
• 如PostMan直接发送Put、delete等方式请求,无需Filter。

3.1.3 SpringMVC新注解

package com.node.demo.controller;

import org.springframework.web.bind.annotation.*;

@RestController
public class HelloController {

    @RequestMapping("/1.jpg")
    public String hello(){
        return "2";
    }

    @GetMapping //@RequestMapping(value = "/user",method = RequestMethod.GET)
    public String getUser(){
        return "GET-张三";
    }

    @PostMapping //@RequestMapping(value = "/user",method = RequestMethod.POST)
    public String saveUser(){
        return "POST-张三";
    }

    @PutMapping  //@RequestMapping(value = "/user",method = RequestMethod.PUT)
    public String putUser(){
        return "PUT-张三";
    }

    @DeleteMapping  //@RequestMapping(value = "/user",method = RequestMethod.DELETE)
    public String deleteUser(){
        return "DELETE-张三";
    }
}

3.1.4 请求映射原理

SpringMVC功能分析都从 org.springframework.web.servlet.DispatcherServlet
–>doDispatch()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所有的请求映射都在HandlerMapping中。

  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
    • 如果有就找到这个请求对应的handler
    • 如果没有就是下一个 HandlerMapping
  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
    在这里插入图片描述

3.2 普通参数与基本注解

3.2.1 注解

@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody
@RequestPart:用在multipart/form-data表单提交请求的方法上(多数用于文件上传),@RequestParam和@RequestPart对比,@RequestPart适用于复杂的请求域(像JSON,XML)

3.2.1.1 测试
3.2.1.1.1 HelloController
package com.node.demo.controller;

import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class HelloController {
    //  car/2/owner/zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String,Object> getCar(@PathVariable("id") Integer id, //地址路径变量
                                     @PathVariable("username") String name,
                                     @PathVariable Map<String,String> pv,
                                     @RequestHeader("User-Agent") String userAgent, //获取请求头
                                     @RequestHeader Map<String,String> header,
                                     @RequestParam("age") Integer age,   //获取请求参数
                                     @RequestParam("inters") List<String> inters,
                                     @RequestParam Map<String,String> params,
                                     @CookieValue("Idea-43d88c3f") String _ga){
/*
@MatrixVariable:矩阵变量:与@RequestParam类似,但是是对路径的修改。需要手动开启。
地址语法:    /cars/sell;low=34;brand=byd,audi,yd     ;下面的是参数
* */

        Map<String,Object> map = new HashMap<>();

        map.put("id",id);
        map.put("name",name);
        map.put("pv",pv);
        map.put("userAgent",userAgent);
        map.put("headers",header);
        map.put("age",age);
        map.put("inters",inters);
        map.put("params",params);
        map.put("Idea-43d88c3f",_ga);
        return map;
    }


    @PostMapping("/save")
    public Map postMethod(@RequestBody String content){   //获取请求体【post】
        Map<String,Object> map = new HashMap<>();
        map.put("content",content);
        return map;
    }

}

3.2.1.1.2 index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="car/2/owner/zhangsan?age=1&inters=game&inters=lla">car/{id}/owner/{username}</a>
<br/>


<form action="/save" method="post">
    测试@RequestBody获取数据
    <br/>
    <p>用户名:<input name="username"/></p>
    <p>密码:<input name="password"/></p>
    <input type="submit" value="提交">
</form>
</body>
</html>
3.2.1.1.2 AttributeController
package com.node.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/*
@RestController:@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,
返回json数据不需要在方法前面加@ResponseBody注解了,
但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
*/
@Controller
public class AttributeController {

    @GetMapping("/goto")
    public String goToPage(HttpServletRequest request){
        request.setAttribute("msg","跳转成功");
        request.setAttribute("code","200");
        return "forward:/success";
    }
@ResponseBody
    @GetMapping("/success")
    public Map success(@RequestAttribute("msg") String msg,
                       @RequestAttribute("code") Integer code,
                       HttpServletRequest request){
        Object msg1=request.getAttribute("msg");
        Map<String,Object> map=new HashMap<>();
        map.put("msg",msg);
    map.put("code",code);
        map.put("msg1",msg1);

        return map;
    }
}

3.3 注解参数处理原理

先略

3.4 Thymeleaff

Thymeleaf是一个用于Web和独立环境的现代服务器端Java模板引擎,能够处理HTML、XML、JavaScript、CSS甚至纯文本。类似与jsp,简单来说是从后端代码的值传递到前端
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

表达式名字语法用途
变量取值${…}获取请求域、session域、对象
选择变量*{…}$1600
消息#{…}$1600
链接@{…}$1600
片段表达式~{…}$1600

3.4.1 字面量

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

3.4.2 文本操作

字符串拼接: +
变量替换: |The name is ${name}|

3.4.3 数学运算

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

3.4.4 布尔运算

运算符: and , or
一元运算: ! , not

3.4.5 比较运算

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

3.4.6 条件运算

If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)

3.4.7 特殊操作

无操作: _

3.4.8 设置属性值-th:attr

3.4.8.1 设置单个值
<form action="subscribe.html" th:attr="action=@{/subscribe}">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
  </fieldset>
</form>
3.4.8.2 设置多个值
<img src="../../images/gtvglogo.png"  th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
3.4.8.3 以上两个的代替写法 th:xxxx
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">

3.4.9 迭代

<tr th:each="prod : ${prods}">
        <td th:text="${prod.name}">Onions</td>
        <td th:text="${prod.price}">2.41</td>
        <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>

3.4.10 条件运算

<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p>
</div>

3.4.11 th:fragment

在这里插入图片描述
在这里插入图片描述

3.4.12 测试

3.4.12.1 引入starter
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
3.4.12.2 application.yml
server:
  servlet:
    context-path: /static
3.4.12.3 ViewController
package com.node.demo.controller;


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ViewController {

    @GetMapping("/hha")
    public String hha(Model model){
        //model中的数据会被放在请求域中request.setAttribute ( "a " , aa)
        model.addAttribute("msg","你好,哈哈");
        model.addAttribute("link","http://www.baidu.com");
        return "success";
    }
}

3.4.12.4 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 th:href="${link}">去百度</a>
    <a th:href="@{link}">去百度2</a>
</h2>
</body>
</html>

在这里插入图片描述

4.web原生组件注入(Servlet、Filter、Listener)

官方文档:
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-embedded-container
在这里插入图片描述

4.1 方法一:使用Servlet API

@ServletComponentScan(basePackages = “com.atguigu.admin”) :指定原生Servlet组件都放在那里
@WebServlet(urlPatterns = “/my”):效果:直接响应,没有经过Spring的拦截器
@WebFilter(urlPatterns={"/css/","/images/"})
@WebListener

4.1.1 创建项目

在这里插入图片描述

4.1.2 主程序

在这里插入图片描述

@ServletComponentScan(basePackages = "com.node.demo")

4.1.3 MyServlet

package com.node.demo.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("66666");
    }
}

在这里插入图片描述

4.1.4 MyFilter

package com.node.demo.servlet;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = {"/css/*"})   //过滤器,过滤静态资源css下的资源(操作自己操作)
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化完成");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter工作");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("MyFilter销毁");
    }
}

4.1.5 MyservletContextListener

package com.node.demo.servlet;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@Slf4j
@WebListener
public class MyservletContextListener implements ServletContextListener {


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyservletContextListener监听到项目初始化完成");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyservletContextListener监听到项目销毁");
    }

}

4.2 方法二:使用RegistrationBean

4.2.1 注释

注释掉MyServlet、MyFilter、MyservletContextListener里面的
//@WebServlet(urlPatterns = “/my”)
//@WebFilter(urlPatterns = {"/css/*"})
//@WebListener

4.2.2 MyRegistConfig

package com.node.demo.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 java.util.Arrays;

@Configuration
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my");
    }


    @Bean
    public FilterRegistrationBean myFilter(){

        MyFilter myFilter = new MyFilter();
//        return new FilterRegistrationBean(myFilter,myServlet());
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener(){
        MyservletContextListener myservletContextListener = new MyservletContextListener();
        return new ServletListenerRegistrationBean(myservletContextListener);
    }
}

5.定制化原理

自己定制更改配置属性

5.1 常见方式

5.1.1 修改配置文件

application.properties、application.yml

5.1.2 xxxxxCustomizer:定制Servlet容器

xxxxxCustomizer:定制化器,可以改变xxxx的默认规则

WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
把配置文件的值和ServletWebServerFactory 进行绑定

  • 修改配置文件 server.xxx
  • 直接自定义 ConfigurableServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}

5.1.3 xxxConfiguration+ @Bean

编写自定义的配置类 xxxConfiguration;+ @Bean替换、增加容器中默认组件;视图解析器

5.1.4 Web应用 编写一个配置类实现 WebMvcConfigurer 即可定制化web功能;+ @Bean给容器中再扩展一些组件

重要

5.1.5 @EnableWebMvc + WebMvcConfigurer +@Bean

可以全面接管SpringMVC,所有规则全部自己重新配置; 实现定制和扩展功能

6.原理分析套路

场景starter - xxxxAutoConfiguration - 导入xxx组件 - 绑定xxxProperties – 绑定配置文件项

加粗部分需要我们自己操作,中间部分Spring boot帮我们配置好

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值