1
1
/*
2
- * Copyright 2016-2020 the original author or authors.
2
+ * Copyright 2016-2021 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
39
39
import org .springframework .kafka .support .KafkaUtils ;
40
40
import org .springframework .lang .Nullable ;
41
41
import org .springframework .messaging .Message ;
42
+ import org .springframework .messaging .MessageHeaders ;
43
+ import org .springframework .messaging .converter .MessageConverter ;
42
44
import org .springframework .messaging .handler .HandlerMethod ;
43
45
import org .springframework .messaging .handler .annotation .Header ;
44
46
import org .springframework .messaging .handler .annotation .SendTo ;
47
+ import org .springframework .messaging .handler .annotation .support .PayloadMethodArgumentResolver ;
45
48
import org .springframework .messaging .handler .invocation .InvocableHandlerMethod ;
46
49
import org .springframework .util .Assert ;
50
+ import org .springframework .validation .Validator ;
47
51
48
52
49
53
/**
@@ -63,6 +67,9 @@ public class DelegatingInvocableHandler {
63
67
64
68
private final ConcurrentMap <Class <?>, InvocableHandlerMethod > cachedHandlers = new ConcurrentHashMap <>();
65
69
70
+ private final ConcurrentMap <InvocableHandlerMethod , MethodParameter > payloadMethodParameters =
71
+ new ConcurrentHashMap <>();
72
+
66
73
private final InvocableHandlerMethod defaultHandler ;
67
74
68
75
private final Map <InvocableHandlerMethod , Expression > handlerSendTo = new HashMap <>();
@@ -77,17 +84,22 @@ public class DelegatingInvocableHandler {
77
84
78
85
private final ConfigurableListableBeanFactory beanFactory ;
79
86
87
+ private final PayloadValidator validator ;
88
+
80
89
/**
81
90
* Construct an instance with the supplied handlers for the bean.
82
91
* @param handlers the handlers.
83
92
* @param bean the bean.
84
93
* @param beanExpressionResolver the expression resolver.
85
94
* @param beanExpressionContext the expression context.
95
+ * @deprecated in favor of
96
+ * {@link #DelegatingInvocableHandler(List, InvocableHandlerMethod, Object, BeanExpressionResolver, BeanExpressionContext, BeanFactory, Validator)}
86
97
*/
98
+ @ Deprecated
87
99
public DelegatingInvocableHandler (List <InvocableHandlerMethod > handlers , Object bean ,
88
100
BeanExpressionResolver beanExpressionResolver , BeanExpressionContext beanExpressionContext ) {
89
101
90
- this (handlers , null , bean , beanExpressionResolver , beanExpressionContext );
102
+ this (handlers , null , bean , beanExpressionResolver , beanExpressionContext , null , null );
91
103
}
92
104
93
105
/**
@@ -97,13 +109,16 @@ public DelegatingInvocableHandler(List<InvocableHandlerMethod> handlers, Object
97
109
* @param bean the bean.
98
110
* @param beanExpressionResolver the resolver.
99
111
* @param beanExpressionContext the context.
112
+ * @deprecated in favor of
113
+ * {@link #DelegatingInvocableHandler(List, InvocableHandlerMethod, Object, BeanExpressionResolver, BeanExpressionContext, BeanFactory, Validator)}
100
114
* @since 2.1.3
101
115
*/
116
+ @ Deprecated
102
117
public DelegatingInvocableHandler (List <InvocableHandlerMethod > handlers ,
103
118
@ Nullable InvocableHandlerMethod defaultHandler ,
104
119
Object bean , BeanExpressionResolver beanExpressionResolver , BeanExpressionContext beanExpressionContext ) {
105
120
106
- this (handlers , defaultHandler , bean , beanExpressionResolver , beanExpressionContext , null );
121
+ this (handlers , defaultHandler , bean , beanExpressionResolver , beanExpressionContext , null , null );
107
122
}
108
123
109
124
/**
@@ -114,13 +129,35 @@ public DelegatingInvocableHandler(List<InvocableHandlerMethod> handlers,
114
129
* @param beanExpressionResolver the resolver.
115
130
* @param beanExpressionContext the context.
116
131
* @param beanFactory the bean factory.
117
- * @since 2.1.11
132
+ * @deprecated in favor of
133
+ * {@link #DelegatingInvocableHandler(List, InvocableHandlerMethod, Object, BeanExpressionResolver, BeanExpressionContext, BeanFactory, Validator)}
134
+ * @since 2.5.11
118
135
*/
136
+ @ Deprecated
119
137
public DelegatingInvocableHandler (List <InvocableHandlerMethod > handlers ,
120
138
@ Nullable InvocableHandlerMethod defaultHandler ,
121
139
Object bean , BeanExpressionResolver beanExpressionResolver , BeanExpressionContext beanExpressionContext ,
122
140
@ Nullable BeanFactory beanFactory ) {
123
141
142
+ this (handlers , defaultHandler , bean , beanExpressionResolver , beanExpressionContext , beanFactory , null );
143
+ }
144
+
145
+ /**
146
+ * Construct an instance with the supplied handlers for the bean.
147
+ * @param handlers the handlers.
148
+ * @param defaultHandler the default handler.
149
+ * @param bean the bean.
150
+ * @param beanExpressionResolver the resolver.
151
+ * @param beanExpressionContext the context.
152
+ * @param beanFactory the bean factory.
153
+ * @param validator the validator.
154
+ * @since 2.5.11
155
+ */
156
+ public DelegatingInvocableHandler (List <InvocableHandlerMethod > handlers ,
157
+ @ Nullable InvocableHandlerMethod defaultHandler ,
158
+ Object bean , BeanExpressionResolver beanExpressionResolver , BeanExpressionContext beanExpressionContext ,
159
+ @ Nullable BeanFactory beanFactory , @ Nullable Validator validator ) {
160
+
124
161
this .handlers = new ArrayList <>();
125
162
for (InvocableHandlerMethod handler : handlers ) {
126
163
this .handlers .add (wrapIfNecessary (handler ));
@@ -132,6 +169,7 @@ public DelegatingInvocableHandler(List<InvocableHandlerMethod> handlers,
132
169
this .beanFactory = beanFactory instanceof ConfigurableListableBeanFactory
133
170
? (ConfigurableListableBeanFactory ) beanFactory
134
171
: null ;
172
+ this .validator = validator == null ? null : new PayloadValidator (validator );
135
173
}
136
174
137
175
private InvocableHandlerMethod wrapIfNecessary (InvocableHandlerMethod handler ) {
@@ -166,6 +204,12 @@ public Object getBean() {
166
204
public Object invoke (Message <?> message , Object ... providedArgs ) throws Exception { //NOSONAR
167
205
Class <? extends Object > payloadClass = message .getPayload ().getClass ();
168
206
InvocableHandlerMethod handler = getHandlerForPayload (payloadClass );
207
+ if (this .validator != null ) {
208
+ MethodParameter parameter = this .payloadMethodParameters .get (handler );
209
+ if (parameter != null ) {
210
+ this .validator .validate (message , parameter , message .getPayload ());
211
+ }
212
+ }
169
213
Object result ;
170
214
if (handler instanceof MetadataAwareInvocableHandlerMethod ) {
171
215
Object [] args = new Object [providedArgs .length + 1 ];
@@ -279,23 +323,29 @@ protected boolean matchHandlerMethod(Class<? extends Object> payloadClass, Invoc
279
323
if ((methodParameter .getParameterAnnotations ().length == 0
280
324
|| !methodParameter .hasParameterAnnotation (Header .class ))
281
325
&& methodParameter .getParameterType ().isAssignableFrom (payloadClass )) {
326
+ if (this .validator != null ) {
327
+ this .payloadMethodParameters .put (handler , methodParameter );
328
+ }
282
329
return true ;
283
330
}
284
331
}
285
332
286
- boolean foundCandidate = false ;
333
+ MethodParameter foundCandidate = null ;
287
334
for (int i = 0 ; i < parameterAnnotations .length ; i ++) {
288
335
MethodParameter methodParameter = new MethodParameter (method , i );
289
336
if ((methodParameter .getParameterAnnotations ().length == 0
290
337
|| !methodParameter .hasParameterAnnotation (Header .class ))
291
338
&& methodParameter .getParameterType ().isAssignableFrom (payloadClass )) {
292
- if (foundCandidate ) {
339
+ if (foundCandidate != null ) {
293
340
throw new KafkaException ("Ambiguous payload parameter for " + method .toGenericString ());
294
341
}
295
- foundCandidate = true ;
342
+ foundCandidate = methodParameter ;
296
343
}
297
344
}
298
- return foundCandidate ;
345
+ if (foundCandidate != null && this .validator != null ) {
346
+ this .payloadMethodParameters .put (handler , foundCandidate );
347
+ }
348
+ return foundCandidate != null ;
299
349
}
300
350
301
351
/**
@@ -325,4 +375,32 @@ private static final class MetadataAwareInvocableHandlerMethod extends Invocable
325
375
326
376
}
327
377
378
+ private static final class PayloadValidator extends PayloadMethodArgumentResolver {
379
+
380
+ PayloadValidator (Validator validator ) {
381
+ super (new MessageConverter () { // Required but never used
382
+
383
+ @ Override
384
+ @ Nullable
385
+ public Message <?> toMessage (Object payload , @ Nullable
386
+ MessageHeaders headers ) {
387
+ return null ;
388
+ }
389
+
390
+ @ Override
391
+ @ Nullable
392
+ public Object fromMessage (Message <?> message , Class <?> targetClass ) {
393
+ return null ;
394
+ }
395
+
396
+ }, validator );
397
+ }
398
+
399
+ @ Override
400
+ public void validate (Message <?> message , MethodParameter parameter , Object target ) { // NOSONAR - public
401
+ super .validate (message , parameter , target );
402
+ }
403
+
404
+ }
405
+
328
406
}
0 commit comments