BridgeMethodResolver properly resolves all declared interfaces

Issue: SPR-16288
This commit is contained in:
Juergen Hoeller 2018-01-11 10:18:27 +01:00
parent ea73ec5c41
commit 121f9e3734
2 changed files with 97 additions and 14 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -196,7 +196,10 @@ public abstract class BridgeMethodResolver {
return method;
}
else {
return searchInterfaces(ifc.getInterfaces(), bridgeMethod);
method = searchInterfaces(ifc.getInterfaces(), bridgeMethod);
if (method != null) {
return method;
}
}
}
return null;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 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.
@ -31,8 +31,10 @@ import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
@ -44,6 +46,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
@ -1224,13 +1227,22 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
getServlet().service(request, response);
}
@Test
public void bridgeMethodsWithMultipleInterfaces() throws Exception {
initServletWithControllers(ArticleController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/method");
MockHttpServletResponse response = new MockHttpServletResponse();
getServlet().service(request, response);
}
@Test
public void requestParamMap() throws Exception {
initServletWithControllers(RequestParamMapController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/map");
request.addParameter("key1", "value1");
request.addParameter("key2", new String[]{"value21", "value22"});
request.addParameter("key2", new String[] {"value21", "value22"});
MockHttpServletResponse response = new MockHttpServletResponse();
getServlet().service(request, response);
@ -1249,7 +1261,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/map");
request.addHeader("Content-Type", "text/html");
request.addHeader("Custom-Header", new String[]{"value21", "value22"});
request.addHeader("Custom-Header", new String[] {"value21", "value22"});
MockHttpServletResponse response = new MockHttpServletResponse();
getServlet().service(request, response);
@ -2591,7 +2603,6 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
public String getContentType() {
return null;
}
@Override
@SuppressWarnings({"unchecked", "deprecation", "rawtypes"})
public void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response)
@ -3106,6 +3117,78 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
}
}
@RestController
@RequestMapping(path = ApiConstants.ARTICLES_PATH)
public static class ArticleController implements ApiConstants, ResourceEndpoint<Article, ArticlePredicate> {
@GetMapping(params = "page")
public Collection<Article> find(String pageable, ArticlePredicate predicate) {
throw new UnsupportedOperationException("not implemented");
}
@GetMapping
public List<Article> find(boolean sort, ArticlePredicate predicate) {
throw new UnsupportedOperationException("not implemented");
}
}
interface ApiConstants {
String API_V1 = "/v1";
String ARTICLES_PATH = API_V1 + "/articles";
}
public interface ResourceEndpoint<E extends Entity, P extends EntityPredicate> {
Collection<E> find(String pageable, P predicate) throws IOException;
List<E> find(boolean sort, P predicate) throws IOException;
}
public static abstract class Entity {
public UUID id;
public String createdBy;
public Instant createdDate;
}
public static class Article extends Entity {
public String slug;
public String title;
public String content;
}
public static abstract class EntityPredicate<E extends Entity> {
public String createdBy;
public Instant createdBefore;
public Instant createdAfter;
public boolean accept(E entity) {
return (createdBy == null || createdBy.equals(entity.createdBy)) &&
(createdBefore == null || createdBefore.compareTo(entity.createdDate) >= 0) &&
(createdAfter == null || createdAfter.compareTo(entity.createdDate) >= 0);
}
}
public static class ArticlePredicate extends EntityPredicate<Article> {
public String query;
@Override
public boolean accept(Article entity) {
return super.accept(entity) && (query == null || (entity.title.contains(query) || entity.content.contains(query)));
}
}
@Controller
public static class RequestParamMapController {
@ -3277,7 +3360,6 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
private String name;
public String getName() {
return name;
}
@ -3325,16 +3407,14 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
}
@RequestMapping("/singleString")
public void processMultipart(@RequestParam("content") String content,
HttpServletResponse response) throws IOException {
public void processMultipart(@RequestParam("content") String content, HttpServletResponse response)
throws IOException {
response.getWriter().write(content);
}
@RequestMapping("/stringArray")
public void processMultipart(@RequestParam("content") String[] content,
HttpServletResponse response) throws IOException {
public void processMultipart(@RequestParam("content") String[] content, HttpServletResponse response)
throws IOException {
response.getWriter().write(StringUtils.arrayToDelimitedString(content, "-"));
}
}
@ -3458,7 +3538,7 @@ public class ServletAnnotationControllerHandlerMethodTests extends AbstractServl
@RequestMapping(value = "empty", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public HttpHeaders createNoHeader() throws URISyntaxException {
public HttpHeaders createNoHeader() {
return new HttpHeaders();
}
}