SpringBoot入门篇 02、SpringBoot Web开发

简介: SpringBoot入门篇 02、SpringBoot Web开发

前情回顾以及问题解决


回顾一下之前学习的内容


我们使用springboot之后就是一个个jar包,内置了一个tomcat服务器,所以我们运行jar包就能够直接运行!不用再放置到webapp下。


自动装配:springboot到底在启动时给我们配置了什么?我们能不能对其配置进行修改?是否能够进行扩展?


@xxxAutoConfiguration:向容器中自动配置组件

@xxxProperties:自动配置类,装配配置文件中自定义的一些内容

紧接着进入web开发部分需要解决的问题,版本springboot2.4.1


导入静态资源

初始运行访问是一个error页面,定制一个首页

不推荐使用jsp,使用模板引擎Thymeleaf

装配扩展SpringMVC

增删改查

拦截器

国际化


一、静态资源


SpringBoot默认为我们提供了静态资源的处理,其通过配置类WebMvcAutoConfiguration实现的。此类存放了与web开发相关的各种配置属性和方法。


我们通过下面源码的阅读即可知道静态能够放置的路径


我们定位到 WebMvcAutoConfiguration类中的WebMvcAutoConfigurationAdapter这个内部类:


// on the classpath
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class,
      org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
  ...
    @Override
    //addResourceHandlers()方法对静态资源路径作出了默认的处理
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
    logger.debug("Default resource handling disabled");
    return;
    }
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
            //方式一:查看/webjars/**路径下是否有资源
    if (!registry.hasMappingForPattern("/webjars/**")) {
    customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/")
      .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)
      .setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
    }
            //方式二:staticPathPattern="/**"
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    if (!registry.hasMappingForPattern(staticPathPattern)) {
                //this.resourceProperties.getStaticLocations()可以得到静态资源路径
    customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
      .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
      .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)
      .setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
    }
  }



从源码中我们可以看到两处访问路径,那这两处访问路径都代表着什么含义呢?我们往下看


第一种:/webjars/**

我们把这一段拿下来看,可以看到/webjars/**下面添加了对应的资源路径classpath:/META-INF/resources/webjars/,简单来说就是我们在网页中访问/webjars/**就能够映射到classpath:/META-INF/resources/webjars/


if (!registry.hasMappingForPattern("/webjars/**")) {
    customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/")
      .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)
      .setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
  }


接下来问题来了,classpath:/META-INF/resources/webjars/指的是我们项目中哪里?


首先我们先来了解一下webjars是什么?


WebJars是将这些通用的Web前端资源打包成Java的Jar包,然后借助Maven工具对其管理,保证这些Web资源版本唯一性,升级也比较容易。

WebJars的官网:https://www.webjars.com/

我们从官网上拿来下一段jquery的jar包依赖,放入到pom.xml中使用Maven管理:


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


接着我们看向External Libaries中的jar包:



看上图我们就能够很清晰的看到classpath:/META-INF/resources/webjars/就是指代的第三方jar包下使用webjars打包的jar包路径。


此时我们看能否访问到该路径下的jquery.js资源,我们启动springboot来进行访问:


访问成功!这里的/webjars/映射到classpath:/META-INF/resources/webjars/里,之后添加对应的包名及资源名即可访问!!!



总结:第一种通过/webjars/**来指向对应jar包中(classpath:/META-INF/resources/webjars/)的静态资源,我们之后引入如jquery等js文件可以通过webjars打包的jar包来通过maven管理,并进行访问使用。


若是在springboot中使用jsp页面,我们导入如jquery只需要这样引入:


<script type="text/javascript" src="${pageContext.request.contextPath }/webjars/jquery/3.5.1/jquery.js"></script>


第二种:/**

我们继续看对应的第二部分代码:


//方式二:staticPathPattern="/**"
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
    //this.resourceProperties.getStaticLocations()可以得到静态资源路径
    customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                                        .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                         .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)
                                         .setUseLastModified(this.resourceProperties.getCache().isUseLastModified()));
}


①我们从何得知staticPathPattern="/**"?


我们点入this.mvcProperties.getStaticPathPattern()方法进入到WebMvcProperties类中的方法如下:


public String getStaticPathPattern() {
   return this.staticPathPattern;
}


//继续点击 依旧是WebMvcProperties类里的 this.staticPathPattern即可查看对应路径
private String staticPathPattern = "/**";


② 此时我们知道静态资源路径为/**,那么映射到本地路径哪里呢?


我们点击对应getStaticLocations()方法,进入到WebProperties类中的方法如下:


public String[] getStaticLocations() {
   return this.staticLocations;
}


// 继续点击到达  WebProperties类里的一个内部类Resources
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
//点击常量CLASSPATH_RESOURCE_LOCATIONS 依旧是Resouces类里 此时查看到对应映射路径
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };


分别是下面四个路径:


classpath:/META-INF/resources/:指的是第三方jar包中的资源

classpath:/resources/:指的是src/resources/resources

classpath:/static/:指的是src/resources/static/

classpath:/public/:指的是src/resources/public/



也就是我们通过/*即可访问到对应resources下三个目录的资源,其中static仅仅是创建工程默认自带给我们放置资源的。


启动项目来进行访问测试:直接/后面写资源名称即可映射到对应目录中,这里三个js中仅仅写数字来测试



③不同目录下其优先级是如何排序的?


我们通过测试,可以得知resources>static>public,分别按照优先级进行排序


自定义路径(不推荐)

我们知道这个WebMvcAutoConfiguration配置类是spring.factories中的,在启动类中会自动对其下的配置类进行自动配置



我们点进WebMvcAutoConfiguration中查看其内部类,上面的静态资源配置也是在这个适配器中



说了一大堆,进入正题,我们在第二种/**这个路径值的获取时就是通过这个WebMvcProperties这个类的一个属性获取:


@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
    ...
  private String staticPathPattern = "/**";
    ...
}


因为其是自动配置类,那么也就是说我们也可以通过yaml配置文件来进行配置其静态资源的路径了:


ok,我们在application.yaml配置文件中进行配置:


spring.mvc.static-path-pattern=/changlu/**


此时默认路径就像这里浏览器访问的一样了,我们已经修改了访问路径,试验一下:



说明:这里只是一种更改静态路径的方式,还有通过自定义静态资源映射类来进行更改,不过不推荐更改


总结

使用如下方式来处理静态资源


第一种:/webjars/**,浏览器访问localhost:8080/webjars/,对应第三方jar包下的classpath:/META-INF/resources/webjars/,可以去webjars官网获取依赖jar包


第二种:/**,浏览器访问localhost:8080/,对应四个路径下,/resources/resources /resouces/static /resources/public 以及classpath:/META-INF/resources/


其优先级为resources>static>public,默认项目会自带一个static目录


三个目录经常使用如下:


public:公共的资源

static:图片等等

resource:upload上传的文件

解决访问不了静态路径下的资源

我在static目录下添加了几个文件,接着我在浏览器中访问http://localhost:8080/css/bootstrap.css,就跳转了错误页面



解决方案:


使用maven自带的clean,清除一下,最好再清除一下浏览器缓存,再次访问即可解决!


二、自定义首页及favion


自定义首页

在springboot,也早就自定义好了默认的首页位置,我们往下看


依旧是在WebMvcAutoConfiguration的内部类EnableWebMvcConfiguration中:



这个内部类中使用了@Bean来自动注册WelcomePageHandlerMapping


/**
 * Configuration equivalent to {@code @EnableWebMvc}.
 */
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    @Bean
  public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
    FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
      new TemplateAvailabilityProviders(applicationContext), applicationContext,
                    //这里构造器的参数调用了这个方法,我们往下找
                    getWelcomePage(),
      this.mvcProperties.getStaticPathPattern());
    welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
    welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
    return welcomePageHandlerMapping;
  }
      private Optional<Resource> getWelcomePage() {
        //获取到四个静态资源默认路径,就是上面/**对应的资源路径
  String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
        //这里使用了jdk1.8新特性stream的map方法来进行合并路径也就是对应四个路径下,来进行依次访问
  return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
  }
  private Resource getIndexHtml(String location) {
            //例如classpath:/resources/index.html
    return this.resourceLoader.getResource(location + "index.html");
  }
    ...
}



也就是说我们只需要放置在对应/*映射的四个目录下即可进行访问对应的首页,访问localhost:8080/即可:



若是三个目录下都有index.html,那么对应的优先级如下:resource>static>public



这里扩展一下,在templates中放置index.html,如何访问?


这里的templates目录就相当于之前web项目里的web-inf目录中,只能通过controller来进行个跳转访问。


我们在templates中放入index.html,并且编写一个controller程序来测试一下:


//这里是返回modelandview , springboot已经帮我们将静态资源配置配好了
@Controller
public class HelloController {
    @RequestMapping("/")
    public String hello(){
        return "index";
    }
}


这还不够,要想访问templates目录中的资源,还需要添加thymeleaf依赖,我们导入pom.xml依赖:


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>


或者在创建springboot项目时进行选择模板:



接下来我们访问一下吧:localhost:8080/,即可自动访问到templates目录下的index.html(就算其他静态资源有index.html):



favion图标

对于springboot2.1.7版本,我们设置favion图标,我们仅仅需要在yaml配置文件中这样设置:


# 消除springboot初始图标
spring:
 favicon:
  enabled: false


接着将favion图标(.ico结尾)放在对应四个静态资源目录下即可生效


说明:Spring Boot项目的issues中提出,如果提供默认的Favicon可能会导致网站信息泄露


对应springboot 2.4.1,移除了图标


参考文章:(解答)SpringBoot从2.1.X过渡到2.2.X后,网站图标favicon.ico去哪了?


经过测试了之后,单独将favicon.ico的图标直接放置static目录下即可生效!!!


我们对需要图标的标签中添加如下内容即可获取:


<link rel="icon" href="assets/img/favicon.ico">


对应前后端分离,我们后端的本就不用去管前端的页面了!!!


相关文章
|
9天前
|
关系型数据库 MySQL
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
web简易开发(二){html5+php实现文件上传及通过关键字搜索已上传图片)}
|
3天前
|
前端开发 JavaScript Java
Java与Web开发的结合:JSP与Servlet
Java与Web开发的结合:JSP与Servlet
8 0
|
3天前
|
存储 程序员 API
python web开发示例详解
python web开发示例详解
12 0
|
3天前
|
XML 前端开发 JavaScript
CSR(客户端渲染)和AJAX在Web开发中各自扮演不同的角色
【5月更文挑战第8天】CSR(客户端渲染)与AJAX在Web开发中各司其职。CSR提供初始HTML框架,通过JavaScript在浏览器端获取并渲染数据,提升交互性和响应速度。AJAX则实现页面局部更新,如实时搜索,不刷新页面即可获取数据。CSR可能因DOM操作多而引发性能问题,但可优化解决;AJAX适合频繁交互场景,提高响应性。两者在不同需求下各有优势,需按项目选择适用技术。
13 4
|
3天前
|
前端开发 搜索推荐 安全
AJAX和CSR(客户端渲染)是Web开发中常用的两种技术
【5月更文挑战第8天】AJAX提升用户体验,减轻服务器压力,但对搜索引擎不友好且增加开发复杂度,易引发安全问题。CSR提供快速响应和交互性,改善用户体验,但首屏加载慢,搜索引擎支持不足,同样面临安全挑战。两者各有适用场景,需按项目需求选择。
10 0
|
4天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
45 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
4天前
|
前端开发 JavaScript 开发者
新一代前端框架:革命性的Web开发利器
传统的前端框架在满足日益复杂的Web开发需求上逐渐显露出局限性,而新一代前端框架的出现,以其革命性的设计和功能,重新定义了Web开发的标准。本文将介绍这些新一代前端框架的特点和优势,并探讨它们在实际项目中的应用。
|
6天前
|
安全 测试技术 PHP
掌握现代Web开发:PHP 8的新特性与最佳实践
【5月更文挑战第5天】 在当今快速发展的网络世界中,PHP作为一种流行的服务器端脚本语言,持续地演化着。最新的PHP 8版本引入了一系列令人兴奋的新特性和性能改进,为开发者提供了更加强大和灵活的工具。本文将深入探讨PHP 8中的新特性,包括联合类型、名称参数、匹配表达式等,并分享一些最佳实践,帮助开发者提高代码质量,优化性能,并确保安全性。通过这些实用技巧和示例,您将能够构建更高效、更安全的PHP应用程序。
|
10天前
|
Java 数据库连接 数据库
Springboot整合mybatisPlus开发
MyBatis-Plus是一个MyBatis的增强工具,旨在简化开发和提高效率。它在不修改原有MyBatis的基础上提供额外功能。要将MyBatis-Plus集成到SpringBoot项目中,首先通过Maven添加mybatis-plus-boot-starter和相应数据库驱动依赖,然后配置application.yml中的数据库连接信息,并指定Mapper类的扫描路径。Mapper接口可继承BaseMapper实现基本的CRUD操作。
|
10天前
|
前端开发 JavaScript Java
Springboot框架整合jsp开发【干货满满】
该文介绍了如何在Spring Boot中集成JSP,需包含`spring-boot-starter-web`、`tomcat-embed-jasper`和`jstl`三个依赖。配置Spring Boot寻找JSP的位置,设置`spring.mvc.view.prefix`为`/WEB-INF/jsp/`,`spring.mvc.view.suffix`为`.jsp`。JSP文件应放在`src/main/webapp/WEB-INF/jsp/`下。