Session timeout DINAMICO

Galera estou usando o

10

para configurar o tempo em que a sessao vai aspirar, porem como meu sistema vai rodar em varias empresas diferentes, pode surgir a necessidade de cada cliente exigir um determinado tempo para aspirar a sessao, eu ate poderia barrar isso e deixar um tempo padarao para todas as empresas, mas pretendo deixar isso flexivel do jeito q o cliente achar melhor.

Alguem sabe uma boa forma de fazer isso, eu tinha pensando em uma tela de configuracao, porem eu nao sei como fazer isso na pratica, sou iniciante em java web e gostaria da ajuda de voces.
Valeu d+.

No objeto session você pode colocar o tempo.

session.setMaxInactiveInterval(time);// Em milisegundos

tudo bem Alberes, cara disculpa eu nao responder a sua ajuda, mas cara sera q ainda tem como vc me ajudar com essa minha duvida.

Tipo assim eu quero fazer uma tela de cadastro de tempo de sessao, esta tela ira alimentar uma tabela uma unica vez, na tabela sera salvo o tempo da sessao em minutos(ou segundos), quando o sistema for executado, pegar os dados da tabela e configurar o tempo da sessao. Assim eu terei um sistema dinamico onde o usuario pode expecificar o tempo da sessao de acordo com a sua necessidade.

vc me disse que eu poderia usar 1. session.setMaxInactiveInterval(time);// Em milisegundos, cara mas tipo assim sera que eu terei que deletar la no meu web.xml meu codigo:

10

Valeu Albertes, tudo bom…

Se você configurar o timeout no web.xml o sistem terá o comportamento padrão e caso você faça isso no servlet session.setMaxInactiveInterval(time); o sistema assume o do código, mas só se passar nesse ponto do código.

Agora o que você quer é:
Criar um tela de cadastro e salvar essas configurações, isso você poderá armazenar as informações em uma tabela ou arquivo e quando você inicializar o sistema você ler as configurações que foram armazenada e aplicar.

o objeto HttpSession

Algumas observações
Especificado em segundos (não em mili como tinha colocado) para cada solicitação, em outras palavras, o tempo será configurado a cada solicitação.

HttpSession.setMaxInactiveInterval(int interval);

Esse método um long que é o momento em que a sessão foi criada, isso é interessante quando você quer invalidar a sessão depois de um determinado momento.

HttpSession.getCreationTime();

Há duas formas de invalida a sessão do usuário

HttpSession.invalidate() ;
HttpSession.setMaxInactiveInterval(0);

Retorna um long.

HttpSession.getLastAccessedTime() ;

Um exemplo de como ficaria (não fiz o teste, segui o raciocinio)

Como o retorno é um long, você poderá criar uma data, considerei que o usuário tem um tempo por acesso e não por solicitação, caso seja essa segunda opção faça a adaptação

HttpSession session = request.getSession();
java.util.Date dataAtual = new java.util.Date();
// Assumindo que a data foi colocado quando o usuário logou, vou colocar em um código abaixo para não confundir
java.util.Date dataSessao = (java.util.Date())session.getAttribute("dataSessao");

// Se a data atual é menor que a data da sessao invalide a sessão
if(dataAtual.compareTo(dataSessao.getTime()) <= 0){
    session.invalidate() ;
}

Faça algo parecido quando o usuário logar ou caso não tenha login você pode verificar se a sessão foi criada com HttpSession.isNew() que retorna verdadeiro caso seja a primeira vez.
Faça algo parecido ou utilize o HttpSession.getCreationTime();

// No servlet
Integer timeConfig = (Integer)getServletContext().getAttribute("timeConfig");
// Data atual mais o tempo da sessão
java.util.Calendar dataSessao = Calendar.getInstance();
dataSessao.add(Calendar.HOUR, timeConfig);// Coloquei em horas, mas pode ser em minutos etc.
session.setAttribute("dataSessao", dataSessao.getTime());

Um outra coisa interessante são os listeners, você pode interceptar suas chamadas, existem para Sessão, solicitação, atributos, contexto etc.

Utilize esse o ServletContextListener para pegar as informações de configuração

ServletContextListener.contextInitialized(ServletContextEvent sce){    
    Integer timeConfig = //Consulta o BD ou arquivo e coloca o atributo no contexto
     sce.getServletContext().setAttribute("timeConfig", timeConfig);
}

Não fiz o teste, só coloquei uma idéia.

Consegui usar o session.setMaxInactiveInterval(time); dentro do filter.

public class SessionTimeoutFilter implements Filter {
private String timeoutPage = “forUserLogin.jsp”;

public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filterChain) throws IOException, ServletException {

    if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        // is session expire control required for this request?

        HttpSession session = ((HttpServletRequest) request).getSession();
        session.setMaxInactiveInterval(20);
        int tempo = session.getMaxInactiveInterval();

        if (isSessionControlRequiredForThisResource(httpServletRequest)) {

            // is session invalid?
            if (isSessionInvalid(httpServletRequest)) {
                String timeoutUrl = httpServletRequest.getContextPath() + "/" + getTimeoutPage();
                System.out.println("Session is invalid! redirecting to timeoutpage : " + timeoutUrl);
                httpServletResponse.sendRedirect(timeoutUrl);

                return;
            }
        }
    }
    filterChain.doFilter(request, response);
}

private boolean isSessionControlRequiredForThisResource(HttpServletRequest httpServletRequest) {
    String requestPath = httpServletRequest.getRequestURI();
    boolean controlRequired = !org.apache.commons.lang.StringUtils.contains(requestPath, getTimeoutPage());

    return controlRequired;
}

private boolean isSessionInvalid(HttpServletRequest httpServletRequest) {

    boolean sessionInValid = (httpServletRequest.getRequestedSessionId() != null) && !httpServletRequest.isRequestedSessionIdValid();
    return sessionInValid;

}

public void destroy() {
}

}

Mas ainda estou com um probleminha.
Nos meus diretorios minha classe usuarioLogin esta dentro de Projeto/telasComponentes/usuarioLogin.jsp

Exemplo do problema:
O usuario esta navegando no sistema e esta na tela Cadastro de Pessoa localizado dentro de Projeto/cadastro/cadPessoa.jsp, o usuario fica um tempo sem dar submite e entao a sessao expira, quando o usuario clica na tela deveria abrir a tela de Login pq a sessao expirou ne, porem o sistema da o seguinte erro:
The requested resource (/Projeto/cadastro/telasComponentes/usuarioLogin.jsp) is not available.
O sistema pega o endereco do filter "telasComponentes/usuarioLogin.jsp "e concatena com o endereço do diretorio de onde o usuario deu o ultim submit “Projeto/cadastro/”.

Dentro do meu filter eu redireciono httpServletResponse.sendRedirect(timeoutUrl); timeoutUrl = “forUserLogin.jsp”

A tela forUserLogin.jsp usa um javaScript para redirecionar para telasComponentes/usuarioLogin.jsf.

Index

Cara nao sei com arrumar isso eu imaginava que meu codigo javascript deveria redirecionar para “telasComponentes/usuarioLogin.jsf” independente de onde o usuario esteja no sistema, caiu a sessao redirecionar para “telasComponentes/usuarioLogin.jsf”;

Cara fico mei confuso mas sera q tem como dar um luz ai,
valeu…
thank you.

No servlet ou até mesmo no JSP (não recomendado) você pode fazer um forward/sendRedirect caso o usuário não esteja logado.

vou colocar um exemplo no servlet

// Se a sessão for nova o usuário fará o login
if(session.isNew()){
    RequestDispatch rd = getRequest().getRequestDispatcher("/login.jsp");    
    rd.forward(request, forward);
}

ou

Login login = (Login) session.getAttribute("login");// Assumi que pode existe o objeto Login
if(login == null){
    RequestDispatch rd = getRequest().getRequestDispatcher("/login.jsp");    
    rd.forward(request, forward);
}

Você pode usar o filter também, o código abaixo envia uma resposta para o navegador para fazer uma novar solicitação para url informada sem o usuário perceber, é automático, não precisa de javascript. O navegador recebe um código http para ser redirecionado.

httpServletResponse.sendRedirect(suaURL);
//onde url é algo como www.seusite.com

A diferença entre um forward e sendRedirect é que o forward enviar para um recurso (JSP ou servlet) no servidor enquanto o sendRedirect enviar para o navegador e o navegador faz um nova solicitação com base na url informada, você deverá utilizar a primeira opção, já que o recurso está no servidor.

Acho que é isso.

Eu estou meio que forçado a usar javaScript pq estou trabalhando com frames e usando httpServletResponse.sendRedirect(suaURL); eu nao estava conseguindo fazer direito, tipo assim eu consegui redirecionar para a tela de login porem meu frames principal (Menu) ficava sempre do lado, o javascript foi uma solucao para quando a sessao expirar eu conseguir redirecionar para login e ficar apenas a tela login aberta.

Agora o que ta me pegado e a questao do erro
The requested resource (/Projeto/cadastro/telasComponentes/usuarioLogin.jsp) is not available.

eu queria que meu javascript abrisse a tela de login independente de onde o usuario estivesse navegando

is not available é um http 404 se não estou enganado, tem como você colocar no web.xml um página padrão quando isso ocorrer.

Não sei se é a melhor opção para seu problema.

<error-page>
    <error-code>404</error-code>
    <location>/login.jsp</location>
</error-page>

Acho melhor você dar uma olhada na sua aplicação, acho que o servidor não encontrou seu jsp, por isso o “is not available”.