Olá a todos… vou explicar o que eu fiz e o que esta faltando fazer…
Estou usando JSF 2.1 e primefaces 2.2.1, implementei em meu site uma verificação de aviso de sessão expirada usando Filter, nao vou colar a classe inteira pra dar uma economizada, se for o caso eu posto ela depois, mas enfim, tenho essa classe que uso pra verificar se o usuario tem acesso a página solicitada e agora para verificar se a sessão expiroupublic class FiltrarRestricoes implements Filter, Serializable {pra quem usa, sabe q a classe possui os métodos init, doFilter e destroy e no doFilter é onde eu faço as validações, uso o seguinte código para verificar se a sessão expiroutry {
chain.doFilter(request, response);
} catch (Exception ex) {
if (ex instanceof javax.servlet.ServletException) {
Throwable t = ex.getCause();
if (t instanceof javax.faces.application.ViewExpiredException) {
oQueFazer = "sessaoExpirada.xhtml";
} else {
ex.printStackTrace();
}
}
}e depois dependendo do valor dessa String oQueFazer, eu redireciono pra algum lugar, no caso a pagina sessãoExpirada.xhtml.
isto está funcionando com links, mas não com requisições ajax, por exemplo, combobox estado atualizando combobox cidades, se a sessão está expirada, ele nao atualiza o combobox cidade mas tbem nao redireciona, nem da erro nem nd…
o que eu preciso saber é como verificar se a sessão está expirada em requisições ajax, alguem tem alguma idéia ?
Cara, tenta fazer com javascript.
O JQuery tem a função ajaxError, como o primefaces usa JQuery, ele deve ter algo parecido.
Usando o sendRedirect para as requisições ajax não vai funcionar porque elas não tem “poder” de alterar a página, mas se você tratar o erro em javascript deve funcionar.
Acho que dá até pra você detectar no seu Filter se uma requisição é em javascript vendo se o header possui XMLHttpRequest, por exemplo:
if ("XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"))) {
// requisição em ajax
// pode mandar aqui alguma informação pelo reponse.getWriter, por exemplo, para ser recebida no javascript da página
} else {
// requisições normais pode fazer só o sendRedirect
}
o problema q estou tendo é que nao consigo capturar o estado da sessão do faces, ó codigo abaixo sempre imprime nullif (FacesContext.getCurrentInstance() == null) {
System.out.println("faces null");
} else {
System.out.println("faces criado");
}e se eu usarHttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();tbem nao funciona, o httpsession não é o mesmo que a session do faces…
a unica maneira q eu consigo verificar o estado da sessão do faces na minha classe filter, é usando aquele try catch sitado no primeiro post
Alguma idéia pra verificar o estado da sessão dentro do ifif ("XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"))) {
}
Cara, nao entendi direito o problema. Parece que voce já tá com a faca e queijo na mao, meu velho.
No seu filtro, voce recebe um ServletRequest (que é um HttpServletRequest). Esse cara vai ter um metodo getSession(), que irá te retornar a sessão corrente ou criará uma (por padrao).
Entao, suponho que voce poderia fazer algo assim no seu filtro:
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpSession session = httpRequest.getSession(false) //NAO cria uma nova sessao
if (session == null)
//a sessao expirou
Ademais, o erro que está tratando, ViewExpiredException, não é necessariamente a mesma coisa que uma sessão expirada
affff, consegui enchergar onde eu tava errando depois da sua mensagem alias, nao tinha atentado ao parametro para criar sessao no metodo getSession(false) eu tava usando sem parametro, ai ele sempre criava uma nova sessao, então no final das contas ficou assim[code]HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession(false);
if (“XMLHttpRequest”.equalsIgnoreCase(req.getHeader(“x-requested-with”))) {
if (session == null) {
System.out.println(“requisição ajax - sessão null”);
resp.sendRedirect(“sessaoExpirada.xhtml”);
} else {
System.out.println(“requisição ajax - sessao criada”);
}
}[/code]mas ele nao consegue redirecionar se a sessao estiver terminada, qual é a maneira correta agora de proceder? criar uma nova sessão antes de redirecionar para a pagina de sessãoExpirada, acho isso meio fora de lógica, o erro que acontece é java.lang.IllegalStateException: Cannot create a session after the response has been committed
como proceder agora, nao sei…
se puderem me ajudar, agradeço, vou continuar dando uma pesquisada aqui pra ver se encontro a solução…
vlw t+
Vixe, essa exceção é um capeta hehe, mas é exatamente o que a descrição diz, sua aplicação está tentando manipular a resposta após ela ter sido despachada, talvez em algum filtro? Tem mais filtros aí no seu projeto?
Coloque ai o codigo desse seu xhtml e a pilha de erro (se nao forem muito grandes :lol: , brincadeira, poe aí que a gente tenta ajudar)
só nao repara que ta uma bagunça, de tanto teste q to fazendo aqui kkkkk depois eu vou melhorar o codigo assim q descobrir como as coisas funcionam
metodo doFilter[code]@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession(false);
String currentPage = req.getRequestURL().toString();
if ("XMLHttpRequest".equalsIgnoreCase(req.getHeader("x-requested-with"))) {
if (session == null) {
System.out.println("requisição ajax - sessão null");
resp.encodeURL("sessaoExpirada.xhtml");
} else {
System.out.println("requisição ajax - sessao criada");
}
// requisição em ajax
// pode mandar aqui alguma informação pelo reponse.getWriter, por exemplo, para ser recebida no javascript da página
}
//System.out.println("filtrar: " + currentPage);
if (session != null) {
boolean isRestrict = false;
if (currentPage != null) {
List<PaginasRestritas> paginasRestritas = (List<PaginasRestritas>) session.getAttribute("paginasRestritas");
if (paginasRestritas != null) {
//System.out.println("qtde: " + paginasRestritas.size());
for (PaginasRestritas pr : paginasRestritas) {
//System.out.println("pr: " + pr.getPagina());
if (currentPage.contains(pr.getPagina())) {
isRestrict = true;
break;
}
}
}
}
/*boolean isRestrict = false;
if (currentPage != null) {
if (currentPage.contains("enviarPromocoesCliente.xhtml")) isRestrict = true;
}*/
String oQueFazer = "doFilter";
if (isRestrict) {
Usuarios usuario = (Usuarios) session.getAttribute("usuarioLogado");
List<Acessos> acessos = (List<Acessos>) session.getAttribute("acessos");
if (usuario == null) {
oQueFazer = "index.xhtml";
} else {
boolean temAcesso = false;
for (Acessos a : acessos) {
if (currentPage.contains(a.getPaginasRestritasIdpaginasrestritas().getPagina())) {
temAcesso = true;
break;
}
}
if (temAcesso) {
//System.out.println("tem acesso, seguindo normal");
try {
chain.doFilter(request, response);
} catch (Exception ex) {
if (ex instanceof javax.servlet.ServletException) {
Throwable t = ex.getCause();
if (t instanceof javax.faces.application.ViewExpiredException) {
oQueFazer = "sessaoExpirada.xhtml";
} else {
ex.printStackTrace();
}
}
}
} else {
try {
resp.sendRedirect("index.xhtml");
} catch (Exception ex) {
if (ex instanceof javax.servlet.ServletException) {
Throwable t = ex.getCause();
if (t instanceof javax.faces.application.ViewExpiredException) {
oQueFazer = "sessaoExpirada.xhtml";
} else {
ex.printStackTrace();
}
}
}
}
}
} else {
//System.out.println("nao é restrito, seguindo normal");
try {
chain.doFilter(request, response);
if (session == null) {
System.out.println("sessão nula");
} else {
System.out.println("sessao criada");
}
} catch (Exception ex) {
if (ex instanceof javax.servlet.ServletException) {
Throwable t = ex.getCause();
if (t instanceof javax.faces.application.ViewExpiredException) {
oQueFazer = "sessaoExpirada.xhtml";
} else {
ex.printStackTrace();
}
}
}
}
if (oQueFazer.equals("sessaoExpirada.xhtml")) {
resp.sendRedirect("sessaoExpirada.xhtml");
} else if (oQueFazer.equals("index.xhtml")) {
System.out.println("redirecionar para index");
}
} else {
chain.doFilter(request, response);
}
}[/code]e o xhtm por exemplo o combobox de estado pra atualizar cidades[code]<h:selectOneMenu id="estados"
value="#{index.idEstadoSelecionado}"
style="font-family: Tahoma;font-size: 11px;width: 150px;height: 20px;">
<f:selectItems value="#{index.listaEstados}" />
<p:ajax event="change"
onerror="dlg.show();"
onstart="dlg.show();"
oncomplete="dlg.hide();"
listener="#{index.atualizarDDDsCidades(true)}"
update="ddds,cidades,garagens,ordenarCidades,ordenarGaragens,listaOrdenacao,infoAnunciosRecentes,tabelaAnunciosRecentes" />
</h:selectOneMenu>[/code]
Cara, veja que após o redirect voce chama o metodo doFilter() do FilterChain, que vai invocar o resto da pilha de filtros e continuar o processo de renderização. Voce NAO pode fazer isso, uma vez feito o redirect.
ai jesuis, hahah perai, essa é a primeira classe de filtro q to fazendo na vida, to meio perdido, vamos com calma, vamos nos concentrar no trecho de código abaixoif ("XMLHttpRequest".equalsIgnoreCase(req.getHeader("x-requested-with"))) {
if (session == null) {
System.out.println("requisição ajax - sessão null");
resp.sendRedirect("sessaoExpirada.xhtml");
} else {
System.out.println("requisição ajax - sessao criada");
}
// requisição em ajax
// pode mandar aqui alguma informação pelo reponse.getWriter, por exemplo, para ser recebida no javascript da página
} o que tiver abaixo desse codigo já esta funcionado, ou seja, as validaçoes de usuario logado e permissões de acesso as paginas…
o que eu preciso agora é no caso de uma requisição ajax, se a sessão estiver = null redirecionar para a pagina sessaoExpirada…
do jeito q tah ali, usando resp.sendRedirect(“sessaoExpirada.xhtml”) eu obtenho a seguinte excessao[quote]17/01/2012 16:52:00 com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/sessaoExpirada.xhtml]
java.lang.IllegalStateException: Cannot create a session after the response has been committed[/quote]tah blz, agora eu tenho q fazer o q? criar uma nova session antes de redirecionar ?
voce identificou que a sessao expirou. ok.
voce fez o response.sendRedirect(“suapagina.xhtml”). ok.
seguindo no codigo, voce tem um
if (session != null) {
//faz um monte de coisas
} else {
//essa linha NAO pode ser executada, pois voce JÁ redirecionou o response para outra pagina.
chain.doFilter(request, response);
}
entendeu? voce está fazendo o redirect, ok, mas está mandando a requisição corrente continuar…
tenho uma outra suspeita sobre o erro, mas tentemos essa opção primeiro…vamos fazer um laboratorio :lol:
do jeito q eu fiz agora, ele nem se quer abre a pagina inicial, pois se eu verificar se a sessao é null e redirecionar pra sessaoExpirada.xhtml logo quando carregar a pagina inicial a session ainda é null[code]public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession(false);
String currentPage = req.getRequestURL().toString();
o problema é q ao mudar de HttpSession session = req.getSession(); para HttpSession session = req.getSession(false); ele nao está mais criando a session ao carregar a pagina inicial
tah, dei uma arrumada na logica e agora tah assim[code]@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession(false);
String currentPage = req.getRequestURL().toString();
boolean isRestrict = false;
if (session != null) {
//pegos as paginas restritas, verifico se usuario tah logado e se ele tem permissão...
} else {
if ("XMLHttpRequest".equalsIgnoreCase(req.getHeader("x-requested-with"))) {
resp.sendRedirect("sessaoExpirada.xhtml");
} else {
try {
chain.doFilter(request, response);
} catch (Exception ex) {
if (ex instanceof javax.servlet.ServletException) {
Throwable t = ex.getCause();
if (t instanceof javax.faces.application.ViewExpiredException) {
resp.sendRedirect("sessaoExpirada.xhtml");
} else {
ex.printStackTrace();
}
}
}
}
}
}[/code]novamente cai no problema inicial, para links funciona, redireciona certinho para a sessaoExpirada.xhtml, mas no caso das requisições ajax ele nao redireciona, nao da erro nao faz nd, nao sei como fazer pra redirecionar no caso do cara clicar no combobox estados por ex, as cidades nao atualizam, nao da erro, nao redireciona...
na linha 13, pq ela nao redireciona ? isso q eu nao intendo, os outros sendRedirect funcionam
bom, pelo q eu to entendendo nas minhas pesquisas, é q ao utilizar ajax nao é feito um redirect na pagina, dai o pq de nao estar redirecionando, kkkk
e eu to vendo em vários lugares na net, que tem q retornar um erro, e em algum lugar da pagina tenho q ter um javascript que ao verificar o erro retornado, redirecione para a minha pagina de sessao expirada…
mas ainda nao consegui fazer isso, to tentando aqui…
tbem ja tentei varios javascripts q achei por ai como o tuliomonteazul sugeriu, mas nao da nem sinal, talvez eu esteja usando errado, veja como estou fazendo:
na index.xhtml[code]<h:head>
//outras tags…
<script type="text/javascript">$ = jQuery;</script>
<script type="text/javascript">
$.ajax({
statusCode: {
403: function() {
alert('page not found');
}
}
});
</script>
</h:head>[/code]e na classe Filter no mesmo codigo do post anterior[code]if ("XMLHttpRequest".equalsIgnoreCase(req.getHeader("x-requested-with"))) {
//resp.sendRedirect("sessaoExpirada.xhtml");
resp.sendError(403);
}[/code]
explicação básica, se a session for null, eu tento seguir o caminho normal, se a excessao de visão expirada for lançada, redireciono pra sessaoExpirada.xhtml, e no caso de ser uma requisição ajax, retorno o erro 403 pra pragina, e o javascript se encarrega de fazer o redirecionamento… e se a session nao for null, eu faço as validações necessárias, usuario logado, tem permissão pra acessar a pagina…