[RESOLVIDO] Vraptor - Ntlm nullpointerexception

Estou tentando pegar o usuário que está logado em uma máquina cliente, porém estou com o seguinte problema:

Erro:

com.google.inject.ProvisionException: Guice provision errors:

1) Error injecting constructor, java.lang.NullPointerException
  at br.com.controlador.InicioController.<init>(InicioController.java:41)
  at br.com.caelum.vraptor.ioc.guice.GuiceComponentRegistry.bindToConstructor(GuiceComponentRegistry.java:151)
  while locating br.com.controlador.InicioController

Meu controller:

@Resource
public class InicioController implements Serializable {
	private static final long serialVersionUID = 1L;
	private final Result resultado;
	private UsuarioSessao usuarioSessao;
	private Usuario usuario;
	private HttpServletRequest request;
	
	public InicioController(Result resultado, UsuarioSessao usuarioSessao,
			Usuario usuario, HttpServletRequest request) {
		this.resultado = resultado;
		this.usuarioSessao = usuarioSessao;
		this.usuario = usuario;
		this.request = request;

		NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication) request.getSession()
				.getAttribute("NtlmHttpAuth");
		usuario.setLogin(auth.getUsername());
		usuarioSessao.setUsuario(usuario);
	}

	@Publico
	@Get("/")
	public void index() {

	}
}

Como proceder?

Você pode começar lendo a mensagem da exceção:

[quote]Error injecting constructor, java.lang.NullPointerException
at br.com.controlador.InicioController.<init>(InicioController.java:41)[/quote]

Isso indica que você tem um erro na linha 41 do construtor da classe InicioController. Como não sei qual seria essa linha, vou chutar a mais óbvia:

Isso pode ter sido ocasionado por este trecho aqui:

A variável auth provavelmente veio nula.

Fiz o seguinte:

Servlet:

public class ControlServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication) request.getSession()
					.getAttribute("NtlmHttpAuth");
		
		UsuarioSessao us = new UsuarioSessao();
		Usuario u = new Usuario();
		u.setLogin(auth.getUsername());
		us.setUsuario(u);
		
	    response.sendRedirect("/projeto/");
		
	}
	
}

InicioController:

@Resource
public class InicioController implements Serializable {
	private static final long serialVersionUID = 1L;
	private final Result resultado;
	private UsuarioSessao usuarioSessao;
	
	public InicioController(Result resultado, UsuarioSessao usuarioSessao) {
		this.resultado = resultado;
		this.usuarioSessao = usuarioSessao;
	}

	@Publico
	@Get("/")
	public void index() {
		System.out.println(this.usuarioSessao.getUsuario().getLogin());
	}
}

Tentei pegar a sessao do usuário pelo Controller, mas ela veio vazia.
Como colocar o usuário na sessão e conseguir resgatá-la no InicioController?

se vc faz new UsuarioSessao(), não eh o objeto que o VRaptor ta gerenciando…

tente nao usar servlet, fazer usando um controller do vraptor.

Acontece que essa chamada no controller da nullpointexception:

NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication) request.getSession()  
                    .getAttribute("NtlmHttpAuth"); 
auth.getUsername();

Fiz um debug aki e desconfiei que o controller executa antes do jsp, por isso ele não consegue pegar esse valor.
Por esse motivo optei de pegar por Servlet.
Como posso resolver isso?

se o atributo tá na sessão, é indiferente…

o nullpointer tá dando porque auth tá nulo, certo?

o nome do atributo da sessão está correto?

Então, para eu pegar a sessão pelo controller, eu tenho que passar o HttpSevletRequest pelo construtor da classe, certo?

@Resource
public class InicioController implements Serializable {
	private static final long serialVersionUID = 1L;
	private final Result resultado;
	private UsuarioSessao usuarioSessao;
	private Usuario usuario;
	private HttpServletRequest request;
	
	public InicioController(Result resultado, UsuarioSessao usuarioSessao,
			Usuario usuario, HttpServletRequest request) {
		this.resultado = resultado;
		this.usuarioSessao = usuarioSessao;
		this.usuario = usuario;
		this.request = request;

		NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication) request.getSession()
				.getAttribute("NtlmHttpAuth");
		usuario.setLogin(auth.getUsername());
		usuarioSessao.setUsuario(usuario);
	}

	@Publico
	@Get("/")
	public void index() {

	}
}

Ai da erro na hora de dar um getUsername() no objeto auth, porque está nulo.
O engraçado é que no Servlet não da erro nenhum. Eu acho q o problema é esse HttpServletRequest que o controller n ta pegando. Por isso ele não ta pegando a sessão direitinho.

então… vc pode até receber HttpSession direto no construtor…

talvez vc tenha que registrar algum filtro ou alguma outra coisa antes do filtro do vraptor pra esse cara funcionar…

o problema é que o session.getAttribute(“NtlmHttpAuth”) está vindo nulo…

não sei como esse cara funciona ou quem popula ele… precisa ver na documentação como ele funciona.

Consegui resolver da seguinte forma, creio que não é a melhor solução, mas está funcionando.

ControlServlet

public class ControlServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication) request.getSession()
				.getAttribute("NtlmHttpAuth");

		request.getSession().setAttribute("ntlm", auth.getUsername());
		
		System.out.println("Servlet: " + auth.getUsername());

		response.sendRedirect("/projeto/");

	}

}

InicioController

@Resource
public class InicioController implements Serializable {
	private static final long serialVersionUID = 1L;
	private final Result resultado;
	private UsuarioSessao usuarioSessao;
	private Usuario usuario;
	private HttpServletRequest request;
	
	public InicioController(Result resultado, UsuarioSessao usuarioSessao,
			Usuario usuario, HttpServletRequest request) {
		this.resultado = resultado;
		this.usuarioSessao = usuarioSessao;
		this.usuario = usuario;
		this.request = request;
	}

	@Publico
	@Get("/")
	public void index() {
		System.out.println("Controller: " + request.getSession().getAttribute("ntlm"));
	}
}

no controller vc pode receber direto o HttpSession, ao invés de fazer request.getSession()

Verdade, já fiz a alteração aki e funcionou 100%. Vlw