因为项目要求用springMvc,但是默认以war包发布到tomact下每一次启动都会很慢,所以希望能用一个嵌入式的web容器,了解到undertow对于小型项目还不错,就使用了undertow.最开始用的Jfinal-undertow,但是突然看到出了spring6.0,就想体验一下,spring6.0对应的servlet版本比较高,jfinal-undertow并不兼容,所以就自己找到了undertow进行使用,以下就是折腾的经历。

1. 依赖安装


<!-- https://mvnrepository.com/artifact/io.undertow/undertow-servlet -->
<dependency><groupId>io.undertow</groupId><artifactId>undertow-servlet</artifactId><version>2.3.3.Final</version>
</dependency><!-- https://mvnrepository.com/artifact/io.undertow/undertow-core -->
<dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>2.3.3.Final</version>
</dependency>

在项目原本的依赖下加入以上两个依赖,版本需要对应一样,分别是undertow的核心依赖和undertow的servlet相关实现。

2. 运行整合

2.1 添加servlet

// 创建servletInfo,指定servlet的命名和servlet对应的class
ServletInfo info = new ServletInfo("mvc", DispatcherServlet.class)// 添加映射路径.addMapping("/")// 设置InitParam,制定了spring-mvc的配置文件位置.addInitParam("contextConfigLocation","classpath:spring-config/spring-mvc.xml")// 设置什么时候进行初始化.setLoadOnStartup(1);

2.2 创建容器

undertow的一个web容器就是一个DeploymentManager,该接口的默认实现类就是DeploymentManagerImpl,然后需要两个参数,分别是DeploymentInfoServletContainer,所以需要先创建DeploymentInfo,然后创建ServletContainer,因为ServletContainer也需要DeploymentInfo作为参数,代码如下所示。

// 创建DeploymentInfo 对象
DeploymentInfo deploymentInfo = new DeploymentInfo()// 指定类加载器.setClassLoader(TestServer.class.getClassLoader())// 设置contextPath.setContextPath("/")// 设置容器名称.setDeploymentName("myUndertow")// 设置初始化参数,制定了spring的配置文件的位置.addInitParameter("contextConfigLocation","classpath:spring-config/spring.xml")// 设置了一个监听器,用于初始化spring.addListener(new ListenerInfo(ContextLoaderListener.class))// 添加servlet.addServlet(info)// 添加一个过滤器,放置乱码问题.addFilter(new FilterInfo("Encoding", CharacterEncodingFilter.class).addInitParam("encoding","utf-8"));// 创建一个ServletContainer,并添加deploymentInfoServletContainerImpl container = new ServletContainerImpl();container.addDeployment(deploymentInfo);// 创建一个DeploymentManagerImplDeploymentManagerImpl manager = new DeploymentManagerImpl(deploymentInfo, container);// 部署该容器,一定要部署否则会报各种空指针manager.deploy();```## 2.3 添加HttpHandler因为是web项目,所以使用HttpHandler,HttpHandler默认有很多实现类,这里使用了最好理解的**PathHandler**,创建完之后添加到**Undertow**的Builder参数中,作为一个Listener,然后启动Undertow。```java
// 创建一个PathHandler,然后添加一个前缀匹配,DeploymentManagerImpl 调用start方法后会返回一个HttpHandler类型
PathHandler root = new PathHandler().addPrefixPath(deploymentInfo.getContextPath(), manager.start());
// 创建一个Undertow对象并配置启动的端口等参数,然后调用start方法启动
Undertow.Builder builder = Undertow.builder().addHttpListener(port, host, root);
Undertow undertow = builder.build();
undertow.start();
logger.info("  the undertow success listen http://"+host+":"+port);

2.4 读取配置文件

我也希望向springBoot项目一样可以直接读取端口等参数直接启动,但是因为容器运行时spring容器还没有运行,所以我才用的方法是手动读取文件并注入字段。

    public void initConfig(String configPath) throws IllegalAccessException {if (configPath.equals("")){configPath = "config/application.yml";}// 读取yaml文件并转换为proppertiesYamlPropertiesFactoryBean propertiesFactoryBean = new YamlPropertiesFactoryBean();propertiesFactoryBean.setResources(new ClassPathResource(configPath));// 配置log4j基本信息PropertyConfigurator.configure(propertiesFactoryBean.getObject());// 读取当前类的字段Field[] fields = this.getClass().getDeclaredFields();for (Field field:fields) {// 检查是否包含Value注解if (field.getAnnotation(Value.class) != null) {String value = field.getAnnotation(Value.class).value();value = value.substring(2).substring(0, value.length() - 3);// 注入参数field.set(this,propertiesFactoryBean.getObject().get(value));}}}@Value("${server.host}")public String host;@Value("${server.port}")public Integer port;

3. 最后

完整代码如下

    package org.gjs;import io.undertow.Undertow;import io.undertow.server.handlers.PathHandler;import io.undertow.servlet.UndertowServletMessages;import io.undertow.servlet.api.DeploymentInfo;import io.undertow.servlet.api.FilterInfo;import io.undertow.servlet.api.ListenerInfo;import io.undertow.servlet.api.ServletInfo;import io.undertow.servlet.core.DeploymentImpl;import io.undertow.servlet.core.DeploymentManagerImpl;import io.undertow.servlet.core.ManagedServlet;import io.undertow.servlet.core.ServletContainerImpl;import io.undertow.servlet.handlers.ServletHandler;import io.undertow.servlet.handlers.ServletInitialHandler;import io.undertow.servlet.handlers.ServletPathMatches;import io.undertow.servlet.spec.ServletContextImpl;import jakarta.servlet.ServletException;import org.apache.log4j.Logger;import org.apache.log4j.PropertyConfigurator;import org.gjs.config.MyUndertowConfig;import org.springframework.beans.factory.annotation.Value;import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;import org.springframework.core.io.ClassPathResource;import org.springframework.http.server.reactive.UndertowHttpHandlerAdapter;import org.springframework.web.context.ContextLoaderListener;import org.springframework.web.filter.CharacterEncodingFilter;import org.springframework.web.servlet.DispatcherServlet;import java.lang.reflect.Field;public class TestServer {private final Logger logger = Logger.getLogger(this.getClass());public static void main(String[] args) throws ServletException, IllegalAccessException {TestServer server = new TestServer();server.initConfig("");server.start();}public void initConfig(String configPath) throws IllegalAccessException {if (configPath.equals("")){configPath = "config/application.yml";}YamlPropertiesFactoryBean propertiesFactoryBean = new YamlPropertiesFactoryBean();propertiesFactoryBean.setResources(new ClassPathResource(configPath));// 配置log4j基本信息PropertyConfigurator.configure(propertiesFactoryBean.getObject());Field[] fields = this.getClass().getDeclaredFields();for (Field field:fields) {if (field.getAnnotation(Value.class) != null) {String value = field.getAnnotation(Value.class).value();value = value.substring(2).substring(0, value.length() - 3);field.set(this,propertiesFactoryBean.getObject().get(value));}}}@Value("${server.host}")public String host;@Value("${server.port}")public Integer port;public  void start() throws ServletException {ServletInfo info = new ServletInfo("mvc", DispatcherServlet.class).addMapping("/").addInitParam("contextConfigLocation","classpath:spring-config/spring-mvc.xml").setLoadOnStartup(1);DeploymentInfo deploymentInfo = new DeploymentInfo().setClassLoader(TestServer.class.getClassLoader()).setContextPath("/").setDeploymentName("myUndertow").addInitParameter("contextConfigLocation","classpath:spring-config/spring.xml").addListener(new ListenerInfo(ContextLoaderListener.class)).addServlet(info).addFilter(new FilterInfo("Encoding", CharacterEncodingFilter.class).addInitParam("encoding","utf-8"));ServletContainerImpl container = new ServletContainerImpl();container.addDeployment(deploymentInfo);DeploymentManagerImpl manager = new DeploymentManagerImpl(deploymentInfo, container);manager.deploy();PathHandler root = new PathHandler().addPrefixPath(deploymentInfo.getContextPath(), manager.start());Undertow.Builder builder = Undertow.builder().addHttpListener(port, host, root);Undertow undertow = builder.build();undertow.start();logger.info("  the undertow success listen http://"+host+":"+port);}}

springMvc整合undertow容器相关推荐

  1. 六:Dubbo与Zookeeper、SpringMvc整合和使用

    DUBBO与ZOOKEEPER.SPRINGMVC整合和使用 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架 ...

  2. 【转】Dubbo_与Zookeeper、SpringMVC整合和使用(负载均衡、容错)

    原文链接:http://blog.csdn.net/congcong68/article/details/41113239 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服 ...

  3. Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)(转)

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...

  4. 实战_02_Spring SpringMVC 整合Mybaits

    接上一篇:企业实战_01_Spring SpringMVC 整合Mybaits https://blog.csdn.net/weixin_40816738/article/details/101343 ...

  5. SpringMVC(2)—SpringMVC整合Spring的HelloWorld

    一.这是一个SpringMVC框架的案例HelloWorld 功能:HelloWorld 二.SpringMVC运行流程 1.流程 请求-->springDispatcherServlet的ur ...

  6. 【JEECG dubbo专题】Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...

  7. 转:Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)

    Dubbo与Zookeeper.SpringMVC整合和使用(负载均衡.容错) 标签: Dubbospringmvczookeeper负载均衡 2014-11-14 08:14 83517人阅读 评论 ...

  8. Spring和SpringMVC整合

    Spring和SpringMVC整合出现的问题: 原因 SpringMVC就运行在Spring环境之下,为什么还要整合呢?SpringMVC和Spring都有IOC容器,是不是都需要保留呢? 通常情况 ...

  9. 160906、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)

    互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...

最新文章

  1. R语言广义线性模型泊松回归(Poisson Regression)模型
  2. 解决报错:Can't read private key和./build-aux/cksum-schema-check: Permission denied
  3. IBM copy service--flashcopy 实验
  4. 步入三十岁前的总结:看似经历很多得到很多,但,实际却一无所得
  5. Django - 两周从入门到熟练工
  6. 超越java jb51_.net mvc超过了最大请求长度的解决方法
  7. 浙江大学 计算机学院 秦青青,我院研究生在乒乓球大赛中喜获佳绩
  8. 使用FFTW的fftw_plan_dft_c2r_1d()由于未归一化结果错误的解决方案
  9. 解决在极光推送的时候会出现一个 JPush提示:缺少统计代码
  10. Dirichlet分布深入理解
  11. 5、maplotlib中的轴刻度和轴线
  12. maven内存不足:Unexpected error occurred: Not enough memory to allocate buffers for rehashing Java heap
  13. 使用Altium Designer绘制电路原理图
  14. MATLAB-二次曲面
  15. 概率论:古典概型与伯努利概型
  16. Android仿微信图片编辑处理:文字,马赛克,裁剪,涂鸦,旋转图片等
  17. 现代网络负载均衡和代理技术
  18. js之浏览器本地存储webstorage
  19. 【Typora Emoji 图标】
  20. 数控车椭圆编程实例带图_数控车床加工椭圆的宏程序实例

热门文章

  1. 毛星云opencv之ROI图像叠加混合--5.2.1(定义ROI区域的方法)
  2. Hive sql 行转列
  3. 数据结构——冒泡算法
  4. 对不起, 老师 我把知识还给您了 呜呜呜 ......面试杀手-double精度问题深入剖析 进制转换
  5. Unity源码3||秀翻同学和老师
  6. 教育部 计算机类专业代码,科普下2020教育部703个本科专业目录及专业代码
  7. 免费的SSL证书(Let‘s Encrypt / acme)
  8. html,jsp和js的区别
  9. android手势解锁说明
  10. Springboot 2.0默认连接池HikariCP详解(效率最高)