解决SpringBoot webSocket 资源无法加载、tomcat启动报错的问题

 更新时间:2020年11月25日 10:58:59   作者:fyhju1  
这篇文章主要介绍了解决SpringBoot webSocket 资源无法加载、tomcat启动报错的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

问题描述:

1. 项目集成WebSocket,且打包发布tomcat时出现websocket is already in CLOSING or CLOSE state这样的问题,建议参考“解决方法二”,但是“解决方法一”请要了解查看 ,因为解决方法二是在一的基础上进行更正

2. 如果出现javax.websocket.server.ServerContainer not available这样的错误,请参考“解决方法一”中步骤3

解决方法一:(常规解决、不推荐)

步骤1:在BootApplication中修改:

public static void main(String[] args) {
		SpringApplication springApplication = new SpringApplication(BootApplication.class);
		springApplication.addListeners(new ApplicationPidFileWriter());
		ConfigurableApplicationContext applicationContext = springApplication.run(args);
		WebSocketServer.setApplicationContext(applicationContext);
	

注:这里的WebSocketServer是指你自定义的websocket接受消息的服务类

步骤2:修改WebSocketServer

private static ManageUserMapper manageUserMapper;
 
 public static void setApplicationContext(ConfigurableApplicationContext   applicationContext) {
  WebSocketServer.manageUserMapper = applicationContext.getBean(ManageUserMapper.class);
 }

步骤3: 修改pom.xml

由于我们在开发过程中,如果按照以上步骤1、2进行修改,一般不会出现问题,

但是如果我们打包发布tomcat,就会出现:javax.websocket.server.ServerContainer not available这样的错误,步骤3为常规解决一下问题方式

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<!-- 去除内嵌tomcat -->
			<exclusions>
				 <exclusion>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-tomcat</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

需要去除web-starter的tomcat,因为如果不去除会导致冲突,

如果出现这种问题,你还需要在websocketConfig中做如下修改:(websocket为自定义配置类)

/**
  * 服务器节点
  *
  * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
  * @return
  */
 @Bean
 @Profile("dev")
 public ServerEndpointExporter serverEndpointExporter() {
  return new ServerEndpointExporter();
 }

在application.properties做如下配置

##prod:生产环境 dev:开发环境(WINDOWS)
spring.profiles.active=dev

这里加入了@Profile("dev") 这个注解。意思是在开发的过程中去调用

.记住如果开发过程中,记得一定要把pom.xml中的去除tomcat那句话给注释掉,上线才需要去除

问题反思:(为什么不建议这么解决问题)

这种方式确实可以常规解决websocket打包tomcat不报错问题,同时也解决了在资源无法加载的问题,但是这样却十分的麻烦,理由如下:

1. 繁琐:生产环境和开发环境要一直切换是否注释tomcat

2. 局限性大:我们在BootApplication中添加了websocketserver去访问资源的语句,但是其他地方难道没有需要调用的吗,如果有,难道像这样一直累计添加下去,每个server设置一下

核心思想是资源无法加载的问题,如果你有写线程,且线程你也调用了数据库资源,那么解决方法是一致,编写一个公用的工具类解决

解决方法二:(推荐)

步骤1:新建一个工具类,getbeanTool

此工具类为之后加载资源的工具类,公用

@Component
public class GetBeanTool implements ApplicationContextAware{
	
	private static ApplicationContext applicationContext = null;
 
 @Override
 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  GetBeanTool.applicationContext = applicationContext;
 }
 
 public static Object getBeanByName(String beanName) {
  if (applicationContext == null){
   return null;
  }
  return applicationContext.getBean(beanName);
 }
 
 public static <T> T getBean(Class<T> type) {
  return applicationContext.getBean(type);
 }
 
}

步骤2:在线程、websocket等server中,加载资源

以WebSocketServer作为参考,如下修改:

 private ManageUserMapper manageUserMapper;
 
 public WebSocketServer() {
 	this.manageUserMapper=GetBeanTool.getBean(ManageUserMapper.class);
 }

这么做你就不用在BootApplication中添加语句,来让你的server去调用资源了,一步到位,大家都能用,需要的时候直接通过getbeanTool去请求就行了

步骤3:解决tomcat开发环境,生产环境pom.xml中注释和打开内置tomcat的问题

这里需要修改BootApplication,如下修改:

@SpringBootApplication
@Configuration
public class BootApplication extends SpringBootServletInitializer {
 
	@Override
	protected SpringApplicationBuilder configure(
			SpringApplicationBuilder application) {
		return application.sources(BootApplication.class);
	}
 
 
	public static void main(String[] args) {
		SpringApplication.run(BootApplication.class, args);
	}
}

可以看到这里我继承了SpringBootServletInitializer ,同时重写了configure方法。采用这种写法,如论是开发还是测试,你都不用管是否需要注释内置的tomcat了,是不是很方便,至于原理,这里不解释,篇幅太长,自己去百度吧

总结:

1. 最近做了一个简单的IM功能,遇到了这些问题,作为记录,防止哪天我忘了

2. 网上解决方法的可能有用,但是写的不明不白,不友好,而且不见得好用,在解决问题的时候一定要考虑到通用性,开发一定要为了便利,不然坑了你也坑了被人,改这改那谁尼玛记得住

3. 此博文为本人自身角度进行编写,作为记录。如对他人有帮助,可以点个赞,本人不回复,不评论。

到此这篇关于解决SpringBoot webSocket 资源无法加载、tomcat启动报错的问题的文章就介绍到这了,更多相关SpringBoot webSocket 资源无法加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot关于自定义stater的yml无法提示问题解决方案

    Springboot关于自定义stater的yml无法提示问题解决方案

    这篇文章主要介绍了Springboot关于自定义stater的yml无法提示问题及解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Java中对象的克隆详解

    Java中对象的克隆详解

    这篇文章主要介绍了Java中对象的克隆详解,Java中对象的复制分为浅复制与深复制的不同之处就在于深复制还会复制对象的引用对象,需要的朋友可以参考下
    2023-08-08
  • 解决springboot 实体类String转Date类型的坑

    解决springboot 实体类String转Date类型的坑

    这篇文章主要介绍了解决springboot 实体类String转Date类型的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java实现简单无界面五子棋

    Java实现简单无界面五子棋

    这篇文章主要为大家详细介绍了Java实现简单无界面五子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java中调用Python的实现示例

    Java中调用Python的实现示例

    本文主要介绍了Java中调用Python的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Netty分布式ByteBuf使用命中缓存的分配解析

    Netty分布式ByteBuf使用命中缓存的分配解析

    这篇文章主要为大家介绍了Netty分布式ByteBuf 使用命中缓存的分配解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • Java concurrency之CountDownLatch原理和示例_动力节点Java学院整理

    Java concurrency之CountDownLatch原理和示例_动力节点Java学院整理

    CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 下面通过本文给大家分享Java concurrency之CountDownLatch原理和示例,需要的的朋友参考下吧
    2017-06-06
  • 一文搞懂JMeter engine中HashTree的配置问题

    一文搞懂JMeter engine中HashTree的配置问题

    本文主要介绍了JMeter engine中HashTree的配置,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • IDEA 设置显示内存的使用情况和内存回收的方法

    IDEA 设置显示内存的使用情况和内存回收的方法

    这篇文章主要介绍了IDEA 设置显示内存的使用情况和内存回收的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • java使用poi读取ppt文件和poi读取excel、word示例

    java使用poi读取ppt文件和poi读取excel、word示例

    这篇文章主要介绍了java使用poi读取ppt文件和poi读取excel、word示例,需要的朋友可以参考下
    2014-03-03

最新评论