SpringBoot2核心功能-web开发

news2024/11/27 0:21:42

目录

  • 一、简单功能分析
    • 1.1、静态资源访问
    • 1.2、欢迎页支持、自定义 Favicon
  • 二、请求参数处理
    • 2.1、请求映射
      • 2.1.1、rest使用与原理
      • 2.1.2、请求映射原理
    • 2.2、普通参数与基本注解
      • 2.2.1、注解
      • 2.2.2、Servlet API:
      • 2.2.3、复杂参数:
  • 三、拦截器
  • 四、Web原生组件注入(Servlet、Filter、Listener)
  • 五、定制化原理

一、简单功能分析

1.1、静态资源访问

只要静态资源放在类路径下: called /static (or /public or /resources or /META-INF/resources

访问 : 当前项目根路径/ + 静态资源名
原理: 静态映射/**。

请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面

  • 改变默认的静态资源路径

    spring:
      resources:
        static-locations: [classpath:/haha/]
    
  • 改变静态资源访问前缀
    默认无前缀

    spring:
      mvc:
        static-path-pattern: /res/**
    

    当前项目 + static-path-pattern + 静态资源名

1.2、欢迎页支持、自定义 Favicon

静态资源路径下 index.html

  • 可以配置静态资源路径
  • 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

favicon.ico 放在静态资源目录下即可。

spring:
#  mvc:
#    static-path-pattern: /res/**   这个会导致welcome page、Favicon功能失效
  resources:
    static-locations: [classpath:/haha/]
  resources:
    add-mappings: false   禁用所有静态资源规则

二、请求参数处理

2.1、请求映射

2.1.1、rest使用与原理

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

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

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

    • 核心Filter;HiddenHttpMethodFilter
    • 用法:
      • 表单method=post,隐藏域 _method=put
      • SpringBoot中手动开启
        spring:
          mvc:
            hiddenmethod:
              filter:
                enabled: true   #开启页面表单的Rest功能
        
    @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-张三";
        }
    
    

扩展:如何把_method 这个名字换成我们自己喜欢的。

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

2.1.2、请求映射原理

在这里插入图片描述
SpringMVC功能分析都从 org.springframework.web.servlet.DispatcherServlet-》doDispatch()

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;
 
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
 
		try {
			ModelAndView mv = null;
			Exception dispatchException = null;
 
			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);
 
				// 找到当前请求使用哪个Handler(Controller的方法)处理
				mappedHandler = getHandler(processedRequest);
                
                //HandlerMapping:处理器映射。/xxx->>xxxx

在这里插入图片描述
RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。
在这里插入图片描述
所有的请求映射都在HandlerMapping中。

  • SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
  • SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
  • 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
    • 如果有就找到这个请求对应的handler
    • 如果没有就是下一个 HandlerMapping
  • 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义 HandlerMapping
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

2.2、普通参数与基本注解

2.2.1、注解

@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody

@RestController
public class ParameterTestController {


    //  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("_ga") String _ga,
                                     @CookieValue("_ga") Cookie cookie){


        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("_ga",_ga);
        System.out.println(cookie.getName()+"===>"+cookie.getValue());
        return map;
    }


    @PostMapping("/save")
    public Map postMethod(@RequestBody String content){
        Map<String,Object> map = new HashMap<>();
        map.put("content",content);
        return map;
    }

 //1、语法: 请求路径:/cars/sell;low=34;brand=byd,audi,yd
    //2、SpringBoot默认是禁用了矩阵变量的功能
    //      手动开启:原理。对于路径的处理。UrlPathHelper进行解析。
    //              removeSemicolonContent(移除分号内容)支持矩阵变量的
    //3、矩阵变量必须有url路径变量才能被解析
    @GetMapping("/cars/{path}")
    public Map carsSell(@MatrixVariable("low") Integer low,
                        @MatrixVariable("brand") List<String> brand,
                        @PathVariable("path") String path){
        Map<String,Object> map = new HashMap<>();

        map.put("low",low);
        map.put("brand",brand);
        map.put("path",path);
        return map;
    }

    // /boss/1;age=20/2;age=10

    @GetMapping("/boss/{bossId}/{empId}")
    public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,
                    @MatrixVariable(value = "age",pathVar = "empId") Integer empAge){
        Map<String,Object> map = new HashMap<>();

        map.put("bossAge",bossAge);
        map.put("empAge",empAge);
        return map;

    }

}

手动开启矩阵变量的功能
在这里插入图片描述

2.2.2、Servlet API:

WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId

ServletRequestMethodArgumentResolver 以上的部分参数

@Override
	public boolean supportsParameter(MethodParameter parameter) {
		Class<?> paramType = parameter.getParameterType();
		return (WebRequest.class.isAssignableFrom(paramType) ||
				ServletRequest.class.isAssignableFrom(paramType) ||
				MultipartRequest.class.isAssignableFrom(paramType) ||
				HttpSession.class.isAssignableFrom(paramType) ||
				(pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
				Principal.class.isAssignableFrom(paramType) ||
				InputStream.class.isAssignableFrom(paramType) ||
				Reader.class.isAssignableFrom(paramType) ||
				HttpMethod.class == paramType ||
				Locale.class == paramType ||
				TimeZone.class == paramType ||
				ZoneId.class == paramType);
	}

2.2.3、复杂参数:

Map、Model(map、model里面的数据会被放在request的请求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向携带数据)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

Map<String,Object> map,  Model model, HttpServletRequest 
request 都是可以给request域中放数据,

request.getAttribute();

Map、Model类型的参数,会返回 mavContainer.getModel();—> BindingAwareModelMap 是Model 也是Map
mavContainer.getModel(); 获取到值的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、拦截器

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/**"); //放行的请求
    }
}

四、Web原生组件注入(Servlet、Filter、Listener)

1、使用Servlet API

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

2、使用RegistrationBean

ServletRegistrationBean, FilterRegistrationBean, and ServletListenerRegistrationBean

@Configuration
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean myServlet(){
        MyServlet myServlet = new MyServlet();

        return new ServletRegistrationBean(myServlet,"/my","/my02");
    }


    @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(){
        MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();
        return new ServletListenerRegistrationBean(mySwervletContextListener);
    }
}

五、定制化原理

1、定制化的常见方式

  • 修改配置文件;
  • xxxxxCustomizer;
  • 编写自定义的配置类 xxxConfiguration;+ @Bean替换、增加容器中默认组件;视图解析器
  • Web应用 编写一个配置类实现 WebMvcConfigurer 即可定制化web功能;+ @Bean给容器中再扩展一些组件
@Configuration
public class AdminWebConfig implements WebMvcConfigurer
  • @EnableWebMvc + WebMvcConfigurer —— @Bean 可以全面接管SpringMVC,所有规则全部自己重新配置; 实现定制和扩展功能
    原理
    • 1、WebMvcAutoConfiguration 默认的SpringMVC的自动配置功能类。静态资源、欢迎页…
    • 2、一旦使用 @EnableWebMvc 、。会 @Import(DelegatingWebMvcConfiguration.class)
    • 3、DelegatingWebMvcConfiguration 的 作用,只保证SpringMVC最基本的使用
      • 把所有系统中的 WebMvcConfigurer 拿过来。所有功能的定制都是这些 WebMvcConfigurer 合起来一起生效
      • 自动配置了一些非常底层的组件。RequestMappingHandlerMapping、这些组件依赖的组件都是从容器中获取
      • public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
    • 4、WebMvcAutoConfiguration 里面的配置要能生效 必须 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    • 5、@EnableWebMvc 导致了 WebMvcAutoConfiguration 没有生效。

2、原理分析套路

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2207153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32之CAN外设

相信大家在学习STM32系列的单片机时&#xff0c;在翻阅芯片的数据手册时&#xff0c;都会看到这么一个寄存器外设——CAN外设寄存器。那么&#xff0c;大家知道这个外设的工作原理以及该如何使用吗&#xff1f;这节的内容将会详细介绍STM32上的CAN外设&#xff0c;文章结尾附有…

气象数据三维可视化的实现原理及代码

气象数据三维可视化是一种使用三维图形技术来呈现和分析气象数据的方法。通过三维可视化&#xff0c;用户可以更直观地观察气象数据的空间分布、变化趋势以及天气现象的复杂结构。这种技术广泛应用于气象预报、科学研究以及环境监测等领域。 本文将介绍气象数据三维可视化的基…

未来战争中的指控体系不仅是分布式的

指控体系&#xff0c;作为军事指挥与控制的重要组成部分&#xff0c;经历了从传统的集权指挥向现代分布式指挥的转变。历史上&#xff0c;战争指挥体系主要依赖于集中式指挥官的决策&#xff0c;信息流动缓慢&#xff0c;决策过程受到地理位置、通信手段等多种因素的制约。随着…

数据库实例

例3.5建立一个“学生”表student create table student(sno char(9) primary key,sname char(20) unique,ssex char(2),sage smallint,sdept char(20)); 例3.6建立一个“课程”表course create table course(cno char(4) primary key,cname char(40) not null,cpno char(4),…

保姆级教程 | VMD输出局部结构及利用TkConsole实现旋转

背景 由于课题需要,现需要展示lammps模拟轨迹中的局部结构(主要是想可视化这里的结果:保姆级教程 | 输出分子动力学轨迹文件输出特定原子范围内的化学环境),因为ovito效果有点笨笨的,所以我这里选用VMD软件为例进行操作,效果图(超级好看夸夸): (说明:主要的分子构…

计算机毕业设计 | SSM 旅游网站后台管理系统(附源码)

1&#xff0c;概述 1.1 背景分析 随着人们生活水平的提高和对休闲旅游的日益重视&#xff0c;旅游业已成为全球最大的经济产业之一。越来越多的人选择通过在线方式进行旅行预订&#xff0c;这种趋势为旅游网站提供了巨大的商机。用户体验是决定旅游网站成功与否的关键因素。良…

vue代码中关于字符串对比的实现

常见的数据比较都只限制于数字比较的比较&#xff0c;但是现在遇到一个框架他会自动将所有传输过来的值转化为字符串形式&#xff0c;导致在比较的时候无法进入到表单校验的代码中去 1.使用Number函数 2.使用 号运算符,都可以实现

python networkx 计算路径A*

import matplotlib.pyplot as plt # 导入 Matplotlib 工具包 import networkx as nx # 导入 NetworkX 工具包 from typing import List# 初始化空的无向图 graph nx.Graph() # 向图中添加多条赋权边: (node1,node2,weight) graph.add_weighted_edges_from([(1, 2, 50),(1, 3…

智能扭矩系统在制造领域应用_SunTorque

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在当今高度自动化和智能化的制造领域&#xff0c;各种先进技术不断涌现&#xff0c;为提高生产效率、保证产品质量和降低成本提供了有力支持。智能扭矩系统作为其中…

【电子电力】基于DSP28335+DSP28035的三相三电平大功率并网逆变器程序代码

摘要 本文介绍了基于DSP28335和DSP28035的三相三电平大功率并网逆变器设计和实现。通过DSP控制器对三电平逆变器的精确控制&#xff0c;实现了逆变器与电网的并网控制&#xff0c;保证了系统的高效稳定运行。该设计主要应用于光伏发电和风力发电系统中的并网发电部分。本文通过…

在AI大模型时代遨游,你不得不知道的一些事

用户到底为什么而买单/产品和研发要抛弃的历史包袱 在大模型时代之前&#xff0c;其实企业和企业之间的软件产品壁垒来自两个地方&#xff1a; 交互&#xff0c;让用户用起来感觉舒服。打磨&#xff0c;我花了五年修复了用户遇到的一万个bug,所以我的产品比你好。 但是无论如何…

如何使用flutter doctor命令检测环境是否配置成功

Flutter Windows Android环境搭建 真机调试学习地址&#xff1a; 17 Flutter介绍-Flutter Windows Android环境搭建 真机调试 如何使用flutter doctor命令检测环境是否配置成功&#xff0c;详细步骤如下&#xff1a; 第一次执行可能会提示下面错误&#xff1a; 1、错误一&am…

建站:腾讯云+宝塔linux+xftp

1.首先&#xff0c;控制台&#xff0c;服务器 2.服务器-网络与域名-ip地址&#xff0c;能看到公网地址 3.宝塔Linux面板-网站-添加站点 4.填写域名会自动生成 ftp 帐号密码 域名可以加上端口&#xff0c;端口号可以写大点 5.xftp新建会话 主机地址&#xff1a;腾讯云拿到的公…

直流有刷电机驱动芯片:【TOSHIBA:TB6612】

Toshiba TB6612是是东芝半导体的一款驱动电机的IC。一个TB6612FNG可以驱动两个电机&#xff0c;每一个驱动都有两个逻辑输入引脚&#xff0c;一个输出引脚和一个PWM引脚。可以通过给两个逻辑输入引脚不同的电平来控制电机的运行状态&#xff0c;通过PWM输入引脚实现电机调速。 …

怎么看待数字化转型是大势所趋?

怎么看到数字化转型是大势所趋&#xff1f;下面我结合最新数据给大家讲明白这个事。 近日&#xff0c;我通过大量的数据相关性分析&#xff0c;有了一些关键发现。 【数字化转型】之所以势在必行&#xff0c;主要是因为数字化转型为各个国家数字经济发展提供了重要的参考依据。…

R2:RNN-心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、实验目的&#xff1a; 本地读取并加载数据。了解循环神经网络&#xff08;RNN&#xff09;的构建过程测试集accuracy到达87% 拔高&#xff1a;测试集accur…

腾讯云Android 相关

集成遇到异常怎么办&#xff1f; 您可以使用 armeabi 和 armeabi-v7a 架构。 如上图所示&#xff0c;请在app的 build.gradle 中指定 abiFilters 为“armeabi”。 功能模块升级后&#xff0c;短视频 SDK 的功能不能使用&#xff1f; 1. 如果使用的是 androidstudio&#xff0…

2024Selenium自动化常见问题!

"NoSuchElementException"异常&#xff1a; 确保使用了正确的选择器来定位元素。可以使用id、class、XPath或CSS选择器等。 可以尝试使用find_elements方法来查找元素列表&#xff0c;并检查列表的长度来判断元素是否存在。 使用显式等待&#xff08;WebDriverWait…

考研编程:10.11 回文数 水仙花 生成一定范围内的随机数 求二叉树宽度

回文数 #include <stdio.h>int main(){int a,b,c0,sum;scanf("%d",&a);ba;while(b!0){c b%10 c*10;b b/10;}if(ca){printf("yes");}return 0; } 水仙花 #include <stdio.h> #include <math.h> int main(){int a,b,c0,sum;scan…

内嵌服务器Netty Http Server

内嵌式服务器不需要我们单独部署&#xff0c;列如SpringBoot默认内嵌服务器Tomcat,它运行在服务内部。使用Netty 编写一个 Http 服务器的程序&#xff0c;类似SpringMvc处理http请求那样。举例&#xff1a;xxl-job项目的核心包没有SpringMvc的Controller层&#xff0c;客户端却…