0

I'm a little confused about exactly how annotations work so I could not locate the answer to this easily, even if it was right in front of my eyes without an explanation.

Lets say for example we have this class

//this happens to be a Spring annotation in this case
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = " not found")
class NotFoundException extends RuntimeException {

    public NotFoundException(String resourceName) {
        //get access to reason from class's annotation
        reason = resourceName + reason;
    }
}

How do I get access to the annotation's parameter reason at runtime? Is this even possible? If so, I know reflection is involved, but not completely sure the right way to do it.

JNYRanger
  • 6,829
  • 12
  • 53
  • 81
  • Are you asking in general or are you actually trying to get it in that piece of code? If the latter, why are you doing this? You own that source code, there's no reason for you to parse an annotation only to re-apply it to the code that is annotated. – Sotirios Delimanolis Feb 19 '15 at 02:21
  • Which class's annotation - is it always NotFoundException that you want to access the annotation from? – user253751 Feb 19 '15 at 02:21
  • @SotiriosDelimanolis am trying to get it. I was just trying to see I i can get access to it as a shortcut instead of writing a generic message and still only using a single exception to handle all cases. – JNYRanger Feb 19 '15 at 02:22
  • @immibis Yes. I want to access the annotation that's decorated the class itself. – JNYRanger Feb 19 '15 at 02:23
  • Again, it doesn't make sense to me. If you have a `NotFoundException`, then the reason should always be `"not found"`. Just add it literally in the String concatenation. There's no reason to get it from an annotation. – Sotirios Delimanolis Feb 19 '15 at 02:23
  • @SotiriosDelimanolis I know that I can do that way and just leave it, but I wanted to customize the reason parameter's value depending on the resource that's throwing the exception at runtime. – JNYRanger Feb 19 '15 at 02:25
  • 1
    Right, so just do `String reason = resourceName + "not found";`. No reason to retrieve the annotation (or to even have it). – Sotirios Delimanolis Feb 19 '15 at 02:25
  • 1
    @SotiriosDelimanolis Because that wouldn't send out the value of the annotation's reason parameter when I want that HTTP error to be returned...would it? This is for a rest api built with Spring Framework – JNYRanger Feb 19 '15 at 02:30

2 Answers2

2

immibis has shown you the technical way to retrieve attributes from annotations.

I see no reason to do this however. For one, as the javadoc of ResponseStatus#reason states

If this element is not set, it will default to the standard status message for the status code. Note that due to the use of HttpServletResponse.sendError(int, String), the response will be considered complete and should not be written to any further.

You probably want the standard status message to be written to the response rather than your own.

If you still want your own, I would define a constant expression and refer to that whenever you need the reason, instead of retrieving it from the annotation.

@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = NotFoundException.REASON)
class NotFoundException extends RuntimeException {
    static final String REASON = " not found"; // you can define this in another class

    public NotFoundException(String resourceName) {
        String something = resourceName + REASON;
    }
}
Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Ok this makes a lot of sense in the context of that annotation, which is what I was actually trying to accomplish. Sounds like I should just let it be. – JNYRanger Feb 19 '15 at 02:39
1

You can read the annotation's reason with:

String reason = NotFoundException.class.getAnnotation(ResponseStatus.class).reason();

You cannot change values in an annotation.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • Gotcha, this is what I was looking for. i guess I'll have to write custom handlers when I want to change the message. Thanks! – JNYRanger Feb 19 '15 at 02:33