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 问题.