解决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 资源无法加载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot websocket简单入门示例

    之前做的需求都是客户端请求服务器响应,新需求是服务器主动推送信息到客户端.百度之后有流.长轮询.websoket等方式进行.但是目前更加推崇且合理的显然是websocket. 从springboot官网翻译了一些资料,再加上百度简单实现了springboot使用websocekt与客户端的双工通信. 1.首先搭建一个简单的springboot环境 <!-- Inherit defaults from Spring Boot --> <parent> <groupId>o

  • SpringBoot集成WebSocket【基于纯H5】进行点对点[一对一]和广播[一对多]实时推送

    之前实现WebSocket基于STOMP的,觉得SpringBoot封装的太高,不怎么灵活,现在实现一个纯H5的,也大概了解webSocket在内部是怎么传输的. 1.环境搭建 因为在上一篇基于STOMP协议实现的WebSocket里已经有大概介绍过Web的基本情况了,所以在这篇就不多说了,我们直接进入正题吧,在SpringBoot中,我们还是需要导入WebSocket的包. 在pox.xml加上对springBoot对WebSocket的支持: <!-- webSocket --> <

  • 解决IDEA配置tomcat启动报错问题

    在配置servlet不同路径时遇上以下两个错误: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String:  java.lang.ClassNotFoundException: org.apache.jsp.index_jsp: 对于第一个问题,我上网查阅了很多资料后发现,可能是tomcat版本冲突导致,catalina log如下: 19-Feb-2018

  • tomcat启动报错:java.util.zip.ZipException的解决方法

    发现问题 早上起来报错误,Jenkins打包到tomcat服务器,死活启动不起来,一些定时任务也没跑成功. 报错如下: org.apache.catalina.startup.ContextConfig.beforeStart Exception fixing docBase for context [/test] java.util.zip.ZipException: error in opening zip file at java.util.zip.ZipFile.open(Native

  • SpringBoot集成WebSocket实现前后端消息互传的方法

    什么是WebSocket? WebSocket 协议是基于 TCP 的一种新的网络协议.它实现了浏览器与服务器全双工 (full-duplex) 通信-允许服务器主动发送信息给客户端. 为什么需要WebSocket? 大家都知道以前客户端想知道服务端的处理进度,要不停地使用 Ajax 进行轮询,让浏览器隔个几秒就向服务器发一次请求,这对服务器压力较大.另外一种轮询就是采用 long poll 的方式,这就跟打电话差不多,没收到消息就一直不挂电话,也就是说,客户端发起连接后,如果没消息,就一直不返

  • SpringBoot webSocket实现发送广播、点对点消息和Android接收

    1.SpringBoot webSocket SpringBoot 使用的websocket 协议,不是标准的websocket协议,使用的是名称叫做STOMP的协议. 1.1 STOMP协议说明 STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议. 它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消

  • CentOS 6.5上的Tomcat启动报错问题解决方法

    这里有两个错误: 1.第一个错误,APR的问题,错误详情: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path 2.第二个错误,错误详情: Exception in thread "main" java.lang.InternalError        

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

    问题描述: 1. 项目集成WebSocket,且打包发布tomcat时出现websocket is already in CLOSING or CLOSE state这样的问题,建议参考"解决方法二",但是"解决方法一"请要了解查看 ,因为解决方法二是在一的基础上进行更正 2. 如果出现javax.websocket.server.ServerContainer not available这样的错误,请参考"解决方法一"中步骤3 解决方法一:(常

  • vue-router 按需加载 component: () => import() 报错的解决

    vue的单页面(SPA)项目,必然涉及路由按需的问题. 以前我们是这么做的 //require.ensure是webpack里面的,这样做会将单独拉出来作为一个chunk文件 const Login = r => require.ensure( [], () => r (require('../component/Login.vue'))); 但现在vue-router的官网看看,推荐这种方式: //vue异步组件和webpack的[代码分块点]功能结合,实现了按需加载 const App =

  • 解决springboot 多线程使用MultipartFile读取excel文件内容报错问题

    springboot项目开启多线程 启动类加注解开启 @EnableAsync,实现类方法加注解 @Async 前端页面 报错信息 java.io.FileNotFoundException: C:\Users\dongao\AppData\Local\Temp\tomcat.1255209411477782290.8051\work\Tomcat\localhost\ROOT\upload_7d7b99e5_38da_4a03_93e0_bff20cb48022_00000000.tmp (系

  • CI框架自动加载session出现报错的解决办法

    很多程序员在CI中使用session的时候,开启自动加载session之后网站就报错了,具体错误信息如下:In order to use the Session class you are required to set an encryption key 下面一起来看问题解决办法. 提示信息说明:如果想用session类的话就必须要设置一个加密的密钥!那就给设置一个吧,毕竟也是出于安全考虑. 打开application/config/config.php找到Encryption Key 复制代

  • 解决Idea的tomcat启动报多个listener的错误问题

    错误截图 找不到出错的异常位置在哪里.解决办法:在resources目录下创建一个logging.properties的文件,然后重启 handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler ############################################################ # Handler specific properties. # Describes speci

  • 解决springMVC 跳转js css图片等静态资源无法加载的问题

    web.xml中 servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-va

  • IDEA配置静态资源热加载操作(Springboot修改静态资源不重启)

    第一步: 修改file->settings->compiler->build project automatically 第二步: 按ctrl+shift+a,搜索Registry双击进去,点击面板搜索running,勾选下面的值: 代码的热加载可以使用spring-boot-devtools,百度下就有很多,个人感觉不好用,修改代码需要重启项目,很烦,非常鸡肋,所以我不用,哈哈哈- 补充知识:idea实现修改html等springboot下static目录静态资源重新加载 对于前后端不

随机推荐