目录
注:要使三大组件生效,还需在主启动类(被@SpringBootApplication注解标注的类)中扫描注解
1.内置容器
1.1 内置容器配置
SpringBoot内置了Tomcat,Jetty,Undertow三种web容器,默认使用Tomcat
1.2 切换容器:
在pom.xml文件中剔除Tomcat容器后再新增容器
<!-- 在SpringBoot的起步依赖中插入exclusion标签剔除Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
替换并新增jetty容器
<!--增加jetty starter依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
替换并新增undertow
<!-- 添加undertow依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
2.SpringMvc支持
2.1 静态资源
springBoot默认的静态资源设置类ResourceProperties
优先级分别为:
"classpath:/META-INF/resources/", >"classpath:/resources/", >"classpath:/static/", > "classpath:/public/"
- 静态资源加前缀,以防止与Controller的访问路径冲突
-
- spring.mvc.static-path-pattern="/aaa/**"(按照优先级依次寻找资源)
- 固定static下为静态资源存放位置
-
- spring.resource.static-locations=classpath:/static/
- 配置类的方式给访问静态资源加前缀
@Configuration
public class AppConfig implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
//该代码表示所有以bbb为前缀的请求,都会被静态资源拦截并从static文件夹下寻找资源
registry.addResourceHandler("/bbb/**).adResourceLocation("classpath:/static/")
}
}
- 自定义静态资源存放目录
-
- spring.resource.static-locations=classpath:/c64/
2.2设置首页
直接在默认的静态资源存放位置下存放一个index.html即可,自定义的静态资源存放位置也OK
2.3网站logo设置
将ico的文件放置到静态资源存放位置即可,命名必须为favicon.ico
2.4 视图解析器
如果不做任何配置,webapps文件夹的所有文件都不会被编译到target/classes目录下的,更不会被打包到jar包中.这个时候则需要再pom.xml文件的build标签(如果没有就新增)中新增两个resource标签,分别用于打包src/main/webapps资源文件夹与src/main/resource资源文件夹
<build>
<resources>
<resource>
<directory>src/main/webapps</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resource</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</build>
随后在application.properties文件中配置视图解析器的前缀和后缀
spring.mvc.view.prefix=前缀
spring.mvc.view.suffix=后缀
3.拦截器
依赖于web框架,本质是oop面向切面编程,只拦截controller层的请求
常见的应用场景:
- 权限检查
- 日志记录:记录请求的重要信息
- 性能监控:记录请求进入处理器的开始时间和结束时间,从而得到该请求的耗时
- 通用行为:读取cookie,获取用户信息
public class MyIntercept implements HandlerInterceptor {
// Controller方法处理之前【也就是路径跳转之前】;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//System.out.println("LoginInterceptor exec preHandle");
return true;
}
/**
* 调用条件:preHandle返回true
* 调用时间:Controller方法处理完之后,前端控制器(DispatcherServlet)进行视图渲染前
* 可以对ModelAndView进行操作
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//System.out.println("LoginInterceptor exec postHandle");
}
/**
* 调用前提:preHandle返回true
* 调用时间:DispatcherServlet进行视图的渲染之后
* 应用场景:多用于清理资源,统一日志处理,统一异常处理
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//System.out.println("LoginInterceptor exec afterCompletion");
}
}
创建完自定义拦截器后,记得在配置类中将其注册
/**
* 自定义拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加自己添加的拦截器,并拦截所有请求
registry.addInterceptor(new MyIntercept()).addPathPatterns("/**");
}
4.三大Web组件
4.1 servlet
//使用注解表明此类为servlet,配置访问路径和name值
@WebServlet(urlPatterns = "/myServlet",name = "myServlet")
public class MyServlet extends HttpServlet {
//service方法为,无论是post还是get请求,都能进入此方法,并不特定为某种访问方式
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.write("<h1>my servlet</h1>");
out.flush();
out.close();
}
}
4.2 监听器
监听web中的一些特定事件,主要的应用场景:监听session会话获取在线人数,监听客户端请求的ServletRequest来获取用户的一些信息
/**
*监听器
*/
@WebListener()
public class MyListener implements ServletRequestListener {
//在一个ServletRequest被销毁(即处理完请求并准备发送响应之后)时被调用
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("销毁");
}
//方法会在一个ServletRequest被初始化(即收到一个新的HTTP请求)时被调用
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request= (HttpServletRequest)sre.getServletRequest();
StringBuffer requestURL= request.getRequestURL();
String requestURI= request.getRequestURI();
String remoteAddr = request.getRemoteAddr();
System.out.println("requestURL: "+requestURL);
System.out.println("requestURI: "+requestURI);
System.out.println("remoteAddr: "+remoteAddr);
System.out.println("初始化(请求对象创建)");
}
}
4.3 过滤器
通过过滤器对Web的资源静态html文件,静态图片jsp servlet等进行拦截,过滤器还适用于对用户请求和响应对象进行检查和修改
filter的生命周期分为三个阶段:实例化,初始化,销毁
//urlPatterns为需要过滤的请求
@WebFilter(filterName = "MyFilter",urlPatterns = "/test")
public class MyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("MyFilter doFilter exec ... ");
chain.doFilter(req, resp);//放行
}
public void init(FilterConfig config) throws ServletException {
}
}
注:要使三大组件生效,还需在主启动类(被@SpringBootApplication注解标注的类)中扫描注解
@SpringBootApplication
@ServletComponentScan("com.bdqn.c55.web") //需要扫描的包名
public class 类名 {
4.4 过滤器和拦截器的区别
- 过滤器是基于函数回调的,拦截器是基于servlet容器的
- 过滤器可以过滤几乎所有请求,但是拦截器只能拦截controller层的
- 拦截器可以访问action上下文,值栈里的对象,而过滤器不能访问
- 在controller的生命周期中,过滤器只能在容器初始化时被调用一次,拦截器可以多次被调用
- 拦截器可以获取IOC容器中的各种bean,根据需求进行业务处理,但是过滤器不支持这一点。
4.5 采用配置类的方式注入组件
场景:如若我们使用的servlet等组件是第三方的,jar包中是只读,无法添加注解的,也就无法进行注解扫描,这个时候就得使用配置类的方式
//装配servlet
@Bean
ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean servletRegistrationBean= new ServletRegistrationBean(new MyServlet(),"/myservlet");
return servletRegistrationBean;
}
//装配filter
@Bean
FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean= new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.setUrlPatterns(Arrays.asList("/test"));
return filterRegistrationBean;
}
//装配监听器
@Bean
ServletListenerRegistrationBean servletListenerRegistrationBean(){
ServletListenerRegistrationBean registrationBean= new ServletListenerRegistrationBean(new MyListener());
return registrationBean;
}