说起用springboot框架web项目,我们在刚开始第一篇文章中新建的springboot项目就是web项目,这个是前后端分离的只做服务器端,那么我们能用springboot来开发一个前后台不分的web项目(如:spring MVC中那样前端都放在WEB-INF/目录下)吗?当然可以了,在下面我们就来看看springboot开发web项目的一些其他要点。
一.对静态资源的映射规则
springboot版本是2.1.1时这个类如下图,springboot版本是1.5.1时该类实现了ResourceLoaderAware
在这个类中可以设置和静态资源有关的参数,比如:缓存时间。
在WebMvcAutoConfiguration类中有这么一个方法:
1. /webjars/**
所有/webjars/**,都去classpath:/META-INF/resources/webjars/ 找资源。
webjars:以jar包的方式引入引入静态资源,参考webjars
例如:
引入到项目中,如下图:
所有/webjars/**,都去classpath:/META-INF/resources/webjars/ 找资源,如下图:
例如:重新启动项目,访问localhost:8080/webjars/jquery/3.3.1/jquery.js,响应页面如下,说明访问到了:
2. /**
/** 访问当前项目的任何资源,都去下面这些路径下找,这些文件夹都称为静态资源的文件夹,可以查看ResourceProperties类中的静态常量CLASSPATH_RESOURCE_LOCATIONS的值。
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/",
“/” :当前项目的根路径
我们在浏览器地址栏输入:localhost:8080/abc 会默认去上面这些资源文件夹里面找abc
注意:src/main/resource 是当前类路径的根路径,如下图所示:
例如:现在在类路径的static文件下放一个 test/js/requirejs.js 这样的文件夹,现在访问它。在浏览器中输入:localhost:8080/test/js/requirejs.js,查看响应页面如下,说明访问到了:
3.欢迎页
index.html
同样是在WebMvcAutoConfiguration类中,有个welcomePageHandlerMapping方法,如下图:
欢迎页:去找所有静态资源文件夹下的index.html页面,也被 /** 映射。localhost:8080 ——> 找index.html页面
例如: 在类路径的根目录下的public文件夹下新建一个index.html页面,如下
重启项目,接着在浏览器地址栏输入:localhost:8080/ ,查看响应页面如下图,说明访问到了我们刚才写的html页面:
4.配置喜欢的图标
**/favicon.ico
同样是在WebMvcAutoConfiguration类中,有个FaviconConfiguration 静态内部类。如下:
所有的 **/favicon.ico 都是在静态资源文件夹找
例如:在类路径下resource文件下放一个favicon.ico图标文件(这个图标是webjar官网的logo,把它重命名为favicon.ico)。
重启项目,在浏览器中输入:localhost:8080/,可以看到图标已经变了。如下图:
这些被映射的静态资源文件夹的位置也可以在配置文件application.properties(或者application.yml)中进行配置,例如:配置类路径下的hello文件夹和cdd文件夹,如下图:
二.模板引擎
JSP,Velocity,FreeMark,Thymeleaf等都是模板引擎。下面是模板引擎的工作原理图:
springboot推荐的Thymeleaf:语法更简单,功能更强大。接下来看看在springboot中如何使用thymeleaf。
1.引入thymeleaf依赖
可以参考springboot官方文档 ,如下图:
向pom文件中引入thymeleaf依赖,如下图:
2.thymeleaf使用&语法
我们先来看下ThymeleafProperties类,如下图:
只要我们把html页面放在 classpath:/templates/ 文件夹下,thymeleaf就能自动渲染。
使用,在html页面中。
(1).导入thymeleaf的名称空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
(2).使用thymeleaf语法
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功!</h1>
<!--th:text将div里面的文本内容设置为-->
<div th:text="${hello}">这是显示欢迎信息</div>
</body>
</html>
(3).语法规则
<1>.标签
th:text 改变当前元素里面的文本内容。
可以使用任意 th: 的html属性,例如: th:id。可以使用任意的th:html属性来替换原生html属性的值。
<2>.表达式
更多详情查看thymeleaf官网
Simple expressions:
Variable Expressions: ${...} 变量表达式
a.获取变量值,OGNL。能调用对象的属性;
b.能调用方法;能使用内置的基本对象。能使用的内置对象有:
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object.
c.内置的一些工具对象,如下:
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration)
Selection Variable Expressions: *{...} 选择表达式和${}在功能上是一样的
区别如下:
*{ }
${ }
${ } 和 *{ }混合使用
三.RestfulCRUD
1.默认访问首页
现在要访问静态资源中,模板文件夹中的登录首页,结构如下:
有两种方式进行配置:
(1). 方式一
在controller中进行配置,在controller包中新建一个HelloController类,代码如下:
package com.example.demo2.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
/**
* 方法一:
* 会默认去静态资源的模板文件夹中去找
* @return
*/
@RequestMapping({"/","/login.html"})
public String index(){
return "login";
}
}
启动项目,在浏览器地址栏输入:http://localhost:8080/ ,出现如下页面(就是我们的login.html的内容),说明这个默认首
首页生效了。
(2).方式二
扩展视图解析器,在config包中新建一个MyMvcConfig类,代码如下:
package com.example.demo2.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
/**
* 方法二:
* 添加视图解析映射,"/"映射到”login"页面;”index.html'映射到“login'页面
* 这里经过thymeleaf解析,会给login加上前后缀,去找到该页面
*
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
}
}
先把刚才HelloController里的index()方法注释掉,接着启动项目,在浏览器地址栏输入:http://localhost:8080/login.html,就会出现下面的页面,说明我们刚才写的配置类生效了。
2.国际化
- 编写国际化配置文件
- 使用ResourceBundleMeassageSource来管理国际化资源文件
- 可以在页面使用fmt:message取出国际化内容
(1).编写国际化配置文件
编写国际化配置文件,抽取页面需要显示的国际化消息,编写默认配置文件login.properties,中文配置文件login_zh_CN.properties,英文配置文件login_en_US.properties,如下图(是默认配置文件和中文配置文件内容):
英文的配置文件内容如下:
(2).springboot国际化自动配置
springboot自动配置好了管理国际化资源文件的组件。该类如下图,只截取了部分
在application.properties中配置这些国际化配置文件的路径,如下:
(3).获取国际化的值
去页面获取国际化的值,在静态资源文件的模板文件下login.html文件中修改,如下:
注意:文件编码一定要设置成UTF-8,不然会乱码
(4).查看效果
启动项目,在浏览器地址栏输入:localhost:8080,回车,出现页面如下:
在浏览器的设置里面语言设置成英语,这里我用的浏览器是谷歌,如下图:
接着再次刷新 localhost:8080页面,页面发生了变化,如下图,说明的我们的国际化配置成功了。
3.登录
(1).禁用模板缓存
开发期间模板引擎页面修改以后,要实时生效,则 禁用模板缓存,如下:
(2).登录错误消息显示
对login.html页面进行修改,修改部分如下:
在template文件夹中添加一个success.html页面,当用户名和密码校验通过后显示该页面,页面代码如下:
登录错误消息的显示,用thymeleaf表达式,在LoginController中的login方法中,添加一个map,代码如下:
接下来启动项目,在浏览器地址输入:localhost:8080,响应页面如下:
先输入,用户名:root,密码:123456,点击登录按钮,跳转到下面页面:
再次访问localhost:8080,这次把密码输错,输入,用户名:root,密码:11,点击登录按钮,没有登录成功弹出提示信息“用户名或密码错误”,如下:
4.CRUD
例如:我们现在要对student表进行增删改查,要用RestfulCRUD来实现。
RestfulCRUD: 要满足Rest风格
URI:/资源名称/资源标识
HTTTP请求方式区分对资源CRUD操作
对studen进行操作:
操作 |
普通CRUD(uri来区分操作) |
Restful的CRUD |
查询 |
getStudent |
GET请求方式 |
添加 |
addStudent |
POST请求方式 |
修改 |
updateStudent |
PUT请求方式 |
删除 |
deleteStudent |
DELETE请求方式 |
四.嵌入式Servlet容器
springboot默认使用tomcat作为嵌入式的Servlet容器。查看依赖关系图,如下:
1.如何定制和修改Servlet相关配置
(1).配置文件中修改
properties或yml文件中修改server有关的配置(ServerProperties类),如下:
(2).编写嵌入式Servlet容器的定制器
编写一个EmbeddedServletContainerCustomizer(低版本的springboot有该类,springboot2.0以后的用WebServerFactoryCustomizer):嵌入式Servlet容器的定制器,下面配置类中的webServerFactoryCustomizer()方法
package com.example.demo2.config;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
/**
* 方法二:
* 添加视图解析映射,"/"映射到”login"页面;”index.html'映射到“login'页面
* 这里经过thymeleaf解析,会给login加上前后缀,去找到该页面
*
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
}
/**
* 配置servlet容器的端口
* @return
*/
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
return new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(8081);
}
};
}
}
注:如果application.yml、application.properties,servlet容器定制器中都配置了端口,那么优先级从高到低依次是:
servlet容器定制器 、application.properties 、application.yml
2.注册三大组件(Servlet、Filter、Listener)
由于springboot默认是以jar包的方式启动嵌入式的Servlet容器来启动springboot的web应用,没有web.xml文件(之 前的web应用中带的配置文件),注册三大组件用以下方式:
(1).注册Servlet
编写一个Servlet,如下:
package com.example.demo2.config;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello MyServlet");
}
}
在MyMvcConfig类中添加servletRegistrationBean方法,配置该Servlet要处理的请求并且注册到容器中,如下:
(2).注册过滤器(Filter)
编写一个过滤器,代码如下:
package com.example.demo2.config;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("this is MyFilter");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
在MyMvcConfig类中添加filterRegistrationBean方法,把这个过滤器注册到容器中,如下:
(3).注册监听器(Listener)
编写监听器,代码如下:
package com.example.demo2.config;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("项目启动了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("项目销毁了");
}
}
在MyMvcConfig类中添加servletListenerRegistrationBean方法,把这个监听器注册到容器中,如下:
(4).原生例子
另外一个例子,springboot帮我们自动配置springMVC的时候,自动注册springMVC的前端控制器,DispatcherServlet
在DispatcherServletAutoConfiguration类中,以下方法往容器中注册了DispatcherServlet
到这里我们的springboot的web部分的学习记录就整理完了,该篇文章是我在观看尚硅谷的出的springboot教学视频后总结的,非常感谢尚硅谷的学习资料。有哪里不对的地方,还请各位大佬批评指正。