I have a class
(CreateAccountRequest
) that implement an interface
(Iloggable
), the interface has no method, Just for marking purpose.
public interface Iloggable {}
public class CreateAccountRequest implements Iloggable{
//some private fields, getters and setters
}
In my custom RequestBodyAdviceAdapter
class, trying to check if the request is an instance of Iloggable, to proceed or ignore the request (for instance do the logging or not )
I know we can use instanceOf
operator to check if an object implements an interface or not and the unit test as below approve it:
@Test
void CreateAccountRequest_Object_Instance_Of_Iloggable_Test() {
CreateAccountRequest request = new CreateAccountRequest();
assertTrue(request instanceof Iloggable);
}
But in RequestBodyAdviceAdapter supports method the result is false or true all the time, I tried different ways to distinguish if the parameter implement the interface or not
@ControllerAdvice
public class CustomRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
//if(methodParameter.getParameterType().isInstance(Iloggable.class)) //return false all the time
//if(methodParameter.getParameter().getType().isInstance(Iloggable.class))// return false all the time
if(methodParameter.getParameter().getClass().isInstance(Iloggable.class))// return false all the time
// if(type instanceof Iloggable)// return false all the time
//if(type.getClass().isInstance(Iloggable.class)) //return true all the time
//if(type != null && Iloggable.class.isAssignableFrom(type.getClass()))//return false all the time
return true;
return false;
}
//other override methods
}
For removing any doubt, I put a snapshot of the debugging in the support method:
CodePudding user response:
You want to make sure that type represents a class that implements Illoggable.
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
if ( type instanceof Class ) {
cls = ( Class ) type;
result = Iloggable.class.isAssignableFrom( cls );
} else {
result = false;
}
return result;
}
CodePudding user response:
In this case type
is a java.lang.reflect.Type
(instance) and not an CreateAccountRequest
(instance;)
You could get more lucky with:
if (type instanceof Class) { // type != null
Class<?> aClazz = (Class<?>) type;
return Iloggable.class.isAssignableFrom(aClazz);
}
Class.isAssignableFrom(...)
-javadoc-17
In depth:
-
if(type instanceof Iloggable) //always false, because type is the // (java.lang.reflect.)Type(->class) (occasionally) of the Iloggable and not/ever an instance of it.
-
if(type.getClass().isInstance(Iloggable.class)) //equivalent to // java.lang.reflect.Type.class.isInstance(Iloggable.class) // always false, except when Iloggable *implements* Type (pervert, but possible!;)
-
Iloggable.class.isAssignableFrom(type.getClass()) //incorporates // my "wrong assumptions" on type... type.getClass() would // evaluate to java.lang.reflect.Type.class, which is similar to bullet 2
But I assume (when correctly used -> experiment) some MethodParameter methods should also lead to the desired. Especially:
CodePudding user response:
Try following comparison, target.getTypeName()==Iloggable.class.getTypeName()