SpringBoot基础学习之SpringBoot Web开发(上篇)

前言

小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。
这个SpringBoot基础学习系列用来记录我学习SpringBoot框架基础知识的全过程 (这个系列是参照B站狂神的SpringBoot最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)
之后我将会以一天一更的速度更新这个系列,还没有学习SpringBoot的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。
最后,希望能够和大家一同进步吧!加油吧!少年们!

由于SpringBoot Web开发涉及的内容比较多,所以蜗牛君打算把这部分将会分成上中下三篇博客,上篇主要分析SpringBoot开发Web的优缺点以及静态资源的配置和使用;中篇主要介绍模板引擎和MVC配置原理,下篇是项目实战,基于SpringBoot构建一个简单的员工管理系统!
废话不多说,让我们开始今天的学习内容吧,由于今天我们来到了SpringBoot基础学习的第五站:SpringBoot Web开发(上篇)

5.SpringBoot Web开发

5.1 使用SpringBoot的好处和思考

5.1.1 使用SpringBoot的好处

1. 未使用SpringBoot时
  • 之前的开发,需要我们手动导入webapp的相关jar包,
  • SpringMVC等还需要我们去进行手动配置
  • 需要编写大量的配置文件,反而不能专注于业务代码了
2.使用了SpringBoot之后
  • 现在我们只需要创建应用,然后选择模块就好了
  • Spring已经将环境自动装配好了,也就是各种各种的starter启动器
  • 我们只需专注于业务代码的编写,不用去管理SpringMVC等的配置了

SpringBoot的核心就是:自动装配

5.1.2 对SpringBoot的思考

从以下四个维度去进行思考

SpringBoot到底帮我们配置了什么?我们能不能进行修改?能修改哪些东西?能不能扩展?

  • xxxAutoConfiguration:自动配置类,向容器中自动配置组件
  • xxxProperties:封装配置文件中的属性,也可以自定义内容

5.1.3 要解决的问题

  • 导入静态资源:.css、.js、.jsp文件等
  • 定制首页:解决打开页面就是404问题
  • 模板引擎:使用Thymeleaf
  • 装配扩展SpringMVC:文件上传、返回JSON字符串
  • 增删改查:CRUD
  • 拦截器:Interceptor
  • 国际化:I18N

5.2 静态资源

5.2.1 创建SpringBoot项目

1.选择Spring initializer项目

在这里插入图片描述

2.设置项目基本信息

在这里插入图片描述

3.选择Spring Web应用资源依赖

在这里插入图片描述

4.选择文件存放位置

在这里插入图片描述

5.删除多余文件后项目结构

在这里插入图片描述

5.2.1 编写控制层进行测试

1.编写HelloController控制类
package com.kuang.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//实现Controller接口并且使返回值为字符串形式
@RestController
public class HelloController {
    //设置请求映射路径:http://localhost:8080/hello
    @RequestMapping("/hello")
    public String hello() {
        return "Hello,SpringBoot!";
    }
}
2.启动SpringBoot应用
2-1 找到主应用程序类

在这里插入图片描述

2-2 启动应用成功

在这里插入图片描述

3.测试结果
3-1 访问主页

在这里插入图片描述

结果访问失败,出现了"空白标签错误页面"提示

因此我们需要定制首页,这个后面会提到,目前先不用管它

3-2 访问/hello页面

在这里插入图片描述

结果访问/hello请求成功!

5.2.3 分析WebMvc自动配置原理

1.分析WebMvcAutoConfiguration类
  • 查看WebMvcAutoConfiguration类源码
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
//WebMVC自动配置类
public class WebMvcAutoConfiguration {
    ......
}
  • 查看WebMvcAutoConfigurationAdapter类源码
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
                                org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
//WebMvc的自动配置适配器
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
    ......
}
  • 查看EnableWebMvcConfiguration
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
//WebMvc的能够自动配置
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    ......
}
  • 查看addResourceHandlers方法源码
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    super.addResourceHandlers(registry);
    //如果静态资源的东西已经被自定义了,直接返回
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    ServletContext servletContext = getServletContext();
    addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
        if (servletContext != null) {
            registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
        }
    });
}
  • 再次查看WebMvcAutoConfigurationAdapter
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
                                org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
//WebMvc的自动配置适配器
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
    ......
}
  • 查看WebMvcProperties类源码
//封装绑定了配置文件spring.mvc的所有属性
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
    ......
    //静态资源的路径
    private String staticPathPattern = "/**";
}
  • 在配置文件中测试
spring.mvc.static-path-pattern=
2.分析addResourceHandlers方法
2-1 查看addResourceHandlers类源码
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    super.addResourceHandlers(registry);
    //如果静态资源的东西已经被自定义了,直接返回,即默认的资源失效
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    ServletContext servletContext = getServletContext();
    //添加静态资源到/webjars/**中,位置在classpath:/META-INF/resources/webjars/
    addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
        if (servletContext != null) {
            registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
        }
    });
}
2-2 什么是webjars?

在这里插入图片描述

2-3 导入webjars形式的jquery
<!--导入jquery-->
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>
2-4 查看webjars形式jquery位置

在这里插入图片描述

2-5 使用浏览器访问jquery.js文件

在这里插入图片描述

2-5 分析addResourceHandlers方法
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    super.addResourceHandlers(registry);
    //如果静态资源的东西已经被自定义了,直接返回,即默认的资源失效
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    ServletContext servletContext = getServletContext();
    //添加静态资源到/webjars/**中,位置在classpath:/META-INF/resources/webjars/
    addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
    //getStaticPathPattern:获取静态资源的路径
    addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
        registration.addResourceLocations(this.resourceProperties.getStaticLocations());
        if (servletContext != null) {
            registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
        }
    });
}
2-6 结论

在SpringBoot中,我们可以使用以下方式处理静态资源

除了 /**"外,还有classpath:/METAINF/resources/;以及classpath:/resources/、classpath:/static/ 和 classpath:/public/

  • webjars路径下:访问方式 —> localhost:8080/webjars/
  • public、static、/**、resources路径下:访问方式 —> localhost:8080 /

5.2.4 静态资源位置优先级测试

1.存放classpath:/public/路径下
1-1 文件存放位置

在这里插入图片描述

1-2 编写JS代码
Hello,JavaScript
1-3 测试结果

在这里插入图片描述

2.存放classpath:/resources/路径下
1-1 文件存放位置

在这里插入图片描述

1-2 编写JS代码
Hello,Spring
1-3 测试结果

在这里插入图片描述

3.使用classpath:/public/ 和classpath:/resources/ 存放同名文件
3-1 文件存放位置

在这里插入图片描述

3-2 编写JS代码
  • 存放classpath:/public/路径下:
Hello,JavaScript
  • 存放classpath:/resources/ 路径下:
Hello,Spring
3-3 测试结果

在这里插入图片描述

3-4 测试结论

结果存放在 classpath:/resources/ 下比classpath:/public/ 下优先级高

4.存放classpath:/static/路径下
4-1 文件存存放位置
  • 在static文件夹下存放hello1.js同名文件

在这里插入图片描述

4-2 编写JS代码
  • classpath:/public/ 路径下:
Hello,JavaScript
  • classpath:/resources/ 路径下:
Hello,Spring
  • classpath:/static/ 路径下:
Hello,SpringMVC
4-3 测试结果

在这里插入图片描述

4-4 测试结论

结论存放在 classpath:/resources/ 下也比classpath:/static/ 下优先级高

5.使用classpath:/public/ 和 classpath:/static/ 存放同名路径
5-1 删除classpath:/resources/ 下文件

在这里插入图片描述

5-2 编写JS文件
  • 存放 classpath:/public/ 路径下:
Hello,JavaScript
  • 存放 classpath:/static/ 路径下:
Hello,SpringMVC
5-3 测试结果

在这里插入图片描述

5-4 测试结论

结论存放 classpath:/static/ 路径下优先级比存放 classpath:/public/ 下高

6.自定义资源访问路径
6-1 编写application.properties文件
# 在配置文件下自定义资源访问路径
spring.mvc.static-path-pattern=/hello/**
6-2 测试结果

在这里插入图片描述

6-3 测试结论

结论如果在配置文件下自定义资源访问路径,那么存放在resources、static以及public下的文件都会失效

7.使用总结

优先级比较结果:classpath:/resources/ > classpath:/static/ (默认使用) > classpath:/public/

资源存放总结

  • 因此,我们一般在public下存放一些公共资源,大家都会访问到的JS文件<
  • static下放一些静态资源,比如图片等
  • 而在resources下会放一些上传(upload) 的文件

5.2.5 定制首页

1.查看WebMvcAutoConfiguration类源码
  • 我们查看WebMvcAutoConfiguration自动配置类源码后发现,其中有个getIndexHtml方法来获取html页面资源
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
//WebMVC自动配置类
public class WebMvcAutoConfiguration {
    
         ......
             
        //欢迎页控制映射    
        @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
                                                                   FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
           ......
        }
    
            ......
                
            private Resource getIndexHtml(String location) {
                
            return getIndexHtml(this.resourceLoader.getResource(location));
        }
        //获取页面资源
        private Resource getIndexHtml(Resource location) {
           ......
        }    
}
  • 接下来我们来继续查看getIndexHtml方法,探究其是如何来获取html页面资源的
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
//WebMVC自动配置类
public class WebMvcAutoConfiguration {
    
         ......
             
        //欢迎页控制映射    
        @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
                                                                   FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
             //获取欢迎页面控制器映射(WelcomePageHandlerMapping)对象
            WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
                new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
                //获得静态路径参数
                this.mvcProperties.getStaticPathPattern());
 //设置拦截器
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
            welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
             //返回到欢迎页面映射
            return welcomePageHandlerMapping;
        }
    
            ......
        //获取页面资源        
        private Resource getIndexHtml(String location) {
            //通过定位来返回获取到的html页面       
            return getIndexHtml(this.resourceLoader.getResource(location));
        }
        //获取页面资源
        private Resource getIndexHtml(Resource location) {
            try {
                //创建index.html页面资源
                Resource resource = location.createRelative("index.html");
                //判断资源是否存在或者获取到的资源UR链接是否为空
                if (resource.exists() && (resource.getURL() != null)) {
                    //如果满足条件则返回资源
                    return resource;
                }
            }
            catch (Exception ex) {
            }
            //如果不满足条件就返回空
            return null;
        }    
}
2.存放主页到根目录下
2-1 主页存放位置

在这里插入图片描述

2-2 编写index.html主页
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>首页</h1>
</body>
</html>
2-3 主页访问测试

在这里插入图片描述

2-4 测试结论

结论直接存放在根目录不能直接访问!

3.存放主页到templates文件下
3-1 主页存放位置

在这里插入图片描述

3-2 编写index.html主页

与2-2中的主页代码相同

3-3 编写IndexControlller控制类
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//在templates目录下的所有页面,只能通过controller来跳转
//这个需要模板应请支持:thymeleaf
//使用@Controller注解来实现Controller接口
@Controller
public class IndexController {
    //真实访问路径为:http://loclahost:8080/index
    //使用@RequestMapping注解,设置请求映射路径
    @RequestMapping("/goIndex")
    public String index() {
        //返回的视图逻辑名
        return "index";
    }
}
3-3 主页访问测试
  • 直接访问主页

在这里插入图片描述

结果访问失败,可能需要通过控制器来访问主页!

  • 使用goIndex请求访问

在这里插入图片描述

结果仍然访问失败,应该是为导入模板引擎 (thymeleaf) 的资源jar包所导致的 !

4.存放index.html主页到static文件下
4-1 主页存放位置

在这里插入图片描述

4-2 编写index.html主页

与2-2主页代码相同

4-3 编写IndexController控制类

与3-3控制类代码相同

4-4 测试结果
  • 直接访问主页

    结果访问成功!同时也印证了之前说的,可以把大家都会访问的资源放在static文件下

  • 通过goIndex请求访问

在这里插入图片描述

结果访问主页失败!应该是视图逻辑名拼接出了问题,因为我们并不清楚SpringBoot中视图解析器如何处理返回的视图逻辑名

5.定制图标
5-1 图标存放位置

在这里插入图片描述

5-2 编写application.properties配置文件
# 关闭默认图标
spring.mvc.favicon.enabled=false

新版SpringBoot已经不支持favicon了,不过可以在html的link标签中实现

5-3 编写index.html主页
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="icon" href="/favicon.ico">
</head>
<body>
<h1>首页</h1>
</body>
</html>
5-4 测试结果

在这里插入图片描述

结果定制图标成功!


好了,今天的有关 SpringBoot基础学习之SpringBoot Web开发(上篇) 的学习就到此结束啦,欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连,我们下期见,拜拜啦!


参考视频链接:https://www.bilibili.com/video/BV1PE411i7CV(【狂神说Java】SpringBoot最新教程IDEA版通俗易懂)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔の蜗牛rz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值