SpringBoot的难点总结
WebJars:以jar包的方式引入
例如jquery,我们可以这样引入1
2
3
4
5<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.0.0</version>
</dependency>
然后在目录结构是:
html中引入 /webjars/jquery/3.0.0/jquery.js就可以加载到
分析 WebMvcAutoConfiguration
“/**”访问当前项目的任何资源(静态资源文件夹)
1 | "classpath:/META‐INF/resources/", |
欢迎页; 静态资源文件夹下的所有index.html页面;被”/**”映射
访问 localhost/ 会首先找Index.html
所有的 **/favicon.ico 都是在静态资源文件下找;
SpringBoot自定义web配置文件以及拦截器
springboot1.x版本的时候我们会继承WebMvcConfigurerAdapter,但是在2.x版本以后被标注@Deprecated,表示这个方法再慢慢被其他用法给替代
所以我们使用实现WebMvcConfigurer,然后重写其方法1
2
3
4
5
6
7
8
public class MyConfig implements WebMvcConfigurer{
public void addViewControllers(ViewControllerRegistry registry) {
//主要处理一些不需要直接操作,只需要映射地址的
registry.addViewController("/index").setViewName("index");
}
}
当然我们也可以这样使用1
2
3
4
5
6
7
8
9
10
11
12
public class MyConfig implements WebMvcConfigurer{
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("test");
}
};
}
}
SpringBoot的拦截器
我们往往在操作前要校验权限,所以拦截器有必要使用
创建一个类,实现HandlerInterceptor接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String username = (String) request.getSession().getAttribute("username");
if(StringUtils.isEmpty(username)){
username = request.getParameter("username");
if(!StringUtils.isEmpty(username)){
request.getSession().setAttribute("username",username);
}
//没有输入username并且没有登录转发给登录页面
request.getRequestDispatcher("/index").forward(request,response);
return false;
}
return true;
}
}
我使用的是把拦截器注册到ioc容器中,这样防止以后我在拦截器中注入其他组件不能使用的问题1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MyConfig implements WebMvcConfigurer{
private LoginInterceptor loginInterceptor;
public void addViewControllers(ViewControllerRegistry registry) {
//主要处理一些不需要直接操作,只需要映射地址的
registry.addViewController("/index").setViewName("index");
}
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("test");
}
// 按住ctrl+O
// springboot 1.x版本静态资源默认不拦截,但是2.x以后会拦截静态资源
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").
excludePathPatterns("/index","/login","/");
}
};
}
}
我使用的1
2
private LoginInterceptor loginInterceptor;
注意:
加载ioc容器中的拦截组件,然后registry.addInterceptor(loginInterceptor)
加载,而不是使用
registry.addInterceptor(new loginInterceptor())
方式,这种情况时,自定义的interceptor中不能注入其他内容,比
如redis或者其他service,如果要注入,必须使用上面这种方法
SpringBoot错误处理机制
查看源码 ErrorMvcAutoConfiguration类的使用
当访问后出现4XX或者5XX的错误的时候,会转发/error请求,然后查看静态文件夹有没有error文件夹,如果没有,根据请求的设备不同,会有不同的处理结果(默认错误页面)
检查设备是PC会返回html,其他设备返回json格式的数据
如何定制错误呢
有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的error文件夹下】,发生此状态码的错误就会来到 对应的页面;
我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态
码.html);页面能获取的信息;
- timestamp:时间戳
- status:状态码
- error:错误提示
- exception:异常对象
- message:异常消息
- errors:JSR303数据校验的错误都在这里
没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;
- 以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;
定义错误页面1
2
3
4
5
6
7
8
9
10
11
12
13
14//出现异常会进入这个类中的方法
public class MyException {
(CustomException.class)
public String handleException(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","500");
map.put("message",e.getMessage());
return "forward:/error";
}
}
但是上面这一种不具有适配性,所以我们可以这样做1
2
3
4
5
6
7
8
9public class MyErrorAttributes extends DefaultErrorAttributes {
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
map.put("company","nyist");
return map;
}
}
SpringBoot嵌入式Servlet容器
优点: 简单、便携
缺点: 默认不支持JSP,优化定制比较复杂
我们可以外置的Servlet容器,然后我们可以这样做
- 创建成一个war项目
- 将嵌入式的tomcat设置成provided
必须编写一个类
1
2
3
4
5
6
7
8public class ServletInitializer extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TomcatDemoApplication.class);
}
}
- 启动就可以使用了
我们也要配置静态资源的访问1
2spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp