-
-
Save amaralani/2e310d0f2855c8f0a6c50724e5cab03a to your computer and use it in GitHub Desktop.
Logging all request mappings and their parameters in Spring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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