49
49
import org .springframework .kafka .listener .MessageListener ;
50
50
import org .springframework .kafka .support .Acknowledgment ;
51
51
import org .springframework .kafka .support .KafkaHeaders ;
52
+ import org .springframework .kafka .support .KafkaUtils ;
52
53
import org .springframework .kafka .support .converter .MessagingMessageConverter ;
53
54
import org .springframework .kafka .support .converter .RecordMessageConverter ;
54
55
import org .springframework .lang .Nullable ;
@@ -104,6 +105,8 @@ public abstract class MessagingMessageListenerAdapter<K, V> implements ConsumerS
104
105
105
106
private boolean hasAckParameter ;
106
107
108
+ private boolean messageReturnType ;
109
+
107
110
public MessagingMessageListenerAdapter (Object bean , Method method ) {
108
111
this .bean = bean ;
109
112
this .inferredType = determineInferredType (method );
@@ -288,11 +291,13 @@ protected void handleResult(Object resultArg, Object request, Object source) {
288
291
this .logger .debug ("Listener method returned result [" + resultArg
289
292
+ "] - generating response message for it" );
290
293
}
291
- Object result = resultArg instanceof InvocationResult ? ((InvocationResult ) resultArg ).getResult () : resultArg ;
294
+ boolean isInvocationResult = resultArg instanceof InvocationResult ;
295
+ Object result = isInvocationResult ? ((InvocationResult ) resultArg ).getResult () : resultArg ;
292
296
String replyTopic = evaluateReplyTopic (request , source , resultArg );
293
297
Assert .state (replyTopic == null || this .replyTemplate != null ,
294
298
"a KafkaTemplate is required to support replies" );
295
- sendResponse (result , replyTopic , source );
299
+ sendResponse (result , replyTopic , source , isInvocationResult
300
+ ? ((InvocationResult ) resultArg ).isMessageReturnType () : this .messageReturnType );
296
301
}
297
302
298
303
private String evaluateReplyTopic (Object request , Object source , Object result ) {
@@ -311,12 +316,13 @@ private String evaluateTopic(Object request, Object source, Object result, Expre
311
316
return sendTo .getValue (String .class );
312
317
}
313
318
else {
314
- Object value = sendTo .getValue (this .evaluationContext , new ReplyExpressionRoot (request , source , result ));
319
+ Object value = sendTo == null ? null
320
+ : sendTo .getValue (this .evaluationContext , new ReplyExpressionRoot (request , source , result ));
315
321
boolean isByteArray = value instanceof byte [];
316
- if (!(value instanceof String || isByteArray )) {
322
+ if (!(value == null || value instanceof String || isByteArray )) {
317
323
throw new IllegalStateException (
318
324
"replyTopic expression must evaluate to a String or byte[], it is: "
319
- + ( value == null ? null : value .getClass ().getName () ));
325
+ + value .getClass ().getName ());
320
326
}
321
327
if (isByteArray ) {
322
328
return new String ((byte []) value , StandardCharsets .UTF_8 );
@@ -334,7 +340,7 @@ private String evaluateTopic(Object request, Object source, Object result, Expre
334
340
*/
335
341
@ Deprecated
336
342
protected void sendResponse (Object result , String topic ) {
337
- sendResponse (result , topic , null );
343
+ sendResponse (result , topic , null , false );
338
344
}
339
345
340
346
/**
@@ -343,11 +349,12 @@ protected void sendResponse(Object result, String topic) {
343
349
* @param result the result.
344
350
* @param topic the topic.
345
351
* @param source the source (input).
352
+ * @param messageReturnType true if we are returning message(s).
346
353
* @since 2.1.3
347
354
*/
348
355
@ SuppressWarnings ("unchecked" )
349
- protected void sendResponse (Object result , String topic , @ Nullable Object source ) {
350
- if (topic == null ) {
356
+ protected void sendResponse (Object result , String topic , @ Nullable Object source , boolean messageReturnType ) {
357
+ if (! messageReturnType && topic == null ) {
351
358
if (this .logger .isDebugEnabled ()) {
352
359
this .logger .debug ("No replyTopic to handle the reply: " + result );
353
360
}
@@ -358,7 +365,12 @@ else if (result instanceof Message) {
358
365
else {
359
366
if (result instanceof Collection ) {
360
367
((Collection <V >) result ).forEach (v -> {
361
- this .replyTemplate .send (topic , v );
368
+ if (v instanceof Message ) {
369
+ this .replyTemplate .send ((Message <?>) v );
370
+ }
371
+ else {
372
+ this .replyTemplate .send (topic , v );
373
+ }
362
374
});
363
375
}
364
376
else {
@@ -486,6 +498,7 @@ else if (methodParameter.getGenericParameterType().equals(Acknowledgment.class))
486
498
() -> String .format (stateMessage , "List<ConsumerRecord>" ));
487
499
Assert .state (!this .isMessageList || validParametersForBatch ,
488
500
() -> String .format (stateMessage , "List<Message<?>>" ));
501
+ this .messageReturnType = KafkaUtils .returnTypeMessageOrCollectionOf (method );
489
502
return genericParameterType ;
490
503
}
491
504
0 commit comments