[Resolvido] Vraptor - Anotação @HeaderParam não considerada

5 respostas
paulog

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);
	}
}

5 Respostas

Lucas_Cavalcanti

Parece um bug do vraptor mesmo =(

tenta colocar @HeaderParam(“accept”) String accept

faz o bugfix lá no código do vraptor por favor?

se não quiser implementar, abra uma issue, por favor: https://github.com/caelum/vraptor/issues

Valeu

paulog

Ok Lucas. Obrigado pela resposta!

Mas qual seria a solução a ser implementada?

Ajustar o ParametersInstantiatorInterceptor para que ele defina no Parâmetros do Request no lugar de definir no Atributos?
Ou ajustar o IogiParametersProvider para buscar nos atributos do request?

Lucas_Cavalcanti

a sua solução: request.setParameter(parameters[i], value);

no arquivo que eu linkei antes

paulog

Para quem quiser acompanhar: https://github.com/caelum/vraptor/pull/455

Lucas_Cavalcanti

obrigado paulog… já comentei lá =)

Criado 13 de agosto de 2012
Ultima resposta 27 de ago. de 2012
Respostas 5
Participantes 2