web-dev-qa-db-fra.com

Impossible de câbler automatiquement. Aucun bean de type SimpMessagingTemplate trouvé

Je configure Websockets dans Spring essentiellement en suivant le guide fourni dans la documentation.

J'essaie actuellement d'envoyer un message du serveur au client comme expliqué dans la section " Envoi de messages de n'importe où "

En suivant l'exemple, vous pouvez câbler automatiquement une classe appelée SimpMessagingTemplate

@Controller
public class GreetingController {

    private SimpMessagingTemplate template;

    @Autowired
    public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @RequestMapping(value="/greetings", method=POST)
    public void greet(String greeting) {
        String text = "[" + getTimestamp() + "]:" + greeting;
        this.template.convertAndSend("/topic/greetings", text);
    }

}

Cependant, mon projet actuel ne trouve pas le bean "SimpMessagingTemplate". (Intellij: 'Impossible de câbler automatiquement. Aucun bean de type SimpMessagingTemplate trouvé'.

J'ai vérifié plusieurs exemples sur Internet, mais je ne trouve pas comment faire en sorte que Spring crée une instance de SimpMessagingTemplate. Comment puis-je le câbler automatiquement?

MODIFIER:

J'ai décidé d'envoyer plus d'informations de fond. Voici ma configuration Websocket actuelle:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">

        <!-- TODO properties to be read from a properties file -->
        <websocket:message-broker application-destination-prefix="/app">
            <websocket:stomp-endpoint path="/new_session" >
                <websocket:sockjs/>
            </websocket:stomp-endpoint>
            <websocket:simple-broker prefix="/topic"/>
        </websocket:message-broker>
</beans>

Websocket fonctionne avec ce contrôleur

@Controller
public class SessionController {

    private static final Logger log = LoggerFactory.getLogger(SessionController.class);

    @MessageMapping("/new_session")
    @SendTo("/topic/session")
    public SessionStatus newSession(Session session) throws Exception {
    Thread.sleep(3000); // simulated delay
    log.info("Response sent !!");
    return new SessionStatus("StatusReport, " + session.toString() + "!");
    }
}

Je ne sais pas comment faire fonctionner ça

public class SessionController {

    private static final Logger log = LoggerFactory.getLogger(SessionController.class);

    private SimpMessagingTemplate template;

    @Autowired
    public SessionController(SimpMessagingTemplate template) {
    this.template = template;
    }

}

Comme le bean "SimpMessagingTemplate template" est introuvable. La documentation de Spring n'offre pas plus de détails à ce sujet.

[~ # ~] modifier [~ # ~] : Exemple de code de travail dans github

16
Tk421

Étrange, car lorsque vous utilisez l'espace de noms websocket, l'élément "message-broker" provoque la création d'un bean SimpMessagingTemplate qui devrait ensuite être disponible pour que vous puissiez l'injecter. Le contrôleur et l'espace de noms websocket sont-ils dans le même ApplicationContext ou peut-être l'un dans le contexte "racine" et l'autre dans le contexte DispatcherServlet?

6
Rossen Stoyanchev

J'ai eu le même problème, l'erreur s'est produite car mon fichier de configuration websocket:

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

}

n'a pas été scanné au printemps.

le correctif consistait donc à ajouter le package avec ce fichier de configuration aux packages analysés.

10
Urbanleg

Vous devez soit avoir un identifiant de définition de bean avec le même nom que le nom de classe dans votre XML applicationContext, soit annoter @Component sur l'injection de classe pour qu'Autowire fonctionne.

<bean id="SimpMessagingTemplate " class="your-class" >

Vous devrez peut-être définir la balise ci-dessous pointant vers votre colis pour un cas ultérieur

<context:component-scan base-package="com.x.y"/>
6
earthling

Rossen avait raison. L'ajout de l'élément ajoutera le bean SimpMessagingTemplate au contexte d'injection. Cela doit être dans le contexte racine de l'application Web, et non dans le contexte de Spring DispatchServlet. Par exemple, dans le fichier web.xml suivant, l'élément courtier de messages doit être inclus dans le fichier app-root.xml. L'inclusion uniquement dans app-mvc.xml entraînera NoSuchBeanDefinitionException.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/app-root.xml</param-value>
</context-param>

<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/spring/app-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
1
raymond