1

How to inject a dependency inside a Web Socket handler:

public class WebsocketHandler extends AbstractWebSocketHandler {
    @Autowired
    GreetingMap greetingMap;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        // NullPointerException here
        String greeting = greetingMap.getSampleGreetings().get("hello") + " " + message.getPayload();
        session.sendMessage(new TextMessage(greeting));
    }
}

The code above throws NullPointerException

What could be missing here?

quarks
  • 33,478
  • 73
  • 290
  • 513
  • Didn't you forget to put some decorator in WebsocketHandler, like Configuration or Component ? If you instanciate an object of WebsocketHandler class manually, then the Sprig DI can't inject none of depedencies of the class, you should do it manually too. Edit the question explaning the context where the classe will be used. – Rodrigo Apr 18 '20 at 02:05
  • Even if I add `@Component` in the `WebsocketHandler` still throw NPE, my goal is for the websocket handler to be able to access dependencies used by Spring Controllers in my app. But somehow it seems that the Websocket handler is stand-alone and cannot access components that Spring Controllers can access on the other hand. – quarks Apr 18 '20 at 02:25

2 Answers2

2

Try using dependency injection with constructor instead @Autowired:

private GreetingMap greetingMap;

public WebsocketHandler(GreetingMap greetingMap){
    this.greetingMap = greetingMap
}
0

I think the problem is that SocketHanler is not a spring bean, but is created by "new" operator:

@Configuration
@EnableWebSocket
public class WebSocketsConfiguration implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketHandler(), "/socket")
                .setAllowedOrigins("*");
    }
}

What you need to do in this case, is to inject your dependency into WebSocketConfiguration and pass it manually to SocketHandler constructor:

@Configuration
@EnableWebSocket
public class WebSocketsConfiguration implements WebSocketConfigurer {
    @Autowired
    MyDependency myDependency;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketHandler(myDependency), "/socket")
                .setAllowedOrigins("*");
    }
}

And in the handler, you need to add constructor that receives the dependency

public class SocketHandler extends AbstractWebSocketHandler {
    private MyDependency myDependency;

    public SocketHandler(MyDependency myDependency) {
        this.myDependency = myDependency;
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println(String.format("Message from client: %s", message));
    }
}
Eduard Grinberg
  • 129
  • 2
  • 8