欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot起飞系列-配置嵌入式Servlet容器(八)

程序员文章站 2022-04-18 11:25:08
一、前言 springboot中默认使用的是tomcat容器,也叫做嵌入式的servlet容器。因为它和我们平常使用的tomcat容器不一样,这个tomcat直接嵌入到的springboot,平常我们使用tomcat容器是一个独立的应用,配置的时候需要在tomcat中的xml中配置,而使用sprin ......

一、前言

springboot中默认使用的是tomcat容器,也叫做嵌入式的servlet容器。因为它和我们平常使用的tomcat容器不一样,这个tomcat直接嵌入到的springboot,平常我们使用tomcat容器是一个独立的应用,配置的时候需要在tomcat中的xml中配置,而使用springboot就不一样了,本文我们来学习怎么配置和替换servlet容器、以及注册传统的servlet组件。

二、自定义servlet容器的相关配置

2.1 修改配置文件的值

我们可以在application.properties中按照传统的配置方式设置,如下:

server.port=8081
server.context-path=/crud

server.tomcat.uri-encoding=utf-8

//通用的servlet容器设置
server.xxx
//tomcat的设置
server.tomcat.xxx

其中server开头的是web容器统一的配置,因为我们以后可以使用其他的web容器,带tomcat的是特定为tomcat容器的配置。

2.2 编码方式配置

编写一个embeddedservletcontainercustomizer:嵌入式的servlet容器的定制器,来修改servlet容器的配置。我们可以添加一个myserverconfig类,用注解的方式来配置我们的server配置。

 1 package com.example.demo.config;
 2 
 3 import org.springframework.boot.web.server.configurablewebserverfactory;
 4 import org.springframework.boot.web.server.webserverfactorycustomizer;
 5 import org.springframework.context.annotation.bean;
 6 import org.springframework.context.annotation.configuration;
 7 
 8 
 9 @configuration
10 public class myserverconfig {
11 
12     @bean
13     public webserverfactorycustomizer embeddedservletcontainercustomizer(){
14         return new webserverfactorycustomizer<configurablewebserverfactory>() {
15             @override
16             public void customize(configurablewebserverfactory factory) {
17                 factory.setport(8085);
18             }
19         };
20     }
21 }

启动之后我们就把端口设置到了8085。

三、注册servlet三大组件(servlet、filter、listener)

由于springboot默认是以jar包的方式启动嵌入式的web服务器来启动springboot应用,没有web.xml文件。传统情况下我们配置三大组件都是在web.xml中添加配置,现在就不能这么做了。

3.1 注册servlet

我们使用servletregistrationbean类来往容器中添加servlet组件,在myserverconfig中添加一个方法:

1     @bean
2     public servletregistrationbean myservlet(){
3         servletregistrationbean registrationbean = new servletregistrationbean(new myservlet(),"/myservlet");
4         return registrationbean;
5     }

添加一个myservlet类来处理/myservlet的请求:

1 public class myservlet extends httpservlet {
2     protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
3         response.getwriter().write("hello,my servlet");
4     }
5 
6     protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {
7         this.dopost(request, response);
8     }
9 }

启动后浏览器访问http://localhost:8085/myservlet,被我们的myservlet接管处理,因为配置的时候我们要处理的urlpatterns是/myservlet。

3.2 注册filter

一样的原理,我们使用filterregistrationbean类来往容器中添加filter组件:

1     @bean
2     public filterregistrationbean myfilter(){
3         filterregistrationbean registrationbean = new filterregistrationbean();
4         registrationbean.setfilter(new myfilter());
5         registrationbean.seturlpatterns(arrays.aslist("/hello","/myservlet"));
6         return registrationbean;
7     }

添加一个myfilter的类来处理映射的url:

 1 @webfilter(filtername = "myfilter")
 2 public class myfilter implements filter {
 3     public void destroy() {
 4     }
 5 
 6     public void dofilter(servletrequest req, servletresponse resp, filterchain chain) throws servletexception, ioexception {
 7         resp.getwriter().write("hello,my filter");
 8         chain.dofilter(req, resp);
 9     }
10 
11     public void init(filterconfig config) throws servletexception {
12 
13     }
14 
15 }

3.3 注册listener

使用servletlistenerregistrationbean类来往容器中添加listener组件:

1     @bean
2     public servletlistenerregistrationbean mylistener(){
3         servletlistenerregistrationbean<mylistener> registrationbean = new servletlistenerregistrationbean<>(new mylistener());
4         return registrationbean;
5     }

添加一个mylistenner的类来处理逻辑:

 1 public class mylistener implements servletcontextlistener {
 2     @override
 3     public void contextinitialized(servletcontextevent sce) {
 4         system.out.println("contextinitialized...web应用启动");
 5     }
 6 
 7     @override
 8     public void contextdestroyed(servletcontextevent sce) {
 9         system.out.println("contextdestroyed...当前web项目销毁");
10     }
11 }

这就是我们注册传统三大组件的方法。

有了以上的基础,我们就可以看一下,其实springboot为我们启动springmvc的时候也是通过这种方式注册了dispatcherservlet,这就是我们springmvc中核心的servlet。

 1 @bean(name = default_dispatcher_servlet_registration_bean_name)
 2 @conditionalonbean(value = dispatcherservlet.class, name = default_dispatcher_servlet_bean_name)
 3 public servletregistrationbean dispatcherservletregistration(
 4       dispatcherservlet dispatcherservlet) {
 5    servletregistrationbean registration = new servletregistrationbean(
 6          dispatcherservlet, this.serverproperties.getservletmapping());
 7     //默认拦截: /  所有请求;包静态资源,但是不拦截jsp请求;   /*会拦截jsp
 8     //可以通过server.servletpath来修改springmvc前端控制器默认拦截的请求路径
 9     
10    registration.setname(default_dispatcher_servlet_bean_name);
11    registration.setloadonstartup(
12          this.webmvcproperties.getservlet().getloadonstartup());
13    if (this.multipartconfig != null) {
14       registration.setmultipartconfig(this.multipartconfig);
15    }
16    return registration;
17 }

四、总结

这次我们学些了怎样注册传统的三大组件,虽然用到的机会可能不会那么多了,但是springboot的设计理念还是很好的。