茂展的分享博客

SpringBoot的难点总结

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就可以加载到
Jquery目录结构


分析 WebMvcAutoConfiguration

“/**”访问当前项目的任何资源(静态资源文件夹)

1
2
3
4
5
"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径

欢迎页; 静态资源文件夹下的所有index.html页面;被”/**”映射

访问 localhost/ 会首先找Index.html

所有的 **/favicon.ico 都是在静态资源文件下找;

SpringBoot自定义web配置文件以及拦截器

springboot1.x版本的时候我们会继承WebMvcConfigurerAdapter,但是在2.x版本以后被标注@Deprecated,表示这个方法再慢慢被其他用法给替代
所以我们使用实现WebMvcConfigurer,然后重写其方法

1
2
3
4
5
6
7
8
@Configuration
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
@Configuration
public class MyConfig implements WebMvcConfigurer{

public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
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
@Component
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
@Configuration
public class MyConfig implements WebMvcConfigurer{

@Autowired
private LoginInterceptor loginInterceptor;

public void addViewControllers(ViewControllerRegistry registry) {
//主要处理一些不需要直接操作,只需要映射地址的
registry.addViewController("/index").setViewName("index");
}

public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/test").setViewName("test");
}

// 按住ctrl+O
// springboot 1.x版本静态资源默认不拦截,但是2.x以后会拦截静态资源
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/**").
excludePathPatterns("/index","/login","/");
}
};
}
}

我使用的

1
2
@Autowired
private LoginInterceptor loginInterceptor;

注意
加载ioc容器中的拦截组件,然后registry.addInterceptor(loginInterceptor)加载,而不是使用

registry.addInterceptor(new loginInterceptor())方式,这种情况时,自定义的interceptor中不能注入其他内容,比

如redis或者其他service,如果要注入,必须使用上面这种方法

SpringBoot错误处理机制

查看源码 ErrorMvcAutoConfiguration类的使用
当访问后出现4XX或者5XX的错误的时候,会转发/error请求,然后查看静态文件夹有没有error文件夹,如果没有,根据请求的设备不同,会有不同的处理结果(默认错误页面)
检查设备是PC会返回html,其他设备返回json格式的数据

如何定制错误呢

  1. 有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的error文件夹下】,发生此状态码的错误就会来到 对应的页面;
    我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态
    码.html)

    页面能获取的信息;

    • timestamp:时间戳
    • status:状态码
    • error:错误提示
    • exception:异常对象
    • message:异常消息
    • errors:JSR303数据校验的错误都在这里
  2. 没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;

  3. 以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

定义错误页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//出现异常会进入这个类中的方法
@ControllerAdvice
public class MyException {


@ExceptionHandler(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
9
public class MyErrorAttributes extends DefaultErrorAttributes {

@Override
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
    8
    public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(TomcatDemoApplication.class);
    }

    }
  • 启动就可以使用了

springboot整合外置tomcat
我们也要配置静态资源的访问

1
2
spring.mvc.view.prefix=/WEB-INF/
spring.mvc.view.suffix=.jsp

------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶