在springboot项目文件夹下我们找不到 web-app文件夹
我们该如何开发web-application
静态资源
前端页面
持久处理
静态资源
1、存放位置
在resources 目录下 为我们准备了 static 和 templates
static 用来存放静态资源
templates 用来存放模板文件
- templates
n. 模板;范本(template的复数);属性单元
1.2、源码分析
找到springmvc的自动装配类 WebMvcAutoConfiguration.class
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
ServletContext servletContext = this.getServletContext();
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (servletContext != null) {
registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
}
});
}
}
-
if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); }- 我们直译 如果属性配置类被加入到映射路径 默认资源处理关闭
- 当我们在配置文件中配置了自己的 静态资源路径那么默认资源路劲就会失效
-
this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");- 加入了一个资源处理器 路径为 /webjars/**
- **会映射到对应资源的webjars/下的路径
- 加入了一个资源处理器 路径为 /webjars/**
WebJars是将客户端(浏览器)资源(JavaScript,Css等)打成jar包文件,以对资源进行统一依赖管理。
我们访问官网为项目添加webjars的jquery 依赖
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
在项目的扩展库中可以发现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G8AFhYH6-1620568482718)(C:\Users\Xingcl\AppData\Roaming\Typora\typora-user-images\image-20210509125945082.png)]
-
如果我们要访问用webjars 管理的静态资源
- 可以使用 项目地址:项目端口/webjars/资源名/资源版本号/具体资源名
- localhost:8080/webjars/jquery/3.6.0/jquerys.js
- 大概就是 webjars/会映射到所有我们导入的webjars 静态资源的webjars路径下
-
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (servletContext != null) { registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")}); } });-
这里使用lamda 表达式还加入了一个 路径
-
通过源码深入我们发现了这样一个路径
this.staticPathPattern = "/**"; -
按照webjars 我们可以理解静态资源的路径是由方法
addResourceLocations的第二个字符串参数和第三个字符串参数拼接的 -
在第二个参数 我们发现了
-
new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/","classpath:/public/"}
-
-
-
-
那么/**应该就是映射到这四个路径下了 我们可以使用(就像直接映射到对应资源的webjars 目录)
- 主机名:端口号/资源名 需要保证资源存在在以上四个路径中
- localhost:8080/资源名
-
优先级
classpath:/resources/>classpath:/static/>classpath:/public/
网站主页
1、源码分析
private Resource getWelcomePage() {
String[] var1 = this.resourceProperties.getStaticLocations();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
String location = var1[var3];
Resource indexHtml = this.getIndexHtml(location);
if (indexHtml != null) {
return indexHtml;
}
}
ServletContext servletContext = this.getServletContext();
if (servletContext != null) {
return this.getIndexHtml((Resource)(new ServletContextResource(servletContext, "/")));
} else {
return null;
}
}
private Resource getIndexHtml(String location) {
return this.getIndexHtml(this.resourceLoader.getResource(location));
}
private Resource getIndexHtml(Resource location) {
try {
Resource resource = location.createRelative("index.html");
if (resource.exists() && resource.getURL() != null) {
return resource;
}
} catch (Exception var3) {
}
return null;
}
-
String[] var1 = this.resourceProperties.getStaticLocations();-
resourceLoader还是从我们的静态资源路径下去寻找首页-
this.getIndexHtml(location);(String)会走这个方法
-
到这
getIndexHtml(Resource location)
-
-
-
如果找不到会判断servlet上下文是否存在 如果存在会从上下文中寻找
-
return this.getIndexHtml((Resource)(new ServletContextResource(servletContext, "/")));
应该是用controller访问首页
ThymeLeaf
ThymeLeaf is a modern server-side Java template engine for both web and standalone environments.
它是一个流行的适合web和独立环境的服务器端java模板引擎
- 一个模板引擎
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sivyy9H1-1620568482720)(https://th.bing.com/th/id/R077a2428811b7e3d3674a80f87e827f4?rik=PUOwjN0my0S8YQ&riu=http%3a%2f%2fupload-images.jianshu.io%2fupload_images%2f8707272-8346cf5c4b91b284.png&ehk=2HTJTJjlnO5HubAAna0DDWE78diyB0tXUENMwvmrpEU%3d&risl=&pid=ImgRaw)]
- 将我们的数据装载到前端页面 (jsp被springboot摒弃了 )然后生成最后展示给用户的效果页面
1、依赖导入
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.5</version>
</dependency>
- 我们导入启动器
2、添加约束
xmlns:th="http://www.thymeleaf.org"
在前端页面使用 ThymeLeaf 的标签去取得数据
| 标签 | 作用 | 示例 |
|---|---|---|
| th:id | 替换id | <input th:id="${user.id}"/> |
| th:text | 文本替换 | <p text:="${user.name}">bigsai</p> |
| th:utext | 支持html的文本替换 | <p utext:="${htmlcontent}">content</p> |
| th:object | 替换对象 | <div th:object="${user}"></div> |
| th:value | 替换值 | <input th:value="${user.name}" > |
| th:each | 迭代 | <tr th:each="student:${user}" > |
| th:href | 替换超链接 | <a th:href="@{index.html}">超链接</a> |
| th:src | 替换资源 | <script type="text/javascript" th:src="@{index.js}"></script> |
-
<p th:text="${test}"></p>
还是类似springmvc 拼接前后缀
ThymeLeaf的标签能够绑定所有的html标签
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setApplicationContext(this.applicationContext);
resolver.setPrefix(this.properties.getPrefix());
resolver.setSuffix(this.properties.getSuffix());
resolver.setTemplateMode(this.properties.getMode());
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
- 拼接前缀
classpath:/templates/所以为了能够访问我们应该把页面文件放在templates路径下 - 后缀
.html
3、定义接口
@RequestMapping("/test")
public ModelAndView thymeleaf(ModelAndView model)
{
model.addObject("test","hello thymeleaf");
model.setViewName("test");
return model;
}
4、访问结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t8kGbLur-1620568482723)(C:\Users\Xingcl\AppData\Roaming\Typora\typora-user-images\image-20210509170008884.png)]
5、thymeleaf 的特点
5.1、动静分离
-
使用
html最为模板 但是有自己独有的标签 没有破坏html结构 -
无网络 不访问后端也能打开前端页面
- 我们打开jsp页面时如果 嵌套了一些引擎语句 那么我们的前端页面如果没有网络访问去后端是会 抛出错误码的 而且后端数据出错了也会抛出错误码
- **这个特点超级重要 ** 那么前端在测试一些东西时可以完全独立了
5.2、开箱即用
- Thymeleaf提供标准和Spring标准两种方言 直接套用模板实现JSTL、 OGNL表达式效果
6、语法
自定义和应用配置
在我们使用springboot开发web项目时 其实springboot 把 诸如 dispatcherServlet (前端控制器) viewResolver (视图解析器) 等之类的都作为组件装配到Ioc 容器中了,但是这并不意味着我们不能掌控这个过程了,如果对自动装配的原理了解,我们可以接管或者拓展 springmvc的组件。
2.1.1 发布的spring boot中文文档有这样一段话
如果您想保留 Spring Boot MVC 功能,并且想要添加其他MVC configuration(拦截器,格式化程序,视图控制器和其他功能)
可以添加自己的@Configuration类,类型为WebMvcConfigurer,但是 没有 @EnableWebMvc。如果希望提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明WebMvcRegistrationsAdapter实例以提供此类件。
如果要完全控制 Spring MVC,则可以添加自己的@Configuration并以@EnableWebMvcComments。
-
可以添加自己的配置类
-
@Configuration
- 自定义配置类需要该注解标注未配置类
-
@EnableWebMvc
- 使用该注解可以摒弃默认被注册的组件 使用自定义的组件接管
- 如果拓展请不要加上该注解
-
自定义的属性配置类一定是
WebMvcConfigurer(继承或实现)
2.4.5 的英文文档案中同样有这样一句
The easiest way to take complete control over MVC configuration is to provide your own @Configuration with the @EnableWebMvc annotation. Doing so leaves all MVC configuration in your hands.
接管springmvc 最简单的方法是使用 @Configuration 配合 @EnableWebMvc 注解提供你自己的
1、 自定义配置类
尝试自定义一个视图解析器
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.mvcProperties.getView().getPrefix());
resolver.setSuffix(this.mvcProperties.getView().getSuffix());
return resolver;
}
@Bean
@ConditionalOnBean({View.class})
@ConditionalOnMissingBean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(2147483637);
return resolver;
}
@Bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(
name = {"viewResolver"},
value = {ContentNegotiatingViewResolver.class}
)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
resolver.setOrder(-2147483648);
return resolver;
}
三个官方的视图解析器在这里装配
-
WebMvcAutoConfiguration -
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class, WebProperties.class})
2、自定义ViewRsolver
//实现视图解析器接口成为一个视图解析器
public class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
3、扩展配置类
@Configuration
//标记未配置类
//@EnableWebMvc
//接管springmvc配置
public class MyWebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver selfViewResolver() {
return new MyViewResolver();
}
//注册到Ioc容器中去
}
结果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8QDzJkRN-1620568482724)(C:\Users\Xingcl\AppData\Roaming\Typora\typora-user-images\image-20210509214203350.png)]
- 我们在dispatcherServlet中ViewResolver中找到了我们自定义的视图解析器
如果我们要接管需要定义很多属性 配合@EnableWebMvc
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
它导入了 DelegatingWebMvcConfiguration.class
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport
该类又继承了 WebMvcConfigurationSupport
会触发
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
专配该类需要满足没有WebMvcConfigurationSupport.class
所以当使用 @EnableWebMvc默认自动装配 类会失效
自定义的配置类会接管
本文介绍 Spring Boot 中 web 应用的开发方法,包括静态资源处理、前端页面配置及 Thymeleaf 模板引擎的使用。同时,探讨如何自定义配置类以增强项目的灵活性。
2409

被折叠的 条评论
为什么被折叠?



