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

}

Второто е в ръководство, написано от един от пролетните блогъри:

@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", изпращачът е нулев и получавам изключение за нулев указател.

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

public class modifier {

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

}

В този втори случай по-горе, след отстраняване на грешки, също има изключение за нулев указател, но то не е с подателя. Той е с sender.template. Шаблонът на изпращача се инициализира, но никога не му се дава стойност или идентификатор. След това, когато this.template.convertAndSend() се извика вътре в greet, се повдига изключение за нулев указател на this.template.

Смесих и съпоставих както двете измислени реализации на контролера, така и моите две реализации на извикване на метода greet от отделен клас в приложението и нито една не работи.

Има ли някой, който може да хвърли малко светлина върху проблема ми? Всяка помощ, съвети или съвети ще бъдат много оценени!

Благодаря предварително.


person Theo    schedule 14.07.2014    source източник
comment
Те са еднакви, единствената разлика е, че единият използва инжектиране, базирано на поле, а другият - инжектиране, базирано на конструктор. Това е единствената разлика. Не трябва да използвате контролера в други класове, контролерът е компонент на уеб слой и не трябва да го използвате в други класове, като правило. Ако искате да използвате повторно функционалността, преместете я в сервизен клас, който инжектирате както в контролера, така и в другите си класове. Вие сами не използвате инжектиране, но сами създавате екземпляри на обекти, оставете Spring да управлява обектите вместо вас.   -  person M. Deinum    schedule 15.07.2014
comment
Ааа, добре, това определено изчисти много проблеми. Кои части трябва да поставя в сервизния клас, а не в контролера?   -  person Theo    schedule 15.07.2014


Отговори (1)


Както правилно е написано в коментарите, има множество начини за автоматично свързване на зависимости, те са предимно еквивалентни, трябва да изберете тези, които предпочитате в зависимост от вашите нужди.

Според другия въпрос: през пролетта контролерът е обектът (singleton), който слуша потребителски заявки, така че картографирането @RequestMapping обработва HTTP заявки към определения URL адрес.

Ако трябва да изпращате съобщения от сървъра към клиента с помощта на обекта SimpMessagingTemplate, трябва да знаете, че клиентът трябва да използва протокола STOMP (през websockets) и трябва да бъде абониран за правилната тема.

Всъщност, използвайки STOMP, сървърът не може произволно да изпраща съобщения до клиента, но може да публикува съобщения само в теми и клиентът трябва да бъде абониран за правилните теми, за да ги получава.

person Alessandro Polverini    schedule 28.07.2014