Springboot 整合 webSocket 报错 Failed to register @ServerEndpoint class 问题汇总

Springboot 整合 webSocket WebsocketService

使用@Component注解后无法启动:

@Component
@ServerEndpoint(value = "/websocket/chat/{info}", configurator = MySpringConfigurator.class)
public class ChatWebSocketServer {
    
    
		//...
}

解决问题

原因1:Session包引用错误、替换成websocket下的Session

import javax.websocket.Session

原因2:onOpen方法未使用@PathParam注解

注:onOpen中除Session、EndpointConfig类型的参数外必须使用@PathParam注解

原因3:onError方法未设置Throwable参数

@OnError
public void onError(Throwable e){
    
    
	// ......
}

关于以上问题的发生原因都可以在源码中找到,我将源码方法列在下面,标明了一些简短的注释,这里就不过多分析了,有兴趣的朋友可以看看。

private static PojoPathParam[] getPathParams(Method m,
        MethodType methodType) throws DeploymentException {
    
    
    if (m == null) {
    
    
        return new PojoPathParam[0];
    }
    boolean foundThrowable = false;
    Class<?>[] types = m.getParameterTypes();
    Annotation[][] paramsAnnotations = m.getParameterAnnotations();
    PojoPathParam[] result = new PojoPathParam[types.length];
    // 重点在这一段
    for (int i = 0; i < types.length; i++) {
    
    
        Class<?> type = types[i];
        // 检查你的Session类型
        if (type.equals(Session.class)) {
    
    
            result[i] = new PojoPathParam(type, null);
        // 检查EndpointConfig类型
        } else if (methodType == MethodType.ON_OPEN &&
                type.equals(EndpointConfig.class)) {
    
    
            result[i] = new PojoPathParam(type, null);
        // 检查ON_ERROR是否携带Throwable参数
        } else if (methodType == MethodType.ON_ERROR
                && type.equals(Throwable.class)) {
    
    
            foundThrowable = true;
            result[i] = new PojoPathParam(type, null);
        } else if (methodType == MethodType.ON_CLOSE &&
                type.equals(CloseReason.class)) {
    
    
            result[i] = new PojoPathParam(type, null);
        } else {
    
    
        // 如果参数不满足上述类型,则检查是否标有@PathParam注解
            Annotation[] paramAnnotations = paramsAnnotations[i];
            for (Annotation paramAnnotation : paramAnnotations) {
    
    
                if (paramAnnotation.annotationType().equals(
                        PathParam.class)) {
    
    
                    result[i] = new PojoPathParam(type,
                            ((PathParam) paramAnnotation).value());
                    break;
                }
            }
            // 不允许使用没有注解的参数
            // Parameters without annotations are not permitted
            if (result[i] == null) {
    
    
                throw new DeploymentException(sm.getString(
                        "pojoMethodMapping.paramWithoutAnnotation",
                        type, m.getName(), m.getClass().getName()));
            }
        }
    }
    //ON_ERROR未携带Throwable参数时抛出的异常
    if (methodType == MethodType.ON_ERROR && !foundThrowable) {
    
    
        throw new DeploymentException(sm.getString(
                "pojoMethodMapping.onErrorNoThrowable",
                m.getName(), m.getDeclaringClass().getName()));
    }
    return result;
}

如果还有其他关于Springboot 整合 webSocket 启动报错的问题,欢迎在评论区说明。
参考文章:Springboot2.0 集成 websocket 出现 Failed to register @ServerEndpoint class 问题.

猜你喜欢

转载自blog.csdn.net/qq_42983806/article/details/107462859