DispatcherHandlerIntegrationTests.java 6.5 KB
Newer Older
A
Arjen Poutsma 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17
package org.springframework.web.reactive.function.server;
A
Arjen Poutsma 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.HandlerAdapter;
import org.springframework.web.reactive.HandlerMapping;
44
import org.springframework.web.reactive.config.WebReactiveConfigurationSupport;
45 46
import org.springframework.web.reactive.function.server.support.HandlerFunctionAdapter;
import org.springframework.web.reactive.function.server.support.ServerResponseResultHandler;
A
Arjen Poutsma 已提交
47
import org.springframework.web.reactive.result.view.ViewResolver;
A
Arjen Poutsma 已提交
48 49 50
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;

import static org.junit.Assert.assertEquals;
51
import static org.springframework.http.codec.BodyInserters.fromObject;
52
import static org.springframework.http.codec.BodyInserters.fromPublisher;
53
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
A
Arjen Poutsma 已提交
54 55

/**
56
 * Tests the use of {@link HandlerFunction} and {@link RouterFunction} in a
A
Arjen Poutsma 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
 * {@link DispatcherHandler}.
 * @author Arjen Poutsma
 */
public class DispatcherHandlerIntegrationTests extends AbstractHttpHandlerIntegrationTests {
	
	private AnnotationConfigApplicationContext wac;

	private RestTemplate restTemplate;

	@Before
	public void createRestTemplate() {
		this.restTemplate = new RestTemplate();
	}

	@Override
	protected HttpHandler createHttpHandler() {
		this.wac = new AnnotationConfigApplicationContext();
		this.wac.register(TestConfiguration.class);
		this.wac.refresh();

		DispatcherHandler webHandler = new DispatcherHandler();
		webHandler.setApplicationContext(this.wac);

		return WebHttpHandlerBuilder.webHandler(webHandler).build();
	}
	
	@Test
	public void mono() throws Exception {
		ResponseEntity<Person> result =
86
				this.restTemplate.getForEntity("http://localhost:" + this.port + "/mono", Person.class);
A
Arjen Poutsma 已提交
87 88 89 90 91 92 93 94 95

		assertEquals(HttpStatus.OK, result.getStatusCode());
		assertEquals("John", result.getBody().getName());
	}

	@Test
	public void flux() throws Exception {
		ParameterizedTypeReference<List<Person>> reference = new ParameterizedTypeReference<List<Person>>() {};
		ResponseEntity<List<Person>> result =
96 97
				this.restTemplate
						.exchange("http://localhost:" + this.port + "/flux", HttpMethod.GET, null, reference);
A
Arjen Poutsma 已提交
98 99 100 101 102 103 104 105 106 107

		assertEquals(HttpStatus.OK, result.getStatusCode());
		List<Person> body = result.getBody();
		assertEquals(2, body.size());
		assertEquals("John", body.get(0).getName());
		assertEquals("Jane", body.get(1).getName());
	}
	

	@Configuration
108
	static class TestConfiguration extends WebReactiveConfigurationSupport {
A
Arjen Poutsma 已提交
109 110 111 112 113 114 115 116 117 118 119 120

		@Bean
		public PersonHandler personHandler() {
			return new PersonHandler();
		}

		@Bean
		public HandlerAdapter handlerAdapter() {
			return new HandlerFunctionAdapter();
		}

		@Bean
121
		public HandlerMapping handlerMapping(RouterFunction<?> routerFunction,
A
Arjen Poutsma 已提交
122
				ApplicationContext applicationContext) {
123
			return RouterFunctions.toHandlerMapping(routerFunction,
124
					new HandlerStrategies() {
A
Arjen Poutsma 已提交
125 126 127 128 129 130 131 132 133
						@Override
						public Supplier<Stream<HttpMessageReader<?>>> messageReaders() {
							return () -> getMessageReaders().stream();
						}

						@Override
						public Supplier<Stream<HttpMessageWriter<?>>> messageWriters() {
							return () -> getMessageWriters().stream();
						}
A
Arjen Poutsma 已提交
134 135 136

						@Override
						public Supplier<Stream<ViewResolver>> viewResolvers() {
137
							return Stream::empty;
A
Arjen Poutsma 已提交
138
						}
A
Arjen Poutsma 已提交
139 140 141 142
					});
		}

		@Bean
143
		public RouterFunction<?> routerFunction() {
A
Arjen Poutsma 已提交
144 145 146 147 148 149
			PersonHandler personHandler = personHandler();
			return route(RequestPredicates.GET("/mono"), personHandler::mono)
					.and(route(RequestPredicates.GET("/flux"), personHandler::flux));
		}

		@Bean
150 151
		public ServerResponseResultHandler responseResultHandler() {
			return new ServerResponseResultHandler();
A
Arjen Poutsma 已提交
152 153 154 155 156
		}
	}
	
	private static class PersonHandler {

157
		public Mono<ServerResponse> mono(ServerRequest request) {
A
Arjen Poutsma 已提交
158
			Person person = new Person("John");
159
			return ServerResponse.ok().body(fromObject(person));
A
Arjen Poutsma 已提交
160 161
		}

162
		public Mono<ServerResponse> flux(ServerRequest request) {
A
Arjen Poutsma 已提交
163 164
			Person person1 = new Person("John");
			Person person2 = new Person("Jane");
165
			return ServerResponse.ok().body(
166
					fromPublisher(Flux.just(person1, person2), Person.class));
A
Arjen Poutsma 已提交
167 168
		}

169 170 171 172
		public Mono<ServerResponse> view() {
			return ServerResponse.ok().render("foo", "bar");
		}

A
Arjen Poutsma 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
	}

	private static class Person {

		private String name;

		@SuppressWarnings("unused")
		public Person() {
		}

		public Person(String name) {
			this.name = name;
		}

		public String getName() {
188
			return this.name;
A
Arjen Poutsma 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public boolean equals(Object o) {
			if (this == o) {
				return true;
			}
			if (o == null || getClass() != o.getClass()) {
				return false;
			}
			Person
					person = (Person) o;
			return !(this.name != null ? !this.name.equals(person.name) : person.name != null);
		}

		@Override
		public int hashCode() {
			return this.name != null ? this.name.hashCode() : 0;
		}

		@Override
		public String toString() {
			return "Person{" +
216
					"name='" + this.name + '\'' +
A
Arjen Poutsma 已提交
217 218 219 220 221 222
					'}';
		}
	}
	
	
}