Spring STOMP отправляет сообщения из любой точки приложения

Я создаю приложение, используя Stomp для передачи сообщений через веб-сокеты. Я пытаюсь отправлять сообщения с сервера клиенту без запроса из любой точки приложения. Я нашел в Интернете два отдельных варианта отправки сообщений из любой точки приложения.

Первый можно найти в документации Websocket. Раздел 20.4.5:

@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);
    }

}

Второй находится в руководстве, написанном одним из блоггеров Spring< /а>:

@Controller
public class GreetingController {

  @Autowired
  private SimpMessagingTemplate template;


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

}

Оба очень похожи. Первый переопределяет конструктор по умолчанию и не выполняет автоматическую инициализацию шаблона. Второй не создает новый конструктор, но автоматически подключает инициализацию шаблона. Мой первый вопрос: эквивалентны ли эти два действия?

Более насущным вопросом является то, что у меня возникают проблемы с вызовом метода «greet» из любого места. Я пытался сделать это несколькими способами.

Вот первое:

    public class modifier {

    @Autowired
    private HelloController sender;


    public void adder(String words) throws Exception {
        sender.greet(words);

    }
}

В приведенном выше случае кажется, что новый HelloController никогда не инициализировался. При отладке я обнаружил, что когда метод сумматора вызывает метод "greet", отправитель имеет значение null, и я получаю исключение нулевого указателя.

Вот другой маршрут, который я использовал для настройки:

public class modifier {

    public void adder(String words) throws Exception {
        HelloController sender = new HelloController();
        sender.greet(words);
}

}

Во втором вышеприведенном случае после отладки также возникает исключение нулевого указателя, но не с отправителем. Это с sender.template. Шаблон отправителя инициализируется, однако ему никогда не присваивается значение или идентификатор. Затем, когда внутри приветствия вызывается this.template.convertAndSend(), для this.template возникает исключение нулевого указателя.

Я смешал и сопоставил две реализации контроллера gound и две мои реализации вызова метода приветствия из отдельного класса в приложении, и ни одна из них не работает.

Есть ли кто-нибудь, кто может пролить свет на мою проблему? Любая помощь, подсказки или советы будут с благодарностью!

Заранее спасибо.


person Theo    schedule 14.07.2014    source источник
comment
Они одинаковы, единственная разница в том, что в одном используется внедрение на основе поля, а в другом — на основе конструктора. Это единственная разница. Вы не должны использовать контроллер в других классах, контроллер является компонентом веб-слоя, и вы не должны использовать его внутри других классов, как правило. Если вы хотите повторно использовать эту функциональность, переместите ее в класс обслуживания, который вы внедрите как в контроллер, так и в другие классы. Вы сами не используете инъекцию, а сами создаете экземпляры объектов, позвольте Spring управлять объектами за вас.   -  person M. Deinum    schedule 15.07.2014
comment
Ах, хорошо, это определенно прояснило много вопросов. Какие части мне нужно поместить в класс обслуживания, а не в контроллер?   -  person Theo    schedule 15.07.2014


Ответы (1)


Как правильно написано в комментариях, существует несколько способов автоматического связывания зависимостей, они в основном эквивалентны, вам нужно выбрать те, которые вы предпочитаете, в зависимости от ваших потребностей.

Что касается другого вопроса: в Spring контроллер — это объект (одноэлементный), который прослушивает запросы пользователей, поэтому сопоставление @RequestMapping обрабатывает HTTP-запросы на указанный URL-адрес.

Если вам нужно отправлять сообщения с сервера клиенту с помощью объекта SimpMessagingTemplate, вы должны знать, что клиент должен использовать протокол STOMP (через веб-сокеты) и должен быть подписан на правильную тему.

На самом деле, используя STOMP, сервер не может произвольно отправлять сообщения клиенту, а может только публиковать сообщения в темах, и клиент должен быть подписан на нужные темы, чтобы получать их.

person Alessandro Polverini    schedule 28.07.2014