eclipse-ee4j / krazo

Apache License 2.0
51 stars 19 forks source link

Krazo disables validation for resources utilizing Content Negotiation #334

Closed erdlet closed 2 years ago

erdlet commented 2 years ago

At the moment I try to implement a example application supporting Content Negotiation, so it uses the same Jakarta REST resource for HTML (provided by MVC / Krazo) and JSON content. This works quite well, but when it comes to validation, Krazo disables it for the non-MVC resource because of using this utility method:

//org.eclipse.krazo.util.AnnotationUtils

public static <T extends Annotation> boolean hasAnnotationOnClassOrMethod(Class<?> clazz, Class<T> annotationType) {
        return hasAnnotation(clazz, annotationType)
                || Arrays.stream(clazz.getMethods()).anyMatch(m -> hasAnnotation(m, annotationType));
    }

This method would work fine if there is a separate controller for MVC and non-MVC resources, but this is exactly not what I want to achieve. So instead, we need to refactor this method to check the invoked method instead.

I did some debugging and saw, that at least the ValidationInterceptorContext used in the org.eclipse.krazo.jersey.validation.KrazoValidationInterceptor is aware of the request handling method and its annotations via context.getInvocable().getHandlingMethod().isAnnotationPresent(Controller.class), so the refactoring should be easy for this.

As I didn't had a look into the RestEasy implementation yet, I can't say if this is possible there too. I'll create a test application for it too.

erdlet commented 2 years ago

I created a reproducer project with RESTEasy and it works there. The GeneralValidator contains, in contrast to the Jersey interface, a method called public boolean isMethodValidatable(Method method) which seems to decide on the called Method directly and handles the request's validation properly.

Because of that, I'll try to fix the Jersey handling so Jersey and RESTEasy support Content Negotiation in mixed resources.