org.springframework.core.annotation.MergedAnnotations#org.springframework.web.reactive.result.method.RequestMappingInfo源码实例Demo

下面列出了org.springframework.core.annotation.MergedAnnotations#org.springframework.web.reactive.result.method.RequestMappingInfo 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

/**
 * Uses method and type-level @{@link RequestMapping} annotations to create
 * the RequestMappingInfo.
 * @return the created RequestMappingInfo, or {@code null} if the method
 * does not have a {@code @RequestMapping} annotation.
 * @see #getCustomMethodCondition(Method)
 * @see #getCustomTypeCondition(Class)
 */
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
	RequestMappingInfo info = createRequestMappingInfo(method);
	if (info != null) {
		RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
		if (typeInfo != null) {
			info = typeInfo.combine(info);
		}
		for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
			if (entry.getValue().test(handlerType)) {
				String prefix = entry.getKey();
				if (this.embeddedValueResolver != null) {
					prefix = this.embeddedValueResolver.resolveStringValue(prefix);
				}
				info = RequestMappingInfo.paths(prefix).build().combine(info);
				break;
			}
		}
	}
	return info;
}
 
/**
 * Create a {@link RequestMappingInfo} from the supplied
 * {@link RequestMapping @RequestMapping} annotation, which is either
 * a directly declared annotation, a meta-annotation, or the synthesized
 * result of merging annotation attributes within an annotation hierarchy.
 */
protected RequestMappingInfo createRequestMappingInfo(
		RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {

	RequestMappingInfo.Builder builder = RequestMappingInfo
			.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
			.methods(requestMapping.method())
			.params(requestMapping.params())
			.headers(requestMapping.headers())
			.consumes(requestMapping.consumes())
			.produces(requestMapping.produces())
			.mappingName(requestMapping.name());
	if (customCondition != null) {
		builder.customCondition(customCondition);
	}
	return builder.options(this.config).build();
}
 
@Override
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) {
	HandlerMethod handlerMethod = createHandlerMethod(handler, method);
	Class<?> beanType = handlerMethod.getBeanType();
	CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class);
	CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class);

	if (typeAnnotation == null && methodAnnotation == null) {
		return null;
	}

	CorsConfiguration config = new CorsConfiguration();
	updateCorsConfig(config, typeAnnotation);
	updateCorsConfig(config, methodAnnotation);

	if (CollectionUtils.isEmpty(config.getAllowedMethods())) {
		for (RequestMethod allowedMethod : mappingInfo.getMethodsCondition().getMethods()) {
			config.addAllowedMethod(allowedMethod.name());
		}
	}
	return config.applyPermitDefaultValues();
}
 
@Test
public void customPathMatchConfig() {
	ApplicationContext context = loadConfig(CustomPatchMatchConfig.class);
	final Field field = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
	ReflectionUtils.makeAccessible(field);

	String name = "requestMappingHandlerMapping";
	RequestMappingHandlerMapping mapping = context.getBean(name, RequestMappingHandlerMapping.class);
	assertNotNull(mapping);

	PathPatternParser patternParser = mapping.getPathPatternParser();
	assertNotNull(patternParser);
	boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils.getField(field, patternParser);
	assertFalse(matchOptionalTrailingSlash);

	Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
	assertEquals(1, map.size());
	assertEquals(Collections.singleton(new PathPatternParser().parse("/api/user/{id}")),
			map.keySet().iterator().next().getPatternsCondition().getPatterns());
}
 
@Test
public void compareTwoHttpMethodsOneParam() {
	RequestMappingInfo none = paths().build();
	RequestMappingInfo oneMethod = paths().methods(RequestMethod.GET).build();
	RequestMappingInfo oneMethodOneParam = paths().methods(RequestMethod.GET).params("foo").build();

	ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/foo"));
	Comparator<RequestMappingInfo> comparator = (info, otherInfo) -> info.compareTo(otherInfo, exchange);

	List<RequestMappingInfo> list = asList(none, oneMethod, oneMethodOneParam);
	Collections.shuffle(list);
	list.sort(comparator);

	assertEquals(oneMethodOneParam, list.get(0));
	assertEquals(oneMethod, list.get(1));
	assertEquals(none, list.get(2));
}
 
@Test
@Ignore
public void preFlightRequest() throws Exception {
	MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.options("/foo")
			.header("Origin", "https://domain.com")
			.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "POST")
			);

	RequestMappingInfo info = paths("/foo").methods(RequestMethod.POST).build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);
	assertNotNull(match);

	info = paths("/foo").methods(RequestMethod.OPTIONS).build();
	match = info.getMatchingCondition(exchange);
	assertNull("Pre-flight should match the ACCESS_CONTROL_REQUEST_METHOD", match);
}
 
private RequestMappingInfo assertComposedAnnotationMapping(String methodName, String path,
		RequestMethod requestMethod) throws Exception {

	Class<?> clazz = ComposedAnnotationController.class;
	Method method = ClassUtils.getMethod(clazz, methodName, (Class<?>[]) null);
	RequestMappingInfo info = this.handlerMapping.getMappingForMethod(method, clazz);

	assertNotNull(info);

	Set<PathPattern> paths = info.getPatternsCondition().getPatterns();
	assertEquals(1, paths.size());
	assertEquals(path, paths.iterator().next().getPatternString());

	Set<RequestMethod> methods = info.getMethodsCondition().getMethods();
	assertEquals(1, methods.size());
	assertEquals(requestMethod, methods.iterator().next());

	return info;
}
 
源代码8 项目: springdoc-openapi   文件: OpenApiResource.java
/**
 * Calculate path.
 *
 * @param restControllers the rest controllers
 * @param map the map
 */
protected void calculatePath(Map<String, Object> restControllers, Map<RequestMappingInfo, HandlerMethod> map) {
	for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet()) {
		RequestMappingInfo requestMappingInfo = entry.getKey();
		HandlerMethod handlerMethod = entry.getValue();
		PatternsRequestCondition patternsRequestCondition = requestMappingInfo.getPatternsCondition();
		Set<PathPattern> patterns = patternsRequestCondition.getPatterns();
		for (PathPattern pathPattern : patterns) {
			String operationPath = pathPattern.getPatternString();
			Map<String, String> regexMap = new LinkedHashMap<>();
			operationPath = PathUtils.parsePath(operationPath, regexMap);
			if (operationPath.startsWith(DEFAULT_PATH_SEPARATOR)
					&& (restControllers.containsKey(handlerMethod.getBean().toString()) || actuatorProvider.isPresent())
					&& isPackageToScan(handlerMethod.getBeanType().getPackage()) && isPathToMatch(operationPath)) {
				Set<RequestMethod> requestMethods = requestMappingInfo.getMethodsCondition().getMethods();
				// default allowed requestmethods
				if (requestMethods.isEmpty())
					requestMethods = this.getDefaultAllowedHttpMethods();
				calculatePath(handlerMethod, operationPath, requestMethods);
			}
		}
	}
}
 
/**
 * Uses method and type-level @{@link RequestMapping} annotations to create
 * the RequestMappingInfo.
 * @return the created RequestMappingInfo, or {@code null} if the method
 * does not have a {@code @RequestMapping} annotation.
 * @see #getCustomMethodCondition(Method)
 * @see #getCustomTypeCondition(Class)
 */
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
	RequestMappingInfo info = createRequestMappingInfo(method);
	if (info != null) {
		RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
		if (typeInfo != null) {
			info = typeInfo.combine(info);
		}
		for (Map.Entry<String, Predicate<Class<?>>> entry : this.pathPrefixes.entrySet()) {
			if (entry.getValue().test(handlerType)) {
				String prefix = entry.getKey();
				if (this.embeddedValueResolver != null) {
					prefix = this.embeddedValueResolver.resolveStringValue(prefix);
				}
				info = RequestMappingInfo.paths(prefix).build().combine(info);
				break;
			}
		}
	}
	return info;
}
 
/**
 * Create a {@link RequestMappingInfo} from the supplied
 * {@link RequestMapping @RequestMapping} annotation, which is either
 * a directly declared annotation, a meta-annotation, or the synthesized
 * result of merging annotation attributes within an annotation hierarchy.
 */
protected RequestMappingInfo createRequestMappingInfo(
		RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {

	RequestMappingInfo.Builder builder = RequestMappingInfo
			.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
			.methods(requestMapping.method())
			.params(requestMapping.params())
			.headers(requestMapping.headers())
			.consumes(requestMapping.consumes())
			.produces(requestMapping.produces())
			.mappingName(requestMapping.name());
	if (customCondition != null) {
		builder.customCondition(customCondition);
	}
	return builder.options(this.config).build();
}
 
@Override
protected CorsConfiguration initCorsConfiguration(Object handler, Method method, RequestMappingInfo mappingInfo) {
	HandlerMethod handlerMethod = createHandlerMethod(handler, method);
	Class<?> beanType = handlerMethod.getBeanType();
	CrossOrigin typeAnnotation = AnnotatedElementUtils.findMergedAnnotation(beanType, CrossOrigin.class);
	CrossOrigin methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, CrossOrigin.class);

	if (typeAnnotation == null && methodAnnotation == null) {
		return null;
	}

	CorsConfiguration config = new CorsConfiguration();
	updateCorsConfig(config, typeAnnotation);
	updateCorsConfig(config, methodAnnotation);

	if (CollectionUtils.isEmpty(config.getAllowedMethods())) {
		for (RequestMethod allowedMethod : mappingInfo.getMethodsCondition().getMethods()) {
			config.addAllowedMethod(allowedMethod.name());
		}
	}
	return config.applyPermitDefaultValues();
}
 
@Test
public void customPathMatchConfig() {
	ApplicationContext context = loadConfig(CustomPatchMatchConfig.class);
	final Field field = ReflectionUtils.findField(PathPatternParser.class, "matchOptionalTrailingSeparator");
	ReflectionUtils.makeAccessible(field);

	String name = "requestMappingHandlerMapping";
	RequestMappingHandlerMapping mapping = context.getBean(name, RequestMappingHandlerMapping.class);
	assertNotNull(mapping);

	PathPatternParser patternParser = mapping.getPathPatternParser();
	assertNotNull(patternParser);
	boolean matchOptionalTrailingSlash = (boolean) ReflectionUtils.getField(field, patternParser);
	assertFalse(matchOptionalTrailingSlash);

	Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
	assertEquals(1, map.size());
	assertEquals(Collections.singleton(new PathPatternParser().parse("/api/user/{id}")),
			map.keySet().iterator().next().getPatternsCondition().getPatterns());
}
 
@Test
public void compareTwoHttpMethodsOneParam() {
	RequestMappingInfo none = paths().build();
	RequestMappingInfo oneMethod = paths().methods(RequestMethod.GET).build();
	RequestMappingInfo oneMethodOneParam = paths().methods(RequestMethod.GET).params("foo").build();

	ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/foo"));
	Comparator<RequestMappingInfo> comparator = (info, otherInfo) -> info.compareTo(otherInfo, exchange);

	List<RequestMappingInfo> list = asList(none, oneMethod, oneMethodOneParam);
	Collections.shuffle(list);
	list.sort(comparator);

	assertEquals(oneMethodOneParam, list.get(0));
	assertEquals(oneMethod, list.get(1));
	assertEquals(none, list.get(2));
}
 
@Test
@Ignore
public void preFlightRequest() throws Exception {
	MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.options("/foo")
			.header("Origin", "http://domain.com")
			.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "POST")
			);

	RequestMappingInfo info = paths("/foo").methods(RequestMethod.POST).build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);
	assertNotNull(match);

	info = paths("/foo").methods(RequestMethod.OPTIONS).build();
	match = info.getMatchingCondition(exchange);
	assertNull("Pre-flight should match the ACCESS_CONTROL_REQUEST_METHOD", match);
}
 
private RequestMappingInfo assertComposedAnnotationMapping(String methodName, String path,
		RequestMethod requestMethod) throws Exception {

	Class<?> clazz = ComposedAnnotationController.class;
	Method method = clazz.getMethod(methodName);
	RequestMappingInfo info = this.handlerMapping.getMappingForMethod(method, clazz);

	assertNotNull(info);

	Set<PathPattern> paths = info.getPatternsCondition().getPatterns();
	assertEquals(1, paths.size());
	assertEquals(path, paths.iterator().next().getPatternString());

	Set<RequestMethod> methods = info.getMethodsCondition().getMethods();
	assertEquals(1, methods.size());
	assertEquals(requestMethod, methods.iterator().next());

	return info;
}
 
@Override
public void afterPropertiesSet() {
	this.config = new RequestMappingInfo.BuilderConfiguration();
	this.config.setPatternParser(getPathPatternParser());
	this.config.setContentTypeResolver(getContentTypeResolver());

	super.afterPropertiesSet();
}
 
/**
 * Delegates to {@link #createRequestMappingInfo(RequestMapping, RequestCondition)},
 * supplying the appropriate custom {@link RequestCondition} depending on whether
 * the supplied {@code annotatedElement} is a class or method.
 * @see #getCustomTypeCondition(Class)
 * @see #getCustomMethodCondition(Method)
 */
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
	RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
	RequestCondition<?> condition = (element instanceof Class ?
			getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
	return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
 
private void updateConsumesCondition(RequestMappingInfo info, Method method) {
	ConsumesRequestCondition condition = info.getConsumesCondition();
	if (!condition.isEmpty()) {
		for (Parameter parameter : method.getParameters()) {
			MergedAnnotation<RequestBody> annot = MergedAnnotations.from(parameter).get(RequestBody.class);
			if (annot.isPresent()) {
				condition.setBodyRequired(annot.getBoolean("required"));
				break;
			}
		}
	}
}
 
@Test
public void createEmpty() {
	RequestMappingInfo info = paths().build();

	PathPattern emptyPattern = (new PathPatternParser()).parse("");
	assertEquals(Collections.singleton(emptyPattern), info.getPatternsCondition().getPatterns());
	assertEquals(0, info.getMethodsCondition().getMethods().size());
	assertEquals(true, info.getConsumesCondition().isEmpty());
	assertEquals(true, info.getProducesCondition().isEmpty());
	assertNotNull(info.getParamsCondition());
	assertNotNull(info.getHeadersCondition());
	assertNull(info.getCustomCondition());
}
 
@Test
public void prependPatternWithSlash() {
	RequestMappingInfo actual = paths("foo").build();
	List<PathPattern> patterns = new ArrayList<>(actual.getPatternsCondition().getPatterns());
	assertEquals(1, patterns.size());
	assertEquals("/foo", patterns.get(0).getPatternString());
}
 
@Test
public void matchPatternsCondition() {
	MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/foo"));

	RequestMappingInfo info = paths("/foo*", "/bar").build();
	RequestMappingInfo expected = paths("/foo*").build();

	assertEquals(expected, info.getMatchingCondition(exchange));

	info = paths("/**", "/foo*", "/foo").build();
	expected = paths("/foo", "/foo*", "/**").build();

	assertEquals(expected, info.getMatchingCondition(exchange));
}
 
@Test
public void matchParamsCondition() {
	ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/foo?foo=bar"));

	RequestMappingInfo info = paths("/foo").params("foo=bar").build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);

	assertNotNull(match);

	info = paths("/foo").params("foo!=bar").build();
	match = info.getMatchingCondition(exchange);

	assertNull(match);
}
 
@Test
public void matchHeadersCondition() {
	MockServerHttpRequest request = MockServerHttpRequest.get("/foo").header("foo", "bar").build();
	ServerWebExchange exchange = MockServerWebExchange.from(request);

	RequestMappingInfo info = paths("/foo").headers("foo=bar").build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);

	assertNotNull(match);

	info = paths("/foo").headers("foo!=bar").build();
	match = info.getMatchingCondition(exchange);

	assertNull(match);
}
 
@Test
public void matchConsumesCondition() {
	MockServerHttpRequest request = MockServerHttpRequest.post("/foo").contentType(MediaType.TEXT_PLAIN).build();
	ServerWebExchange exchange = MockServerWebExchange.from(request);

	RequestMappingInfo info = paths("/foo").consumes("text/plain").build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);

	assertNotNull(match);

	info = paths("/foo").consumes("application/xml").build();
	match = info.getMatchingCondition(exchange);

	assertNull(match);
}
 
@Test
public void matchProducesCondition() {
	MockServerHttpRequest request = MockServerHttpRequest.get("/foo").accept(MediaType.TEXT_PLAIN).build();
	ServerWebExchange exchange = MockServerWebExchange.from(request);

	RequestMappingInfo info = paths("/foo").produces("text/plain").build();
	RequestMappingInfo match = info.getMatchingCondition(exchange);

	assertNotNull(match);

	info = paths("/foo").produces("application/xml").build();
	match = info.getMatchingCondition(exchange);

	assertNull(match);
}
 
@Test
public void pathPrefix() throws Exception {
	this.handlerMapping.setEmbeddedValueResolver(value -> "/${prefix}".equals(value) ? "/api" : value);
	this.handlerMapping.setPathPrefixes(Collections.singletonMap(
			"/${prefix}", HandlerTypePredicate.forAnnotation(RestController.class)));

	Method method = UserController.class.getMethod("getUser");
	RequestMappingInfo info = this.handlerMapping.getMappingForMethod(method, UserController.class);

	assertNotNull(info);
	assertEquals(Collections.singleton(new PathPatternParser().parse("/api/user/{id}")),
			info.getPatternsCondition().getPatterns());
}
 
@Test
public void resolveRequestMappingViaComposedAnnotation() throws Exception {
	RequestMappingInfo info = assertComposedAnnotationMapping("postJson", "/postJson", RequestMethod.POST);

	assertEquals(MediaType.APPLICATION_JSON_VALUE,
		info.getConsumesCondition().getConsumableMediaTypes().iterator().next().toString());
	assertEquals(MediaType.APPLICATION_JSON_VALUE,
		info.getProducesCondition().getProducibleMediaTypes().iterator().next().toString());
}
 
@Test // SPR-14988
public void getMappingOverridesConsumesFromTypeLevelAnnotation() throws Exception {
	RequestMappingInfo requestMappingInfo = assertComposedAnnotationMapping(RequestMethod.POST);

	ConsumesRequestCondition condition = requestMappingInfo.getConsumesCondition();
	assertEquals(Collections.singleton(MediaType.APPLICATION_XML), condition.getConsumableMediaTypes());
}
 
@Test // gh-22010
public void consumesWithOptionalRequestBody() {
	this.wac.registerSingleton("testController", ComposedAnnotationController.class);
	this.wac.refresh();
	this.handlerMapping.afterPropertiesSet();
	RequestMappingInfo info = this.handlerMapping.getHandlerMethods().keySet().stream()
			.filter(i -> {
				PatternsRequestCondition condition = i.getPatternsCondition();
				return condition.getPatterns().iterator().next().getPatternString().equals("/post");
			})
			.findFirst()
			.orElseThrow(() -> new AssertionError("No /post"));

	assertFalse(info.getConsumesCondition().isBodyRequired());
}
 
源代码30 项目: Moss   文件: AdminControllerHandlerMapping.java
private RequestMappingInfo withPrefix(RequestMappingInfo mapping) {
    if (!StringUtils.hasText(adminContextPath)) {
        return mapping;
    }
    PatternsRequestCondition patternsCondition = new PatternsRequestCondition(
        withNewPatterns(mapping.getPatternsCondition().getPatterns()));
    return new RequestMappingInfo(patternsCondition, mapping.getMethodsCondition(), mapping.getParamsCondition(),
        mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(),
        mapping.getCustomCondition());
}