Fix issue with "redirect:" when a media type is present
Issue: SPR-15291
This commit is contained in:
parent
109746a03b
commit
718162b8c4
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -169,6 +169,11 @@ public class RedirectView extends AbstractUrlBasedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRedirectView() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkResourceExists(Locale locale) throws Exception {
|
public boolean checkResourceExists(Locale locale) throws Exception {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -47,6 +47,13 @@ public interface View {
|
||||||
*/
|
*/
|
||||||
List<MediaType> getSupportedMediaTypes();
|
List<MediaType> getSupportedMediaTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this View does rendering by performing a redirect.
|
||||||
|
*/
|
||||||
|
default boolean isRedirectView() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the view based on the given {@link HandlerResult}. Implementations
|
* Render the view based on the given {@link HandlerResult}. Implementations
|
||||||
* can access and use the model or only a specific attribute in it.
|
* can access and use the model or only a specific attribute in it.
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,12 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport
|
||||||
private Mono<? extends Void> render(List<View> views, Map<String, Object> model,
|
private Mono<? extends Void> render(List<View> views, Map<String, Object> model,
|
||||||
ServerWebExchange exchange) {
|
ServerWebExchange exchange) {
|
||||||
|
|
||||||
|
for (View view : views) {
|
||||||
|
if (view.isRedirectView()) {
|
||||||
|
return view.render(model, null, exchange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<MediaType> mediaTypes = getMediaTypes(views);
|
List<MediaType> mediaTypes = getMediaTypes(views);
|
||||||
MediaType bestMediaType = selectMediaType(exchange, () -> mediaTypes);
|
MediaType bestMediaType = selectMediaType(exchange, () -> mediaTypes);
|
||||||
if (bestMediaType != null) {
|
if (bestMediaType != null) {
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
import rx.Completable;
|
import rx.Completable;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticApplicationContext;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
|
@ -42,6 +43,7 @@ import org.springframework.core.io.buffer.support.DataBufferTestUtils;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||||
import org.springframework.mock.http.server.reactive.test.MockServerWebExchange;
|
import org.springframework.mock.http.server.reactive.test.MockServerWebExchange;
|
||||||
import org.springframework.ui.ConcurrentModel;
|
import org.springframework.ui.ConcurrentModel;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
|
@ -194,11 +196,10 @@ public class ViewResolutionResultHandlerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleWithMultipleResolvers() throws Exception {
|
public void handleWithMultipleResolvers() throws Exception {
|
||||||
Object returnValue = "profile";
|
testHandle("/account",
|
||||||
MethodParameter returnType = on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(String.class);
|
on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(String.class),
|
||||||
ViewResolver[] resolvers = {new TestViewResolver("account"), new TestViewResolver("profile")};
|
"profile", "profile: {id=123}",
|
||||||
|
new TestViewResolver("account"), new TestViewResolver("profile"));
|
||||||
testHandle("/account", returnType, returnValue, "profile: {id=123}", resolvers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -280,6 +281,25 @@ public class ViewResolutionResultHandlerTests {
|
||||||
.verify();
|
.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // SPR-15291
|
||||||
|
public void contentNegotiationWithRedirect() throws Exception {
|
||||||
|
|
||||||
|
HandlerResult handlerResult = new HandlerResult(new Object(), "redirect:/",
|
||||||
|
on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(String.class),
|
||||||
|
this.bindingContext);
|
||||||
|
|
||||||
|
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
|
||||||
|
viewResolver.setApplicationContext(new StaticApplicationContext());
|
||||||
|
ViewResolutionResultHandler resultHandler = resultHandler(viewResolver);
|
||||||
|
|
||||||
|
MockServerWebExchange exchange = get("/account").accept(APPLICATION_JSON).toExchange();
|
||||||
|
resultHandler.handleResult(exchange, handlerResult).block(Duration.ZERO);
|
||||||
|
|
||||||
|
MockServerHttpResponse response = exchange.getResponse();
|
||||||
|
assertEquals(303, response.getStatusCode().value());
|
||||||
|
assertEquals("/", response.getHeaders().getLocation().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private ViewResolutionResultHandler resultHandler(ViewResolver... resolvers) {
|
private ViewResolutionResultHandler resultHandler(ViewResolver... resolvers) {
|
||||||
return resultHandler(Collections.emptyList(), resolvers);
|
return resultHandler(Collections.emptyList(), resolvers);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue