Let's assume a controller object like this:
object Users extends Controller {
...
@ApiOperation(
httpMethod = "POST",
nickname = "authenticate",
value = "Authenticates an user",
notes = "Returns the JSON Web Token to be used in any subsequent request",
response = classOf[models.auth.api.Jwt])
def authenticate = SecuredAction[Users.type]("authenticate").async(parse.json) { implicit request =>
...
}
...
}
How do I get the annotation values of the authenticate
method at runtime? I've tried this:
def methodAnnotations[T: TypeTag]: Map[String, Map[String, Map[String, JavaArgument]]] = {
typeTag[T].tpe.declarations.collect { case m: MethodSymbol => m }.map { m =>
val methodName = m.name.toString
val annotations = m.annotations.map { a =>
val annotationName = a.tpe.typeSymbol.name.toString
val annotationArgs = a.javaArgs.map {
case (name, value) => name.toString -> value
}
annotationName -> annotationArgs
}.toMap
methodName -> annotations
}.toMap
}
methodAnnotations
returns the specified annotation for the specified method and is invoke like this:
val mAnnotations = methodAnnotations[T]
val nickname = mAnnotations("myMethodName")("MyAnnotationName")("myAnnotationMemberName").asInstanceOf[LiteralArgument].value.value.asInstanceOf[String]
The problem is that when I compile the code above I always get the following warnings:
type JavaArgument in trait Annotations is deprecated: Use `Annotation.tree` to inspect annotation arguments
method tpe in trait AnnotationApi is deprecated: Use `tree.tpe` instead
What's the correct way to get method annotations with scala 2.11?
Probably the solution suggested by Nate is the most clean and efficient... but in my case it would require too much refactoring, so I've just decided to still use Scala reflection. Here is my solution:
I hope it helps.