Improve logging of request mapping information

Issue: SPR-17450
This commit is contained in:
Rossen Stoyanchev
2018-11-16 17:30:18 -05:00
parent 539cfc24c6
commit c89e6c616a
4 changed files with 68 additions and 16 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.web.reactive.result.method;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -28,6 +29,8 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;
import reactor.core.publisher.Mono;
@@ -202,7 +205,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup<T>) method -> getMappingForMethod(method, userType));
if (logger.isTraceEnabled()) {
logger.trace("Mapped " + methods.size() + " handler method(s) for " + userType + ": " + methods);
logger.trace(formatMappings(userType, methods));
}
methods.forEach((key, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(key, userType);
@@ -211,6 +214,24 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
}
}
private String formatMappings(Class<?> userType, Map<Method, T> methods) {
String formattedType = Arrays.stream(userType.getPackage().getName().split("\\."))
.map(p -> p.substring(0, 1))
.collect(Collectors.joining(".", "", ".")) + userType.getSimpleName();
Function<Method, String> methodFormatter = method -> Arrays.stream(method.getParameterTypes())
.map(Class::getSimpleName)
.collect(Collectors.joining(",", "(", ")"));
return methods.entrySet().stream()
.map(e -> {
Method method = e.getKey();
return e.getValue() + ": " + method.getName() + methodFormatter.apply(method);
})
.collect(Collectors.joining("\n\t", "\n\t" + formattedType + ":" + "\n\t", ""));
}
/**
* Register a handler method and its unique mapping. Invoked at startup for
* each detected handler method.

View File

@@ -18,6 +18,7 @@ package org.springframework.web.reactive.result.method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.lang.Nullable;
@@ -307,24 +308,28 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
@Override
public String toString() {
StringBuilder builder = new StringBuilder("{");
builder.append(this.patternsCondition);
if (!this.methodsCondition.isEmpty()) {
builder.append(",methods=").append(this.methodsCondition);
Set<RequestMethod> httpMethods = this.methodsCondition.getMethods();
builder.append(httpMethods.size() == 1 ? httpMethods.iterator().next() : httpMethods);
}
if (!this.patternsCondition.isEmpty()) {
Set<PathPattern> patterns = this.patternsCondition.getPatterns();
builder.append(" ").append(patterns.size() == 1 ? patterns.iterator().next() : patterns);
}
if (!this.paramsCondition.isEmpty()) {
builder.append(",params=").append(this.paramsCondition);
builder.append(", params ").append(this.paramsCondition);
}
if (!this.headersCondition.isEmpty()) {
builder.append(",headers=").append(this.headersCondition);
builder.append(", headers ").append(this.headersCondition);
}
if (!this.consumesCondition.isEmpty()) {
builder.append(",consumes=").append(this.consumesCondition);
builder.append(", consumes ").append(this.consumesCondition);
}
if (!this.producesCondition.isEmpty()) {
builder.append(",produces=").append(this.producesCondition);
builder.append(", produces ").append(this.producesCondition);
}
if (!this.customConditionHolder.isEmpty()) {
builder.append(",custom=").append(this.customConditionHolder);
builder.append(", and ").append(this.customConditionHolder);
}
builder.append('}');
return builder.toString();

View File

@@ -18,6 +18,7 @@ package org.springframework.web.servlet.handler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -28,6 +29,8 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -272,7 +275,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
}
});
if (logger.isTraceEnabled()) {
logger.trace("Mapped " + methods.size() + " handler method(s) for " + userType + ": " + methods);
logger.trace(formatMappings(userType, methods));
}
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
@@ -281,6 +284,24 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
}
}
private String formatMappings(Class<?> userType, Map<Method, T> methods) {
String formattedType = Arrays.stream(userType.getPackage().getName().split("\\."))
.map(p -> p.substring(0, 1))
.collect(Collectors.joining(".", "", ".")) + userType.getSimpleName();
Function<Method, String> methodFormatter = method -> Arrays.stream(method.getParameterTypes())
.map(Class::getSimpleName)
.collect(Collectors.joining(",", "(", ")"));
return methods.entrySet().stream()
.map(e -> {
Method method = e.getKey();
return e.getValue() + ": " + method.getName() + methodFormatter.apply(method);
})
.collect(Collectors.joining("\n\t", "\n\t" + formattedType + ":" + "\n\t", ""));
}
/**
* Register a handler method and its unique mapping. Invoked at startup for
* each detected handler method.

View File

@@ -17,6 +17,7 @@
package org.springframework.web.servlet.mvc.method;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpMethod;
@@ -316,24 +317,28 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
@Override
public String toString() {
StringBuilder builder = new StringBuilder("{");
builder.append(this.patternsCondition);
if (!this.methodsCondition.isEmpty()) {
builder.append(",methods=").append(this.methodsCondition);
Set<RequestMethod> httpMethods = this.methodsCondition.getMethods();
builder.append(httpMethods.size() == 1 ? httpMethods.iterator().next() : httpMethods);
}
if (!this.patternsCondition.isEmpty()) {
Set<String> patterns = this.patternsCondition.getPatterns();
builder.append(" ").append(patterns.size() == 1 ? patterns.iterator().next() : patterns);
}
if (!this.paramsCondition.isEmpty()) {
builder.append(",params=").append(this.paramsCondition);
builder.append(", params ").append(this.paramsCondition);
}
if (!this.headersCondition.isEmpty()) {
builder.append(",headers=").append(this.headersCondition);
builder.append(", headers ").append(this.headersCondition);
}
if (!this.consumesCondition.isEmpty()) {
builder.append(",consumes=").append(this.consumesCondition);
builder.append(", consumes ").append(this.consumesCondition);
}
if (!this.producesCondition.isEmpty()) {
builder.append(",produces=").append(this.producesCondition);
builder.append(", produces ").append(this.producesCondition);
}
if (!this.customConditionHolder.isEmpty()) {
builder.append(",custom=").append(this.customConditionHolder);
builder.append(", and ").append(this.customConditionHolder);
}
builder.append('}');
return builder.toString();