Skip to content

Commit

Permalink
Fix issue with "redirect:" when a media type is present
Browse files Browse the repository at this point in the history
Issue: SPR-15291
  • Loading branch information
rstoyanchev committed May 24, 2017
1 parent 109746a commit 718162b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -169,6 +169,11 @@ public void afterPropertiesSet() throws Exception {
}


@Override
public boolean isRedirectView() {
return true;
}

@Override
public boolean checkResourceExists(Locale locale) throws Exception {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -47,6 +47,13 @@ public interface View {
*/
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
* can access and use the model or only a specific attribute in it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ private boolean isBindingCandidate(String name, Object value) {
private Mono<? extends Void> render(List<View> views, Map<String, Object> model,
ServerWebExchange exchange) {

for (View view : views) {
if (view.isRedirectView()) {
return view.render(model, null, exchange);
}
}

List<MediaType> mediaTypes = getMediaTypes(views);
MediaType bestMediaType = selectMediaType(exchange, () -> mediaTypes);
if (bestMediaType != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import reactor.test.StepVerifier;
import rx.Completable;

import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
Expand All @@ -42,6 +43,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
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.ui.ConcurrentModel;
import org.springframework.ui.Model;
Expand Down Expand Up @@ -194,11 +196,10 @@ public void handleReturnValueTypes() throws Exception {

@Test
public void handleWithMultipleResolvers() throws Exception {
Object returnValue = "profile";
MethodParameter returnType = on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(String.class);
ViewResolver[] resolvers = {new TestViewResolver("account"), new TestViewResolver("profile")};

testHandle("/account", returnType, returnValue, "profile: {id=123}", resolvers);
testHandle("/account",
on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(String.class),
"profile", "profile: {id=123}",
new TestViewResolver("account"), new TestViewResolver("profile"));
}

@Test
Expand Down Expand Up @@ -280,6 +281,25 @@ public void contentNegotiationWith406() throws Exception {
.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) {
return resultHandler(Collections.emptyList(), resolvers);
Expand Down

0 comments on commit 718162b

Please sign in to comment.