16
16
17
17
package org .springframework .web .reactive .result .method .annotation ;
18
18
19
- import java .lang . reflect . Method ;
19
+ import java .time . Duration ;
20
20
import java .util .Optional ;
21
21
22
+ import io .reactivex .Single ;
22
23
import org .junit .Before ;
23
24
import org .junit .Test ;
24
25
import reactor .core .publisher .Mono ;
25
26
import reactor .test .StepVerifier ;
26
27
27
28
import org .springframework .context .annotation .AnnotationConfigApplicationContext ;
28
- import org .springframework .core .DefaultParameterNameDiscoverer ;
29
- import org .springframework .core .GenericTypeResolver ;
30
29
import org .springframework .core .MethodParameter ;
31
30
import org .springframework .core .ReactiveAdapterRegistry ;
32
- import org .springframework .core .annotation .SynthesizingMethodParameter ;
33
31
import org .springframework .format .support .DefaultFormattingConversionService ;
34
32
import org .springframework .mock .http .server .reactive .test .MockServerHttpRequest ;
35
33
import org .springframework .mock .web .test .server .MockServerWebExchange ;
36
- import org .springframework .util .ReflectionUtils ;
37
34
import org .springframework .web .bind .annotation .RequestAttribute ;
38
35
import org .springframework .web .bind .support .ConfigurableWebBindingInitializer ;
36
+ import org .springframework .web .method .ResolvableMethod ;
39
37
import org .springframework .web .reactive .BindingContext ;
40
38
import org .springframework .web .server .ServerWebInputException ;
41
39
45
43
import static org .junit .Assert .assertNull ;
46
44
import static org .junit .Assert .assertSame ;
47
45
import static org .junit .Assert .assertTrue ;
48
- import static org .junit . Assert . fail ;
46
+ import static org .springframework . web . method . MvcAnnotationPredicates . requestAttribute ;
49
47
50
48
/**
51
49
* Unit tests for {@link RequestAttributeMethodArgumentResolver}.
@@ -58,37 +56,36 @@ public class RequestAttributeMethodArgumentResolverTests {
58
56
59
57
private final MockServerWebExchange exchange = MockServerWebExchange .from (MockServerHttpRequest .get ("/" ));
60
58
61
- private Method handleMethod ;
59
+ private final ResolvableMethod testMethod = ResolvableMethod .on (getClass ())
60
+ .named ("handleWithRequestAttribute" ).build ();
62
61
63
62
64
63
@ Before
65
64
public void setup () throws Exception {
66
65
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ();
67
66
context .refresh ();
68
- ReactiveAdapterRegistry adapterRegistry = new ReactiveAdapterRegistry ();
69
- this .resolver = new RequestAttributeMethodArgumentResolver (context .getBeanFactory (), adapterRegistry );
70
- this .handleMethod = ReflectionUtils .findMethod (getClass (), "handleWithRequestAttribute" , (Class <?>[]) null );
67
+ ReactiveAdapterRegistry registry = new ReactiveAdapterRegistry ();
68
+ this .resolver = new RequestAttributeMethodArgumentResolver (context .getBeanFactory (), registry );
71
69
}
72
70
73
71
74
72
@ Test
75
73
public void supportsParameter () throws Exception {
76
- assertTrue (this .resolver .supportsParameter (new MethodParameter (this .handleMethod , 0 )));
77
- assertFalse (this .resolver .supportsParameter (new MethodParameter (this .handleMethod , 4 )));
78
- try {
79
- this .resolver .supportsParameter (new MethodParameter (this .handleMethod , 5 ));
80
- fail ();
81
- }
82
- catch (IllegalStateException ex ) {
83
- assertTrue ("Unexpected error message:\n " + ex .getMessage (),
84
- ex .getMessage ().startsWith (
85
- "RequestAttributeMethodArgumentResolver doesn't support reactive type wrapper" ));
86
- }
74
+
75
+ assertTrue (this .resolver .supportsParameter (
76
+ this .testMethod .annot (requestAttribute ().noName ()).arg (Foo .class )));
77
+
78
+ // SPR-16158
79
+ assertTrue (this .resolver .supportsParameter (
80
+ this .testMethod .annotPresent (RequestAttribute .class ).arg (Mono .class , Foo .class )));
81
+
82
+ assertFalse (this .resolver .supportsParameter (
83
+ this .testMethod .annotNotPresent (RequestAttribute .class ).arg ()));
87
84
}
88
85
89
86
@ Test
90
87
public void resolve () throws Exception {
91
- MethodParameter param = initMethodParameter ( 0 );
88
+ MethodParameter param = this . testMethod . annot ( requestAttribute (). noName ()). arg ( Foo . class );
92
89
Mono <Object > mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
93
90
StepVerifier .create (mono )
94
91
.expectNextCount (0 )
@@ -103,7 +100,7 @@ public void resolve() throws Exception {
103
100
104
101
@ Test
105
102
public void resolveWithName () throws Exception {
106
- MethodParameter param = initMethodParameter ( 1 );
103
+ MethodParameter param = this . testMethod . annot ( requestAttribute (). name ( "specialFoo" )). arg ( );
107
104
Foo foo = new Foo ();
108
105
this .exchange .getAttributes ().put ("specialFoo" , foo );
109
106
Mono <Object > mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
@@ -112,7 +109,7 @@ public void resolveWithName() throws Exception {
112
109
113
110
@ Test
114
111
public void resolveNotRequired () throws Exception {
115
- MethodParameter param = initMethodParameter ( 2 );
112
+ MethodParameter param = this . testMethod . annot ( requestAttribute (). name ( "foo" ). notRequired ()). arg ( );
116
113
Mono <Object > mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
117
114
assertNull (mono .block ());
118
115
@@ -124,7 +121,7 @@ public void resolveNotRequired() throws Exception {
124
121
125
122
@ Test
126
123
public void resolveOptional () throws Exception {
127
- MethodParameter param = initMethodParameter ( 3 );
124
+ MethodParameter param = this . testMethod . annot ( requestAttribute (). name ( "foo" )). arg ( Optional . class , Foo . class );
128
125
Mono <Object > mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
129
126
130
127
assertNotNull (mono .block ());
@@ -146,12 +143,30 @@ public void resolveOptional() throws Exception {
146
143
assertSame (foo , optional .get ());
147
144
}
148
145
146
+ @ Test // SPR-16158
147
+ public void resolveMonoParameter () throws Exception {
148
+ MethodParameter param = this .testMethod .annot (requestAttribute ().noName ()).arg (Mono .class , Foo .class );
149
149
150
- private MethodParameter initMethodParameter (int parameterIndex ) {
151
- MethodParameter param = new SynthesizingMethodParameter (this .handleMethod , parameterIndex );
152
- param .initParameterNameDiscovery (new DefaultParameterNameDiscoverer ());
153
- GenericTypeResolver .resolveParameterType (param , this .resolver .getClass ());
154
- return param ;
150
+ // Mono attribute
151
+ Foo foo = new Foo ();
152
+ Mono <Foo > fooMono = Mono .just (foo );
153
+ this .exchange .getAttributes ().put ("fooMono" , fooMono );
154
+ Mono <Object > mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
155
+ assertSame (fooMono , mono .block (Duration .ZERO ));
156
+
157
+ // RxJava Single attribute
158
+ Single <Foo > singleMono = Single .just (foo );
159
+ this .exchange .getAttributes ().clear ();
160
+ this .exchange .getAttributes ().put ("fooMono" , singleMono );
161
+ mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
162
+ Object value = mono .block (Duration .ZERO );
163
+ assertTrue (value instanceof Mono );
164
+ assertSame (foo , ((Mono <?>) value ).block (Duration .ZERO ));
165
+
166
+ // No attribute --> Mono.empty
167
+ this .exchange .getAttributes ().clear ();
168
+ mono = this .resolver .resolveArgument (param , new BindingContext (), this .exchange );
169
+ assertSame (Mono .empty (), mono .block (Duration .ZERO ));
155
170
}
156
171
157
172
@@ -161,8 +176,8 @@ private void handleWithRequestAttribute(
161
176
@ RequestAttribute ("specialFoo" ) Foo namedFoo ,
162
177
@ RequestAttribute (name ="foo" , required = false ) Foo notRequiredFoo ,
163
178
@ RequestAttribute (name ="foo" ) Optional <Foo > optionalFoo ,
164
- String notSupported ,
165
- @ RequestAttribute Mono < Foo > alsoNotSupported ) {
179
+ @ RequestAttribute Mono < Foo > fooMono ,
180
+ String notSupported ) {
166
181
}
167
182
168
183
0 commit comments