2016-08-04 28 views
4

Ich fragte im Grunde dasselbe vor ein paar Monaten mit diesem Post: How should a Spring JMS listener handle a message with an empty payload?, aber alles, was ich bekam, war ein läppischer Kommentar, der darauf hindeutet, dass ich meinen Hörer neu schreibe, um zu tun, was ich will. Eine gültige Aussage, aber in meinen Augen unklar, da ich immer noch mit Spring-Boot klarkomme. Ich habe seitdem gelernt und möchte diese Frage direkter stellen (im Gegensatz zu einem Kopfgeld auf das alte).Spring JMSListener - Wie sollte es mit leeren Nutzlasten umgehen?

stelle ich eine kommentierte Bean-Klasse mit @Configuration und @EnableJms und meine Container Fabrik wie folgt aussieht:

@Bean 
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() { 
     DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); 
     factory.setConnectionFactory(mqConnectionFactory()); 
     factory.setDestinationResolver(destinationResolver()); 
     factory.setConcurrency("1"); 
     factory.setErrorHandler(errorHandler()); 
     factory.setSessionTransacted(true); 
     factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE); 
     return factory; 
    } 

Und der Hörer wie folgt aussieht:

@JmsListener(id = "qID", destination = "qName") 
    public void processOrder(String message) {. . .} 

Wie ich es verstehe, sobald die kommentierten Bean-Klasse wird durchgelaufen, die JMSListener startet grundsätzlich (es sei denn, ich setze autoStartup auf false), so verstehe ich nicht, wo und wann ich die Kontrolle über was oder wie die JmsListener behandelt Dinge. Aus meiner Sicht läuft es "nur". Wenn also eine Warteschlange "\n" oder nur eine leere Zeichenfolge enthält, löst der Listener eine Ausnahme aus. Speziell org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class java.lang.String. Und diese Ausnahme wird hinter die Kulissen geworfen. Ich nie die Chance bekommen, etwas im Inneren des Ich sah in SimpleMessageConverter

Zuhörer auszuführen, aber offenbar nicht, etwas zu sehen, das mich so etwas wie setIgnoreStringPattern() zu sagen erlauben würde. Das gibt es offensichtlich nicht, aber das ist es, was ich brauche. Was vermisse ich? Gibt es eine Möglichkeit, die JmsListener bestimmte Strings zu ignorieren?

+0

Können Sie etwas mehr darüber erklären, warum Sie leere Nachrichten unterstützen müssen? –

+0

@ JohnK Sicher. Wir haben also WebSphere MQ-Warteschlangen, in die andere Anwendungen schreiben. Mein Listener muss die Fehlerwarteschlangen im Auge behalten. Die Fehlerwarteschlangen enthalten sehr merkwürdige Nachrichten. Meine App zielt darauf ab, dies zu beheben, indem nutzlose Nachrichten identifiziert werden. Wie Newline-Zeichen, die in Warteschlangen gelangen, die nicht sein sollten. –

+0

Ich weiß, dass dies Ihre Frage nicht beantwortet, aber wenn Sie Kontrolle darüber haben, was die anderen Apps in die Warteschlange schreiben, ist die beste Antwort vielleicht, sicherzustellen, dass die anderen Apps gültige Nachrichten schreiben? Es sei denn, Sie haben keine Kontrolle über sie in diesem Fall, vergiss es. –

Antwort

1

Ich nahm M. Deinum Vorschlag (wie es schien schnell und sauber) und machte einfach den Parameter Typ javax.jms.Message dann konvertiert die eingehende Nachricht in eine Zeichenfolge. So, jetzt meine Zuhörer sieht aus wie

@JmsListener 
public void processOrder(Message message) throws JMSException { 
    String convertedMessage = ((TextMessage) message).getText(); 
    : 
    : 
} 

Dieses eine JMSException werfen kann, aber ich bin nicht zu sehr mit, dass wie jetzt, wenn meine implementiert ErrorHandler Klasse aufgerufen wird, werde ich weiß jetzt, warum und etwas präziser tun um eine fehlgeschlagene Konvertierung zu verarbeiten. Das macht genau das, wozu ich es brauche.

Edit: Und als Antwort auf Jonh K Vorschlag, hatte der Hörer nicht gerne byte[] als Parameter. Es wollte im Grunde einen Konverter von Byte-Array zu String konvertieren. Ich habe keinen eigenen benutzerdefinierten Konverter implementiert.

0

Sie können der Empfängercontainer-Factory einen benutzerdefinierten Nachrichtenkonverter hinzufügen und mit der eingehenden Nachricht alles tun, was Sie möchten.

+0

Wenn ich dies lese, fällt mir das Wort "custom" auf. Du meinst wortwörtlich meine eigenen schreiben anstatt etwas wie 'Simple MessageConverter' zu benutzen oder zu modifizieren? –

+0

Sie können eine Unterklasse erstellen oder an eine SMC delegieren und benutzerdefinierte Logik hinzufügen. –