Perché devo loggarmi 2 volte?!?

di il
15 risposte

Perché devo loggarmi 2 volte?!?

Le mie classi sembrano scritte correttamente, non trovo errori eppure funzionano male. In pratica devo scrivere le mie credenziali 2 volte.
La prima volta che inserisco le credenziali ottengo questo:

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
	at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:488)
	at web1.LoginFiltrata.doPost(LoginFiltrata.java:47)
ma alla riga 47 non ci sono errori!
response.sendRedirect("/admin/route.jsp");
Se inserisco nuovamente le credenziali una seconda volta va tutto liscio e mi loggo senza problemi.
Quando la URL inizia con '/' il server parte da 'localhost:8080/' che è quello che voglio.
Il problema si è manifestato quando ho modificato l'urlPatterns della servlet in questo modo:
@WebServlet(urlPatterns = "/admin/privatezone.jsp")
Le mie classi sono perfette, non capisco dove sia l'errore!
FiltroA.java (al momento non utilizzato)

package web1;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(
        filterName = "FiltroA",
        urlPatterns = "/admin/*",
        description = "Filtra le pagine .jsp dentro la cartella 'admin' o le Servlet che puntano a /admin/*."
)
public class FiltroA implements Filter {
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request,response);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    @Override
    public void destroy() {
    }
}
FiltroB.java

package web1;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebFilter(
        filterName = "FiltroB",
        urlPatterns = "/admin/*",
        description = "Filtra le pagine .jsp dentro la cartella 'admin' o le Servlet che puntano a /admin/*."
)
public class FiltroB implements Filter {
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpSession session = ((HttpServletRequest) request).getSession();
        String UserID = (String) session.getAttribute("UserID");
        if(UserID == null){
            ((HttpServletResponse) response).sendRedirect("/index.jsp");
        }
        try {
            chain.doFilter(request,response);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    @Override
    public void destroy() {
    }
}
LoginFiltrata.java

package web1;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(urlPatterns = "/admin/privatezone.jsp")
public class LoginFiltrata extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("07.La Servlet sta processando il metodo doPost");
        HttpSession session = request.getSession();
        String UserID = request.getParameter("UserID");
        String Password = request.getParameter("Password");
        FromStringToHash HashText = new FromStringToHash(Password, "pall0");
        ServletContext context = getServletContext();
        String fullPath = context.getRealPath("/WEB-INF/users.txt");
        File fileUtenti = new File(fullPath);
        UserDB udb = new UserDB();
        udb.loadFile(fileUtenti);
        if (udb.authenticateUser(UserID, HashText.getHashText())) {
            session.setAttribute("UserID", UserID);
        }
        response.sendRedirect("/admin/route.jsp");
    }
}
web.xml

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <display-name>Esercitazione 1</display-name>
    <filter>
        <filter-name>FiltroA</filter-name>
        <filter-class>web1.FiltroA</filter-class>
    </filter>
    <filter>
        <filter-name>FiltroB</filter-name>
        <filter-class>web1.FiltroB</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FiltroA</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>FiltroB</filter-name>
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
index.jsp

<form action="/admin/privatezone.jsp" method="POST">
    <p><input type="text" name="UserID"></p>
    <p><input type="password" name="Password"></p>
    <p><input type="submit" value="Invia"></p>
</form>

15 Risposte

  • Re: Perché devo loggarmi 2 volte?!?

    giannino1995 ha scritto:


        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {
            HttpSession session = ((HttpServletRequest) request).getSession();
            String UserID = (String) session.getAttribute("UserID");
            if(UserID == null){
                ((HttpServletResponse) response).sendRedirect("/index.jsp");
            }
            try {
                chain.doFilter(request,response);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
    Sono sicuro di avertelo già segnalato:

    1) Questo filtro NON deve creare una nuova sessione se non c'è già (ora stai usando getSession() ).

    2) Se non c'è la sessione, il session sarebbe null. E lo DEVI testare.

    3) Se fai un sendRedirect NON devi poi far procedere con il chain.doFilter.

    giannino1995 ha scritto:


    
    <!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd" >
    <web-app>
        <display-name>Esercitazione 1</display-name>
        <filter>
            <filter-name>FiltroA</filter-name>
            <filter-class>web1.FiltroA</filter-class>
        </filter>
        <filter>
            <filter-name>FiltroB</filter-name>
            <filter-class>web1.FiltroB</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>FiltroA</filter-name>
            <url-pattern>/admin/*</url-pattern>
        </filter-mapping>
        <filter-mapping>
            <filter-name>FiltroB</filter-name>
            <url-pattern>/admin/*</url-pattern>
        </filter-mapping>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>
    
    L'uso delle nuove annotation (Servlet 3.0+) @WebFilter, @WebServlet è una ALTERNATIVA alle dichiarazioni nel web.xml.
    O usi un modo o usi l'altro. Mai entrambi.

    E c'è anche da tenere presente una cosa. Quando si definiscono i filter nel web.xml, l'ordine in cui i filtri vengono "incatenati" tra di loro (per stesso url-pattern) dipende dall'ordine in cui si presentano nel web.xml. Insomma, un ordine prestabilito è possibile.
    Quando si usa @WebFilter, purtroppo non è possibile stabilire un ordine. Quindi si deve prestare attenzione se due @WebFilter matchano le stesse cose.
  • Re: Perché devo loggarmi 2 volte?!?

    Hai perfettamente ragione! Bravissimo! Chissà però perché prima funzionava tutto.
    Ho risolto con questo codice:
    FiltroB.java
    
    if (request instanceof HttpServletRequest & response instanceof HttpServletResponse) {
                if(((HttpServletRequest) request).getSession(false).getAttribute("UserID")==null){
                    if(((HttpServletRequest) request).getParameter("UserID")==null){
                        ((HttpServletResponse) response).sendRedirect("/admin/privatezone.jsp");
                    }
                } else {
                    try {
                        chain.doFilter(request,response);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
            
    È corretto procedere in questo modo?
    Mi sono sempre chiesto come fosse possibile gestire più filtri sulle stesse URL con le annotazioni e mi hai appena risposto. Semplicemente fantastico.
    Vorrei ora usare anche il FiltroA per fare qualcosa. Mi spiace eliminarlo dall’esercitazione perché mi aiuta a capire e a ricordare come gestire più filtri sulle stesse servlet/jsp. Cosa potrei testare nel filtro A? Hai qualche suggerimento? Può servire verificare che l’utente abbia un IP? Hai idee migliori?
    Ciao e grazie mille!
  • Re: Perché devo loggarmi 2 volte?!?

    giannino1995 ha scritto:


    
    if (request instanceof HttpServletRequest & response instanceof HttpServletResponse) {
                if(((HttpServletRequest) request).getSession(false).getAttribute("UserID")==null){
                    if(((HttpServletRequest) request).getParameter("UserID")==null){
                        ((HttpServletResponse) response).sendRedirect("/admin/privatezone.jsp");
                    }
                } else {
                    try {
                        chain.doFilter(request,response);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
            
    È corretto procedere in questo modo?
    No.
    Primo, è fumoso, non servono quei instanceof. E basta tenersi 2 variabili sfruttando solo 2 cast diretti. Tutti i servlet container che conosco lavorano con HTTP, quindi quegli oggetti request/response sono sicuramente quelli Http***.
    Secondo: il UserID lo stai prendendo come parametro dalla request, NON dalla session !

    Terzo (extra): c'è una questione che non so se ti è chiara. Se non c'è l'utente "loggato", il filtro dovrebbe fare il redirect ad una pagina di "login". La request che il client (browser) fa per quella pagina di login NON dovrebbe passare per il filtro! Insomma la pagina di login è "per tutti" (autenticati o no che siano).
    Se per caso, per come è definito il url-pattern del filtro, esso becca la request alla pagina di login, dovresti essere tu a far passare "liscia" la richiesta all'interno del filtro, testando l'url della richiesta ("se è per la pagina di login, fai comunque il chain.doFilter").

    Se il tuo filtro matcha "/admin/*" e fai un redirect a privatezone.jsp che è sotto la /admin, allora ripassi nel filtro! E il client-browser va in "loop" continuo! (poi dopo un po' il browser si "rompe" e ti segnala redirect errato ..)

    Infine, nota bene che se l'url che passi a sendRedirect inizia con "/" questo slash è relativo alla server-root, NON alla context-root. Insomma, ci vuole il nome della webapp davanti se è deployata sotto un certo nome (cioè se non è "/").


    Guarda, ecco qualcosa di meglio (scritto al volo/parziale):
    @WebFilter(
        filterName = "PrivateZoneFilter",
        urlPatterns = "/admin/*"
    )
    public class PrivateZoneFilter implements Filter {
        // .....
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest httpReq = (HttpServletRequest) req;
            HttpServletResponse httpRes = (HttpServletResponse) res;
    
            if (isUserLogged(httpReq)) {
                chain.doFilter(httpReq, httpRes);
            } else {
                httpRes.sendRedirect("/nomewebapp/login.jsp");  // non è sotto la /admin
            }
        }
    
        private static boolean isUserLogged(HttpServletRequest httpReq) {
            HttpSession session = httpReq.getSession(false);
    
            if (session == null) {
                // eventuale logging sul fatto che non c'è una sessione
                return false;
            }
    
            String userId = (String) session.getAttribute("UserID");
    
            if (userId == null) {
                // eventuale logging sul fatto che non c'è il Id utente
                return false;
            }
    
            return true;
        }
    }
    Nota come è molto pulito e comprensibile: "se loggato procedi, else-altrimenti fai il redirect alla pagina di login"
  • Re: Perché devo loggarmi 2 volte?!?

    andbin ha scritto:


    Infine, nota bene che se l'url che passi a sendRedirect inizia con "/" questo slash è relativo alla server-root, NON alla context-root. Insomma, ci vuole il nome della webapp davanti se è deployata sotto un certo nome (cioè se non è "/").
    Grazie andbin, ho compreso cosa non mi è chiaro. Il mio problema è racchiuso in questa tua frase. Mi spiegheresti la differenza tra 'server-root' e 'context-root'? Inoltre dove trovo su IntelliJ il nome della mia webapp?
    Ho provato a mettere un sacco di nomi ma non risolvo. Inoltre mi piacerebbe creare un filtro riutilizzabile in altri progetti, se scrivo qualcosa di specifico relativo a questo progetto non credo sia il massimo. Non mi è proprio chiaro come scrivere queste URL...
    Inoltre è più corretto intercettare con il filtro la servlet responsabile dell'autenticazione ovvero la classe che crea l'attributo nella sessione oppure solo le altre? Entrambe le soluzioni sono realizzabili ma quale a tuo avviso sono quelle più corrette e prudenti?

    P.S.: Infatti il tuo codice continua a darmi problemi sui redirect (lo script sotto fornisce pagina bianca e nessun errore lato IDE):
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpReq = (HttpServletRequest) request;
            HttpServletResponse httpRes = (HttpServletResponse) response;
            if (isUserLogged(httpReq)) {
                chain.doFilter(httpReq, httpRes);
            } else {
                if(isUserAuthenticating(httpReq)){
                    httpRes.sendRedirect("/admin/privatezone.jsp"); // l'errore e' qui!!!!!!!!!!!!!!
                } else {
                    httpRes.sendRedirect("/index.jsp");
                }
            }
        }
        private static boolean isUserLogged(HttpServletRequest httpReq) {
            HttpSession session = httpReq.getSession(false);
            if (session == null) {
                return false;
            }
            String userId = (String) session.getAttribute("UserID");
            if (userId == null) {
                return false;
            }
            return true;
        }
        private static boolean isUserAuthenticating(HttpServletRequest httpReq) {
            String UserID = httpReq.getParameter("UserID");
            if (httpReq != null) {
                return true;
            }
            return false;
        }
        
  • Re: Perché devo loggarmi 2 volte?!?

    Ho risolto semplicemente escludendo la servlet di autenticazione dal filtro però non ho capito perché l'applicazione va in loop.

    In pratica sembra che l'applicazione sappia che la servlet non sia una semplice servlet ma sia una servlet di autenticazione e quindi non la legge proprio (se dentro la servlet scrivo System.out… ecc… non vedo nulla in console!) perché la url che do allo script è corretta!

    Per sicurezza ho anche usato questo codice:
        public String getLink(HttpServletRequest httpReq, String URL) {
            String scheme = httpReq.getScheme() + "://";
            String serverName = httpReq.getServerName();
            String serverPort = (httpReq.getServerPort() == 80) ? "" : ":" + httpReq.getServerPort();
            String contextPath = httpReq.getContextPath();
            String fullPath = null;
            try {
                StringBuilder sb = new StringBuilder("");
                sb.append(scheme);
                sb.append(serverName);
                sb.append(serverPort);
                sb.append(contextPath);
                sb.append(URL);
                fullPath = sb.toString();
            }catch(Exception e){
                throw new RuntimeException(e);
            }
            return fullPath;
        }
    Impossibile leggere la servlet di autenticzione!
  • Re: Perché devo loggarmi 2 volte?!?

    giannino1995 ha scritto:


    Mi spiegheresti la differenza tra 'server-root' e 'context-root'?
    http://nomehost/nomecontesto/bla/bla/bla......
                   ?            ?
            server-root      context-root
    Gli url che scrivi nel web.xml e nelle annotation @WebServlet/@WebFilter sono relativi alla context-root, perché sono sicuramente (e ovviamente) sotto la applicazione.

    Quindi se una servlet l'hai mappata con es.
        <servlet-mapping>
            <servlet-name>XyzServlet</servlet-name>
            <url-pattern>/xyzservlet.html</url-pattern>
        </servlet-mapping>
    Allora lo slash in /xyzservlet.html è relativo alla context-root, ovvero la servlet risponderà a

    http://nomehost/nomecontesto/xyzservlet.html

    Idem per un include/forward che sono interni alla webapp.

    Diverso invece è il caso del redirect. Il redirect lo fa il client (browser), che non "sa" nulla di ciò che sta lato server (nemmeno che dietro ci sia una webapp JavaEE !). Per il client/browser sono solo url in generale e basta. Quindi per un redirect lo "/" iniziale è alla radice del server.

    giannino1995 ha scritto:


    Inoltre dove trovo su IntelliJ il nome della mia webapp?
    Conosco poco IntelliJ IDEA. L'ho usato solo per mie esercitazioni con JavaFX e Kotlin. Mai per webapp. Tra l'altro hai la versione "Community"? Perché questa se ben ricordo NON ha supporto diretto per sviluppi in Java EE e se vuoi fare qualcosa (non so ora quanto possibile) devi "sporcarti" un po' le mani.

    Comunque non so dire ora. In genere il nome del contesto è di base il nome del progetto ma può essere cambiato (in Eclipse è così).

    giannino1995 ha scritto:


    Inoltre mi piacerebbe creare un filtro riutilizzabile in altri progetti, se scrivo qualcosa di specifico relativo a questo progetto non credo sia il massimo.[/b]
    Domandati: che cosa vorresti tenere comune (e quindi riutilizzabile) e cosa invece potrebbe cambiare da un progetto all'altro?

    Ad esempio:
    - l'url (o gli url) del filtro potrebbero cambiare da un progetto all'altro. In un progetto potresti avere una "/admin" e in un altro "/private" come percorso base per le zone "protette". Bene: vuol dire che NON devi usare l'annotation @WebFilter, perché altrimenti vai a "cablare", fissare nel codice l'url.
    - che cosa metti in sessione. Vuoi solo mettere uno username? O altri dati dell'utente (magari un oggetto di classe User)? Questo sarebbe facilmente astraibile.
    - il nome dell'attributo in sessione. Ammesso che hai deciso cosa tenere in sessione, in un progetto potresti voler mettere un "UserID" e in un altro un "LoggedUserKey". Bene, il NOME di questo attributo lo si può parametrare con un <init-param> del filter nel web.xml.

    Comunque, scusa se lo dico, ma al momento se/come rendere qualcosa riutilizzabile tra progetti diversi dovrebbe essere la tua ULTIMA preoccupazione.

    giannino1995 ha scritto:


    Inoltre è più corretto intercettare con il filtro la servlet responsabile dell'autenticazione ovvero la classe che crea l'attributo nella sessione oppure solo le altre? Entrambe le soluzioni sono realizzabili ma quale a tuo avviso sono quelle più corrette e prudenti?
    Il filtro di cui abbiamo parlato finora lo ripeto che serve per uno scopo: IMPEDIRE ad utenti non "loggati" di accedere ad aree del sito che invece dovrebbero essere solo per utenti "autenticati".

    Se la richiesta della pagina di login viene beccata anche da questo filtro .. sostanzialmente ti stai dando la classica zappa sui piedi ...

    giannino1995 ha scritto:


    P.S.: Infatti il tuo codice continua a darmi problemi sui redirect (lo script sotto fornisce pagina bianca e nessun errore lato IDE):
    Credo ... spero, che ora hai più chiara la questione degli url.

    giannino1995 ha scritto:


        private static boolean isUserAuthenticating(HttpServletRequest httpReq) {
            String UserID = httpReq.getParameter("UserID");
            if (httpReq != null) {
                return true;
            }
            return false;
        }
        
    Te lo ripeto ancora: questo NON ha senso. Non devi prendere un parametro UserID dalla request!!!
    Il filtro potrebbe matchare tante richieste, pure a risorse "statiche" (se le metti nell'area protetta) es. .css, .js., immagini ecc..
    Non ha senso cercare un parametro in questo caso.

    E poi scusa if (httpReq != null) non ha senso, httpReq non può essere null a meno che hai fatto pasticci tu chiamando quel metodo.
  • Re: Perché devo loggarmi 2 volte?!?

    1.Tutto chiaro, mille grazie. Nel mio progetto però 'nomecontesto' non esiste.

    2.Per igiene, regola, buon costume, ecc... quando si usa la maiuscola e quando la minuscola per classi, metodi, servlet, jsp, variabili, ecc...?

    3.Se rimando l'utente che ha sbagliato a scrivere la password o l'user nella pagina di login e desidero che si trovi ciò che ha scritto come posso fare? Devo per forza creare una variabile di sessione con i valori inseriti e poi nella pagina di login ripescarli oppure c'è qualche metodo più furbo?

    ciao
  • Re: Perché devo loggarmi 2 volte?!?

    giannino1995 ha scritto:


    2.Per igiene, regola, buon costume, ecc... quando si usa la maiuscola e quando la minuscola per classi, metodi, servlet, jsp, variabili, ecc...?
    per buona regola puoi tenere tutto minuscolo e buonanotte.
    La notazione c.d. "ungherese" (e le sue varie evoluzioni) arrivano da un trentennio addietro, introdotta da un programmatore Microsoft, e poi abbandonata perfino da questa (in realtà solo in parte, per ragioni di compatibilità storica).

    Troverai guide e suggerimenti di ogni tipo: suggerisco di applicare la seconda legge dell'informatica (se è semplice, FORSE, funziona), senza complicarsi la vita (che è già abbastanza complicata di suo)
  • Re: Perché devo loggarmi 2 volte?!?

    +m2+ ha scritto:


    giannino1995 ha scritto:


    2.Per igiene, regola, buon costume, ecc... quando si usa la maiuscola e quando la minuscola per classi, metodi, servlet, jsp, variabili, ecc...?
    per buona regola puoi tenere tutto minuscolo e buonanotte.
    La notazione c.d. "ungherese" (e le sue varie evoluzioni) arrivano da un trentennio addietro, introdotta da un programmatore Microsoft, e poi abbandonata perfino da questa (in realtà solo in parte, per ragioni di compatibilità storica).

    Troverai guide e suggerimenti di ogni tipo: suggerisco di applicare la seconda legge dell'informatica (se è semplice, FORSE, funziona), senza complicarsi la vita (che è già abbastanza complicata di suo)
    Mille grazie.

    Per il punto 3 ho creato un metodo di questo tipo:
        public String writeStrSessionParameter(HttpServletRequest request, String Parameter){
            try {
                String strParameter = "";
                HttpSession session = request.getSession(false);
                System.out.println(session==null);
                if (session != null) {
                    strParameter = (String) session.getAttribute(Parameter);
                    if (strParameter != null) {
                        return strParameter;
                    } 
                }
                return "";
            }catch (Exception e){
                return "";
            }
        }
    che funziona ma la cosa strana è che stampa in console 'false' anche quando mi collego alla index.jsp per la prima volta. All'inizio dovrei leggere true non false! Quando non ho sessioni attive session==null dovrebbe dare true non false! Perché?
  • Re: Perché devo loggarmi 2 volte?!?

    andbin ha scritto:


    if (session == null) {
                // eventuale logging sul fatto che non c'è una sessione
                return false;
            }
    
    Non è inutile questo codice? Nella mia applicazione non capita mai di avere una sessione nulla.
    Anche quando non ho ancora una sessione, session è comunque diverso da null.

    Mi cade il mondo addosso, avevo letto che session era null se mai creata... Anche io come te andbin credevo che in alcune circostanze session potesse essere null ma non è così...
  • Re: Perché devo loggarmi 2 volte?!?

    giannino1995 ha scritto:


    Nel mio progetto però 'nomecontesto' non esiste.
    La webapp un nome del contesto lo DEVE avere. Al limite può essere "/" (cioè context-root e server-root coincidono ma questo va impostato esplicitamente, non lo hai mai per default!)

    Ma poi scusa, gli url della tua webapp li sai/vedi no? Dimmi un url della tua webapp che metti nel browser che ti mostra qualcosa.
    Il nome del contesto lo vedi ....

    giannino1995 ha scritto:


    2.Per igiene, regola, buon costume, ecc... quando si usa la maiuscola e quando la minuscola per classi, metodi, servlet, jsp, variabili, ecc...?
    Basta che cerchi in rete: java naming conventions

    giannino1995 ha scritto:


    3.Se rimando l'utente che ha sbagliato a scrivere la password o l'user nella pagina di login e desidero che si trovi ciò che ha scritto come posso fare? Devo per forza creare una variabile di sessione con i valori inseriti e poi nella pagina di login ripescarli oppure c'è qualche metodo più furbo?
    Una servlet riceve la richiesta di autenticazione, se non va bene fa un forward alla pagina jsp.

    giannino1995 ha scritto:


    Non è inutile questo codice? Nella mia applicazione non capita mai di avere una sessione nulla.
    Anche quando non ho ancora una sessione, session è comunque diverso da null.

    Mi cade il mondo addosso, avevo letto che session era null se mai creata... Anche io come te andbin credevo che in alcune circostanze session potesse essere null ma non è così...
    Il filtro NON deve creare sessioni inutilmente (non è quello il suo compito). Quindi deve usare il getSession(false)
    Se la sessione c'è, la restituisce. Altrimenti se non c'è NON la crea e restituisce null.
    Quindi il null lo DEVI testare.

    Scusa ma leggi/ascolti quello che ti viene detto?? Perché l'ho detto più volte ...
  • Re: Perché devo loggarmi 2 volte?!?

    Non ricordo di aver mai impostato nulla e le URL della mia webapp sono queste:
    http://localhost:8080/index.js
    http://localhost:8080/admin/route.js
    ecc…
    Non capisco il discorso del forward e neppure quando dici di testare null…
  • Re: Perché devo loggarmi 2 volte?!?

    Ho fatto delle ricerche per questo forward ma ho trovato questo codice:
     
    String nextJSP = "/index.jsp";
    RequestDispatcher dispatcher = request.getServletContext().getRequestDispatcher(nextJSP);
    dispatcher.forward(request,response);
    
    che ho testato e ritestato in mille modi diversi ma non funziona.
    Se metto il codice nella Servlet, ritornando nella index.jsp i dati immessi inizialmente dal client non sono presenti.
    Ho quindi deciso di salvare le variabili in sessione. Il procedimento è un pochetto più articolato ma fa quello che deve fare. Mi spiace non aver capito le potenzialità di questo forward. Se volete potete spiegarmelo.
    Nel mio programma resta un piccolissimo problema e che vi spiego con un esempio.
    L’utente Alfa ha come password Beta. Se Alfa scrive una password sbagliata gli compare il messaggio di errore, fin qui tutto ok. Se riscrive la password corretta accede all’applicazione. Il problema si ha quando l’utente, una volta che ha fatto accesso alla pagina privata (/admin/route.jsp) ritorna alla home (/index.jsp) con il tasto indietro del browser. Alfa ritornando alla index.jsp e sottolineo da utente autenticato legge il messaggio di errore. Se nella index.jsp faccio un refresh il problema scompare così volevo sapere se c’era modo di costringere il browser a ricaricare la pagina da capo senza però mettere in allarme il client con lag strani e forse ancor più spiacevoli.
    Ho già provato ad usare questi codici:
    <meta http-equiv="cache-control" content="no-cache"/>
    <body onload="document.nome_form.reset();">
    ma nulla da fare, il problema persiste.
    Per quanto riguarda il discorso “verificare se esiste oppure no una sessione” ho fatto le mie ricerche ma non ho trovato nulla.
    Questo codice non funziona, in console non trovo nulla.
    
    private static boolean isUserLogged(HttpServletRequest httpReq) {
            HttpSession session = httpReq.getSession(false);
            try{
                session.isNew();
            }catch(IllegalStateException e){
                System.out.println("non esiste una sessione!");
                return false;
            }
            if(session==null){
                System.out.println("non esiste una sessione!");
                return false;
            }
            if(session.equals(null)){
                System.out.println("non esiste una sessione!");
                return false;
            }
            String UserID = (String) session.getAttribute("UserID");
            if (UserID == null) {
                return false;
            }
            return true;
        } 
    
    Fonte: https://docs.oracle.com/javaee/6/api/?javax/servlet/http/HttpSession.html
    Se mi schiarisci le idee sarei felice perché quando chiamo index.jsp che è una semplice pagina statica non dovrei avere sessioni attive. Se poi testo il filtro scrivendo http://localhost:8080/admin/route.js in Firefox, il browser mi rimanda a http://localhost:8080/index.js senza scrivermi in console “non esiste una sessione!”.
    Se scrivo nella index.jsp questo in cima alla pagina:
    
    <%
    session = request.getSession(false);
        if(session==null){
            System.out.println("non esiste una sessione!");
        }
    %>
    
    non leggo in console “non esiste una sessione!”.
  • Re: Perché devo loggarmi 2 volte?!?

    Ho provato anche con manifest di html5 ma non risolto il problema dell'avviso. Non esiste una specifica <%@ ... %> in java che risolve la cosa? Voi come risolvete nei vostro programmi questo problema?
    ciao
Devi accedere o registrarti per scrivere nel forum
15 risposte