Estou tentando criar um Interceptor com accepts validando uma anotacao especifica, para converter automaticamente o retorno dos métodos para json.
A ideia é que todos os métodos com essa anotação tenham seu retorno convertido automaticamente para json.
Como recupero o retorno dos métodos no Interpector?
Consegui resolver!
Estudando o core do VRaptor no github, encontrei um observer chamado OutjectResult que “ouve” um event chamado MethodExecuted que pega o retorno do método executado e escreve no Result.
Sobrescrevi esse observer e anotei com @Specializes, verificando se o método executado possui a minha anotação e escrevendo o retorno do método como json invés de inclui-lo no result.
Segue a classe implementada:
import java.lang.reflect.Type;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Specializes;
import javax.inject.Inject;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.MethodInfo;
import br.com.caelum.vraptor.events.MethodExecuted;
import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.observer.OutjectResult;
import br.com.caelum.vraptor.view.Results;
@Specializes
public class JsonOutjectResult extends OutjectResult {
/**
* @deprecated CDI eyes only
*/
protected JsonOutjectResult() {
this(null);
}
@Inject
public JsonOutjectResult(TypeNameExtractor extractor) {
super(extractor);
}
@Override
public void outject(@Observes MethodExecuted event, Result result, MethodInfo methodInfo) {
Type returnType = event.getMethodReturnType();
if (methodInfo.getControllerMethod().containsAnnotation(ProducesJson.class)) {
if (!returnType.equals(Void.TYPE)) {
result.use(Results.json()).withoutRoot().from(methodInfo.getResult()).recursive().serialize();
}
} else {
super.outject(event, result, methodInfo);
}
}
}