Is it possible to change the @RequestMapping
values on startup?
Basically what I want is to create an annotation @Api(Api.Version.V1)
which would mean that the request mapping should be modified from /api/dogs
to /api/v1/dogs
. I want to do this both on class level (apply to all) and on method level (re-using the controller from an earlier version, and modifying it).
I could hardcode this in, but this leaves a lot of strings to take care of, and it's not as clean as I want it.
So is it possible (using a bpp or something similar) to change the request mappings during startup? after beans have been created, I don't want/need to modify them.
I have been also looking into RequestCondition
but this seems to have a more dynamic nature, and I'm not sure it would help me in this case.
Another issue, I would like being able to annotation two classes with the same request mapping (and then let the annotation rewrite it), and I'm pretty sure this needs to be done on initial context load (so we don't get duplicate mappings etc).
Any pointers in the right direction would be appreciated.
Edit:
Got this almost working, I'm using a custom RequestMappingHandlerMapping
and overriding the method getMappingForMethod
, which allows me to get the annotations (on both type and method) and return a modified RequestMappingInfo
with the paths added.
One issue remains, even if I remove all old mappings and only return /api/v1/dogs
the old mapping to /api/dogs
still works. Is it possible to also remove this mapping somehow?
The code is here, if anyone is interested.
@Component
public class CustomRequestMappingHandlerMapping
extends RequestMappingHandlerMapping
{
@Override
protected RequestMappingInfo getMappingForMethod( Method method, Class<?> handlerType )
{
RequestMappingInfo info = super.getMappingForMethod( method, handlerType );
ApiVersion methodApiVersion = AnnotationUtils.findAnnotation( method, ApiVersion.class );
ApiVersion typeApiVersion = AnnotationUtils.findAnnotation( handlerType, ApiVersion.class );
if ( typeApiVersion == null )
{
return info;
}
Set<String> oldPatterns = info.getPatternsCondition().getPatterns();
Set<String> patterns = new HashSet<>();
for ( String p : oldPatterns )
{
for ( int v = 0; v < typeApiVersion.value().length; v++ )
{
ApiVersion.Version version = typeApiVersion.value()[v];
if ( !p.startsWith( version.getValue() ) )
{
if ( p.startsWith( "/" ) ) patterns.add( "/" + version.getValue() + p );
else patterns.add( "/" + version.getValue() + "/" + p );
}
else
{
patterns.add( p );
}
}
}
PatternsRequestCondition patternsRequestCondition = new PatternsRequestCondition(
patterns.toArray( new String[]{} ), null, null, true, true, null );
RequestMappingInfo mappingInfo = new RequestMappingInfo(
null, patternsRequestCondition, info.getMethodsCondition(), info.getParamsCondition(), info.getHeadersCondition(), info.getConsumesCondition(),
info.getProducesCondition(), info.getCustomCondition()
);
return mappingInfo;
}
}