Skip to content

Instantly share code, notes, and snippets.

@amaralani
Created November 21, 2020 10:35
Show Gist options
  • Save amaralani/2e310d0f2855c8f0a6c50724e5cab03a to your computer and use it in GitHub Desktop.
Save amaralani/2e310d0f2855c8f0a6c50724e5cab03a to your computer and use it in GitHub Desktop.
Logging all request mappings and their parameters in Spring
/**
* A listener to listen on {@link ContextRefreshedEvent}.
*/
@Log4j
@Component
public class EndpointsListener implements ApplicationListener<ContextRefreshedEvent> {
/**
* Provides access to all view controllers defined in {@link SpringConfig}.
*/
private final HandlerMapping viewControllerHandlerMapping;
/**
* Constructor.
*
* @param viewControllerHandlerMapping View Controller Handler Mapping.
*/
public EndpointsListener(HandlerMapping viewControllerHandlerMapping) {
this.viewControllerHandlerMapping = viewControllerHandlerMapping;
}
/**
* On context refresh, get all request handler mappings and create a list.
* Also get the view controller mappings from {@link #viewControllerHandlerMapping} and add to the list.
*
* @param event A {@link ContextRefreshedEvent}.
*/
@SneakyThrows
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
List<CustomMapping> mappings = new ArrayList<>();
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : applicationContext
.getBean(RequestMappingHandlerMapping.class).getHandlerMethods().entrySet()) {
RequestMappingInfo requestMappingInfo = entry.getKey();
HandlerMethod handlerMethod = entry.getValue();
CustomMapping mapping = new CustomMapping();
mapping.setMethods(requestMappingInfo.getMethodsCondition().getMethods()
.stream().map(Enum::name).collect(Collectors.toSet()));
mapping.setPatterns(requestMappingInfo.getPatternsCondition().getPatterns());
Arrays.stream(handlerMethod.getMethodParameters()).forEach(methodParameter -> {
CustomParameter parameter = new CustomParameter();
Annotation[] parameterAnnotations = methodParameter.getParameterAnnotations();
Arrays.stream(parameterAnnotations).forEach(annotation -> {
if (annotation instanceof PathVariable) {
PathVariable pathVariable = (PathVariable) annotation;
mapping.getPathVariables()
.add(new CustomPathVariable(pathVariable.name(), pathVariable.required()));
} else if (annotation instanceof RequestParam) {
RequestParam requestParam = (RequestParam) annotation;
parameter.setName(requestParam.name());
String defaultValue = requestParam.defaultValue();
if (!defaultValue.equals(ValueConstants.DEFAULT_NONE)) {
parameter.setDefaultValue(defaultValue);
}
parameter.setRequired(requestParam.required());
parameter.setType(methodParameter.getParameter().getType().getSimpleName());
mapping.getParams().add(parameter);
}
});
});
mappings.add(mapping);
}
((SimpleUrlHandlerMapping) viewControllerHandlerMapping).getHandlerMap().forEach((s, o) -> {
CustomMapping mapping = new CustomMapping();
mapping.setMethods(Collections.singleton("GET"));
mapping.setPatterns(Collections.singleton(s));
mappings.add(mapping);
});
mappings.sort(Comparator.comparing(o -> o.getPatterns().stream().findFirst().orElse("")));
log.info(new ObjectMapper().writeValueAsString(mappings));
}
/**
* Custom mapping class.
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Data
public class CustomMapping {
private Set<String> patterns;
private Set<String> methods;
private List<CustomParameter> params = new ArrayList<>();
private List<CustomPathVariable> pathVariables = new ArrayList<>();
}
/**
* Custom Parameter class
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class CustomParameter {
private String name;
private String type;
private String defaultValue;
private Boolean required;
}
/**
* Custom path variable class.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@Data
public class CustomPathVariable {
private String name;
private Boolean required;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment