Estou usando a funcionalidade de receber os headers da requisição diretamente nos métodos dos controladores. (Discussão sobre o recurso aqui: [url]https://github.com/caelum/vraptor/issues/405[/url])
O método no controlador é descrito abaixo. Em linhas gerais, o método usa o Header Accept para determinar se a requisição deve ou não ser redirecionada.@Post("/logout")
public void metodo(@HeaderParam("Accept") String accept) {
// ....
}
Porém, o parâmetro accept sempre vem nulo. Pesquisando um pouco, determinei que o ParametersInstantiatorInterceptor é o responsável por verificar se o método possui parâmetros com anotação @HeaderParam e determinar o seu respectivos valores.
Na linhas 103-105, ele realiza o seguinte:HeaderParam headerParam = (HeaderParam) annotation;
String value = request.getHeader(headerParam.value());
request.setAttribute(headerParam.value(), value);
Notei, que para mim, há duas coisas estranhas:
Primeiro, está definindo o valor no Attribute do request.
Segundo, o "alias" do atributo é o nome do Header, e não o nome do parâmetro.
Verifiquei que há dois ParametersProvider (que provê os parâmetros para invocação do método):
IogiParametersProvider
OgnlParametersProvider
O Iogi é o padrão que o VRaptor está utilizando aqui. Ele, em nenhum momento, procura o valor do parâmetro nos attribute do Request (não encontrei pelo menos).
Pelo o que eu vi, o Ognl faz isso. Entretanto, não consegui mudar para que o VRaptor utilize ele.
Questão?
Porque o VRaptor não está definindo os valores do parâmetro corretamente? Algum erro de configuração?
A anotação @HttpParam só é compatível com o OgnlParametersProvider?
===================================
Uma solução gambiosa que eu encontrei, foi criar um interceptador próprio para cuidar disso (mais fácil do que implementar o próprio ParametersProvider):
Definir direto com o parâmetro do Request, tudo funciona. Isso é o que me leva a achar estranho o uso dos atributos, descrito acima.
@Intercepts(before = ParametersInstantiatorInterceptor.class)
@Lazy
public class HeaderParametersInterceptor implements Interceptor {
private final MutableRequest request;
private final ParameterNameProvider nameProvider;
public HeaderParametersInterceptor(MutableRequest request, ParameterNameProvider nameProvider) {
this.request = request;
this.nameProvider = nameProvider;
}
@Override
public boolean accepts(ResourceMethod method) {
return method.getMethod().getParameterTypes().length > 0;
}
@Override
public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance) throws InterceptionException {
Method trueMethod = method.getMethod();
String[] parameters = nameProvider.parameterNamesFor(trueMethod);
Annotation[][] annotations = trueMethod.getParameterAnnotations();
for (int i = 0; i < annotations.length; i++) {
for (Annotation annotation : annotations[i]) {
if (annotation instanceof HeaderParam) {
HeaderParam headerParam = (HeaderParam) annotation;
String value = request.getHeader(headerParam.value());
request.setParameter(parameters[i], value);
}
}
}
stack.next(method, resourceInstance);
}
}