Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Pristup Session Objektu iz klase koja ne extends HttpServlet

[es] :: Java :: Pristup Session Objektu iz klase koja ne extends HttpServlet

[ Pregleda: 2306 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

semsudin
BIH

Član broj: 13751
Poruke: 58
109.175.46.*

Sajt: www.hostbih.com


Profil

icon Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 02:01 - pre 145 meseci
Zdravo

Web aplikacija koju trenutno radim je u Java Servlets, medjutim imam jedan problem.

Unutar projekta imama servlet klase koje nasleđuju HttpServlet i druge normalne klase koje ne nasleđuju HttpServlet.
Problem je u tome sto iz normalnih klasa koje ne nasleđuju HttpServlet ne mogu nikako da pristupim HttpSession objektu (iz HttpServletRequest).

Zna li neko neki metod u Javi koje je ekvivalentan C#-ovom:

Code:
System.Web.HttpContext.Current.Session("imesesije")
 
Odgovor na temu

antix

Član broj: 8388
Poruke: 265
*.adsl.verat.net.

Jabber: antix@elitesecurity.org


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 09:24 - pre 145 meseci
Bojim se da nećeš moći ovako da odradiš to što želiš. Najpametnije je da predaješ HttpSession instancu kao parametar toj tvojoj klasi. Postojao je u HttpSessionContext interface-u takav metod ali je zbog potencijalnih security problema deprecated.
 
Odgovor na temu

semsudin
BIH

Član broj: 13751
Poruke: 58
92.36.196.*

Sajt: www.hostbih.com


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 12:24 - pre 145 meseci
Citat:
Bojim se da nećeš moći ovako da odradiš to što želiš. Najpametnije je da predaješ HttpSession instancu kao parametar toj tvojoj klasi. Postojao je u HttpSessionContext interface-u takav metod ali je zbog potencijalnih security problema deprecated.


Ma znam ja za tu mogucnost ali da mi je da ne prosljeđujem HttpSession pošto imam puno klasa i ne bih da svakoj prosljeđujem HttpSession .
Pored klasa u njima imam puno i stitic metoda kojima bi morao takodjer proslijedjivati HttpSession.
Iz ovog razloga bih volio da mogu pokupiti HttpSession direktno, bez proslijeđivanja.


Ovo mi je ovo potrebno radi mini db persitance frameworka kojeg sam napravio, generator izgenerise klase koji predstavljaju tabele.
Ne zelim da koristim Hibernate jer je po mom misljenju spor, ovaj moj mini db framework radi brze, ali bi bilo jos bolje kada bi se jos vise mogao optimizirati.

Svako put kada ucitavam neki objekat iz tabe ili snimam promjene moram inicilaizirati zasebnu konekciju i onda je diskonektovati na kraju.

Medjutim problem je ako prilikom izvrsavanja programa moram ucitatai vise razlicitih tabela odnosno klasa, tada on svaki put otvori konekciju ucita podatke i zatvori istu.

Ja sam bio kontao da na glavnom servletu inicijaliziram konekciju i da je stavim u session, onda da iz ovih db klasa pristupim njoj, da ne mi svaki put otvarao novu konekciju, i kada se sve iscita da onda zatvorim konekcioju na dnu servleta.


Primjer koda koji generise ovaj moj generator:


Code:

/*
user
UserID || Integer || INT || 0 ||  || Username || String || VARCHAR || 0 ||  || Password || String || VARCHAR || 0 ||  || Name || String || VARCHAR || 0 ||  || Address || String || VARCHAR || 0 ||  || ZipCode || String || VARCHAR || 0 ||  || CityID || Integer || INT || 0 ||  || Country || String || VARCHAR || 0 ||  || Telephone || String || VARCHAR || 0 ||  || MobileTelephone || String || VARCHAR || 0 ||  || Email || String || VARCHAR || 0 ||  || Active || Boolean || TINYINT || 0 ||  || trueCreatedAt || Timestamp || TIMESTAMP || 0 ||  || ActivationCode || String || VARCHAR || 0 ||  || Admin || Boolean || TINYINT || 0 ||  || 

*/

package hdbf;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.Serializable;
import data.*;


public class User implements Serializable
{
    private Integer userID = null;
    private String username = null;
    private String password = null;
    private String name = null;
    private String address = null;
    private String zipCode = null;
    private Integer cityID = null;
    private String country = null;
    private String telephone = null;
    private String mobileTelephone = null;
    private String email = null;
    private Boolean active = new Boolean("true");
    private Timestamp createdAt = null;
    private String activationCode = null;
    private Boolean admin = null;

        
    public User()
    {
        //TODO
    }

    public User(Integer userID, String username, String password, String name, String address, String zipCode, Integer cityID, String country, String telephone, String mobileTelephone, String email, Boolean active, Timestamp createdAt, String activationCode, Boolean admin)
    {
        this.userID = userID;
        this.username = username;
        this.password = password;
        this.name = name;
        this.address = address;
        this.zipCode = zipCode;
        this.cityID = cityID;
        this.country = country;
        this.telephone = telephone;
        this.mobileTelephone = mobileTelephone;
        this.email = email;
        this.active = active;
        this.createdAt = createdAt;
        this.activationCode = activationCode;
        this.admin = admin;
    }


    public Integer getID()
    {
        return userID;
    }

    public void setID(Integer id)
    {
        this.userID=id;
    }


    public Integer getUserID()
    {
        return this.userID;
    }

    public void setUserID(Integer userID)
    {
        this.userID = userID;
    }

    public String getUsername()
    {
        return this.username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getPassword()
    {
        return this.password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getName()
    {
        return this.name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getAddress()
    {
        return this.address;
    }

    public void setAddress(String address)
    {
        this.address = address;
    }

    public String getZipCode()
    {
        return this.zipCode;
    }

    public void setZipCode(String zipCode)
    {
        this.zipCode = zipCode;
    }

    public Integer getCityID()
    {
        return this.cityID;
    }

    public void setCityID(Integer cityID)
    {
        this.cityID = cityID;
    }

    public String getCountry()
    {
        return this.country;
    }

    public void setCountry(String country)
    {
        this.country = country;
    }

    public String getTelephone()
    {
        return this.telephone;
    }

    public void setTelephone(String telephone)
    {
        this.telephone = telephone;
    }

    public String getMobileTelephone()
    {
        return this.mobileTelephone;
    }

    public void setMobileTelephone(String mobileTelephone)
    {
        this.mobileTelephone = mobileTelephone;
    }

    public String getEmail()
    {
        return this.email;
    }

    public void setEmail(String email)
    {
        this.email = email;
    }

    public Boolean getActive()
    {
        return this.active;
    }

    public void setActive(Boolean active)
    {
        this.active = active;
    }

    public Timestamp getCreatedAt()
    {
        return this.createdAt;
    }

    public void setCreatedAt(Timestamp createdAt)
    {
        this.createdAt = createdAt;
    }

    public String getActivationCode()
    {
        return this.activationCode;
    }

    public void setActivationCode(String activationCode)
    {
        this.activationCode = activationCode;
    }

    public Boolean getAdmin()
    {
        return this.admin;
    }

    public void setAdmin(Boolean admin)
    {
        this.admin = admin;
    }



    public boolean delete() throws DataException
    {
        Data data = new Data();
        boolean status = data.deleteData("DELETE FROM user WHERE UserID="+this.userID);
        data.disconnect();
        return status;
    }
    
    public static boolean delete(Integer id) throws DataException
    {
        Data data = new Data();
        boolean status = data.deleteData("DELETE FROM user WHERE UserID="+id);
        data.disconnect();
        return status;
    }

    
    
    public static boolean delete(Integer id, Data data) throws DataException
    {
        boolean status = data.deleteData("DELETE FROM user WHERE UserID="+id);
        data.disconnect();
        return status;
    }

    private static User getUserFromResultSet(ResultSet rs) throws DataException
    {
        User user = null;
        try 
        {
            while (rs.next())
            {
                user = new User(Data.getInteger(rs,"UserID"), Data.getString(rs,"Username"), Data.getString(rs,"Password"), Data.getString(rs,"Name"), Data.getString(rs,"Address"), Data.getString(rs,"ZipCode"), Data.getInteger(rs,"CityID"), Data.getString(rs,"Country"), Data.getString(rs,"Telephone"), Data.getString(rs,"MobileTelephone"), Data.getString(rs,"Email"), Data.getBoolean(rs,"Active"), Data.getTimestamp(rs,"CreatedAt"), Data.getString(rs,"ActivationCode"), Data.getBoolean(rs,"Admin"));
            }
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
        return user;
    }

    private static List<User> getUsersFromResultSet(ResultSet rs) throws DataException
    {
        List<User> userList = new ArrayList<User>();
        try 
        {
            while (rs.next())
            {
                userList.add(new User(Data.getInteger(rs,"UserID"), Data.getString(rs,"Username"), Data.getString(rs,"Password"), Data.getString(rs,"Name"), Data.getString(rs,"Address"), Data.getString(rs,"ZipCode"), Data.getInteger(rs,"CityID"), Data.getString(rs,"Country"), Data.getString(rs,"Telephone"), Data.getString(rs,"MobileTelephone"), Data.getString(rs,"Email"), Data.getBoolean(rs,"Active"), Data.getTimestamp(rs,"CreatedAt"), Data.getString(rs,"ActivationCode"), Data.getBoolean(rs,"Admin")));
            }
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
        return userList;
    }

    public static User get(Integer id) throws DataException
    {
        try
        {
            Data data = new Data();
            ResultSet rs = data.getData("SELECT * FROM user WHERE UserID="+id+" LIMIT 1");
            User user = getUserFromResultSet(rs);
            rs.close();
            data.disconnect();
            return user;
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }

    public static List<User> getAll() throws DataException
    {
        try
        {
            Data data = new Data();
            ResultSet rs = data.getData("SELECT * FROM user");
            List<User> userList = getUsersFromResultSet(rs);
            rs.close();
            data.disconnect();
            return userList;
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }

    public static List<User> getBySQL(String sql) throws DataException
    {
        try
        {
            Data data = new Data();
            ResultSet rs = data.getData(sql);
            List<User> userList = getUsersFromResultSet(rs);
            rs.close();
            data.disconnect();
            return userList;
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }

    public static List<User> getByColumns(String[] columns, String[] values) throws DataException
    {
        try
        {
            Data data = new Data();
            String sqlColumns="";
            for(int i=0; i<columns.length; i++)
            {
                sqlColumns+=columns[i]+"=?";
                if(i+1<columns.length)
                {
                    sqlColumns+=", ";
                }
            }
            PreparedStatement ps = data.createPreparedStatement("SELECT * FROM user WHERE "+sqlColumns );
            for(int i=0; i<columns.length; i++)
            {
                ps.setString(i+1,values[i]);
            }
            ResultSet rs = ps.executeQuery();
            List<User> userList = getUsersFromResultSet(rs);
            rs.close();
            ps.close();
            data.disconnect();
            return userList;
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }


    

    public boolean save() throws DataException
    {
        try
        {
            int statusTemp1 = 0;
            Data data = new Data();
            PreparedStatement ps = null;
            if(this.userID==null)
            {
                ps = data.createPreparedStatement("INSERT INTO user (`UserID`, `Username`, `Password`, `Name`, `Address`, `ZipCode`, `CityID`, `Country`, `Telephone`, `MobileTelephone`, `Email`, `Active`, `CreatedAt`, `ActivationCode`, `Admin`) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                Data.setInteger(ps, 1, this.userID);
                Data.setString(ps, 2, this.username);
                Data.setString(ps, 3, this.password);
                Data.setString(ps, 4, this.name);
                Data.setString(ps, 5, this.address);
                Data.setString(ps, 6, this.zipCode);
                Data.setInteger(ps, 7, this.cityID);
                Data.setString(ps, 8, this.country);
                Data.setString(ps, 9, this.telephone);
                Data.setString(ps, 10, this.mobileTelephone);
                Data.setString(ps, 11, this.email);
                Data.setBoolean(ps, 12, this.active);
                Data.setTimestamp(ps, 13, this.createdAt);
                Data.setString(ps, 14, this.activationCode);
                Data.setBoolean(ps, 15, this.admin);

                statusTemp1 = ps.executeUpdate();

                ResultSet rs = ps.getGeneratedKeys();
                if (rs != null && rs.next())
                {
                    this.userID=rs.getInt(1);
                }
                rs.close();
            }
            else
            {
                ps = data.createPreparedStatement("UPDATE user SET `Username`=?, `Password`=?, `Name`=?, `Address`=?, `ZipCode`=?, `CityID`=?, `Country`=?, `Telephone`=?, `MobileTelephone`=?, `Email`=?, `Active`=?, `CreatedAt`=?, `ActivationCode`=?, `Admin`=? WHERE `UserID`=? ");
                Data.setString(ps, 1, this.username);
                Data.setString(ps, 2, this.password);
                Data.setString(ps, 3, this.name);
                Data.setString(ps, 4, this.address);
                Data.setString(ps, 5, this.zipCode);
                Data.setInteger(ps, 6, this.cityID);
                Data.setString(ps, 7, this.country);
                Data.setString(ps, 8, this.telephone);
                Data.setString(ps, 9, this.mobileTelephone);
                Data.setString(ps, 10, this.email);
                Data.setBoolean(ps, 11, this.active);
                Data.setTimestamp(ps, 12, this.createdAt);
                Data.setString(ps, 13, this.activationCode);
                Data.setBoolean(ps, 14, this.admin);
                Data.setInteger(ps, 15, this.userID);
                statusTemp1 = ps.executeUpdate();
            }

            ps.close();
            data.disconnect();

            if(statusTemp1>0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }

    /*CUSTOMCODE START*/
    public static User getUserByUsernameAndPassword(String username, String password) throws DataException
    {
        try
        {
            Data data = new Data();
            PreparedStatement ps = data.createPreparedStatement("SELECT * FROM user WHERE username= ? and password = ?");
            ps.setString(1, username);
            ps.setString(2, common.Util.encodeToSHA1(password));
            ResultSet rs = ps.executeQuery();
            User user = User.getUserFromResultSet(rs);
            rs.close();
            ps.close();
            data.disconnect();
            return user;

        } catch (Exception e)
        {
            throw new DataException(e.getLocalizedMessage());
        }
    }

    public static User getUserByEmail(String email) throws DataException
    {
        try
        {
            Data data = new Data();
            PreparedStatement ps = data.createPreparedStatement("SELECT * FROM user WHERE email= ? ");
            ps.setString(1, email);
            ResultSet rs = ps.executeQuery();
            return getUserFromResultSet(rs);
        }
        catch (Exception e)
        {
            throw new DataException(e.getLocalizedMessage());
        }
    }

    public static int setUserPassword(User user, String newPassword) throws DataException
    {
        try
        {
            Data data = new Data();
            PreparedStatement ps = data.createPreparedStatement("UPDATE user SET password= ? WHERE UserID=? ");
            ps.setString(1, newPassword);
            Data.setInteger(ps, 2, user.getUserID());
            return ps.executeUpdate();
        }
        catch (Exception e)
        {
            throw new DataException(e.getLocalizedMessage());
        }
    }

    public static User getUserFromSession(javax.servlet.http.HttpServletRequest request)
    {
        if (request.getSession(true).getAttribute("user1") != null)
        {
            return (User)request.getSession(true).getAttribute("user1");
        }
        else
        {
            return null;
        }
    }

    public static User getByColumn(String columnName, String columnValue) throws DataException
    {
        try
        {
            Data data = new Data();
            PreparedStatement ps = data.createPreparedStatement("SELECT * FROM user WHERE "+columnName+" = ? ");
            ps.setString(1,columnValue);
            ResultSet rs = ps.executeQuery();
            List<User> userList = getUsersFromResultSet(rs);
            rs.close();
            ps.close();
            data.disconnect();

            if(userList.isEmpty())
            {
                return null;
            }
            else
            {
                return userList.get(0);
            }
        }
        catch (SQLException ex)
        {
            throw new DataException(ex.getLocalizedMessage());
        }
    }
    /*CUSTOMCODE END*/
    
}











 
Odgovor na temu

antix

Član broj: 8388
Poruke: 265
*.adsl.verat.net.

Jabber: antix@elitesecurity.org


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 13:28 - pre 145 meseci


jos jedan koji misli da ima nesto bolje od Hibernate-a

Stavljanje bilo cega u HttpSession treba da bude pazljivo odradjeno. Stavljanje java.sql.Connection objekta u HttpSession ne da nije dobar pristup vec je uzasan! I drzaces konekciju otvorenu sve dok ne istekne HttpSession? Sta ako imas 1000 korisnika -> imaces 1000 konekcija na bazu istovremeno otvorenih!!! Mozes i HttpServletRequest da koristis za ovo tvoje, zar ne, mada i tada ces imati probleme sa skalabilnoscu jer sta ako ti dodje 1000 requesta u istom momentu, a obrada svakog requesta traje neko vrijeme?

Postoji nesto sto se zove ThreadLocal i mozda to moze da ti koristi... a to sto imas mnogo static promjenljivih moze da bude dobar znak da nisi dobro dizajnirao svoj framework.

Prijateljski savjet: razmisli da koristis Hibernate, TopLink ili plain JDBC.
 
Odgovor na temu

semsudin
BIH

Član broj: 13751
Poruke: 58
92.36.196.*

Sajt: www.hostbih.com


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 14:00 - pre 145 meseci
Citat:

jos jedan koji misli da ima nesto bolje od Hibernate-a

Stavljanje bilo cega u HttpSession treba da bude pazljivo odradjeno. Stavljanje java.sql.Connection objekta u HttpSession ne da nije dobar pristup vec je uzasan! I drzaces konekciju otvorenu sve dok ne istekne HttpSession? Sta ako imas 1000 korisnika -> imaces 1000 konekcija na bazu istovremeno otvorenih!!! Mozes i HttpServletRequest da koristis za ovo tvoje, zar ne, mada i tada ces imati probleme sa skalabilnoscu jer sta ako ti dodje 1000 requesta u istom momentu, a obrada svakog requesta traje neko vrijeme?

Postoji nesto sto se zove ThreadLocal i mozda to moze da ti koristi... a to sto imas mnogo static promjenljivih moze da bude dobar znak da nisi dobro dizajnirao svoj framework.

Prijateljski savjet: razmisli da koristis Hibernate, TopLink ili plain JDBC.


Eh jarane i ti ga pretjera, molim te pogledaj ovaj kod pa ces vidjeti za sta ja koristim static metode, koristim npr kada zelim da ucitam rekord iz baze u obekat npr: User.get(1); get(int id) je static metod
Ako pregledas oavaj kod sto sam ja zalijepio to je cisti JDBC, samo sto je izgenerisan da ne bi za svaki upit pisao SQL.

Ja bih u Session stavio drugi objekat koji unutar sebe sadrzi connection, i ne bih ga trajno cuvao u sesiji, nego bih ga cuvao samo doke se servlet ne izvrsi

Code:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
{
//pocetak servleta
postavi konekciju u session

User.getAll();
City.getAll();
Article.get(12);
.....
diskonektuj konekciju i ukloni iz session-a
//kraj servleta
}



Vidisa ja bih htio samo da imam konekciju otvorenu ali da je ne moram proslijedjivati i kada ucitam sve potrebne podatke onda bi zatvorio konekciju.
U uvom slucaju za ovaj primjer bih imao 1 otvaranje i zatvaranje konekcije umjesto 3 puta

Ja sam Hibernate testirao i dosta mi sporije ucitava poodatke od ovoga sto sam ja pisao.


 
Odgovor na temu

semsudin
BIH

Član broj: 13751
Poruke: 58
92.36.196.*

Sajt: www.hostbih.com


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 14:03 - pre 145 meseci
Eh ThreadLocal bi mogao posluziti, mogao bih u njega privremeno sacuvati konekciju.
 
Odgovor na temu

dejankr
Dejan Krsmanovic
JavaEE programer
Beograd

Član broj: 7842
Poruke: 384
*.dynamic.sbb.rs.



+1 Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 15:07 - pre 145 meseci
Generalno, nije dobar dizajn ako želiš iz data access layera da koristiš HttpSession objekat jer tako stvaraš neprirodnu zavisnost Data layera od strane Web layera. Pogledaj bolje klasu ThreadLocal, gde možeš stavljati objekte i pristupati im kao statickim promenljivima, s tim što su one "staticke" na nivou jednog Thread-a. Znaci u servletu nešto možeš iz sesije da staviš u ThreadLocal i da dalje pristupaš tom ThreadLocalu iz ostalih klasa.

Medutim, iz opisa ovog tvog mini db frameworka, ja ne vidim kako bi on mogao biti brži od Hibernate. Connection objekat je nešto što se ne otvara/zatvara svaki čas jer je vremenski veoma skupa operacija. Konekciju bi trebalo otvoriti jednom, prilikom starta aplikacije i zatvoriti je kada se aplikacija spušta. Dakle, nema razloga da više usera ne koristi istu konekciju kada se radi o web aplikaciji. Takođe, ne znam da li koristiš Connection
Pool, pošto se takođe nikada ne otvara samo jedna konekcija, već na početku rada otvoriš više konekcija i koristiš ih paralelno. Ovu funkcionalnost ti obezbeđuje Conection Pool (pogledaj Apache DBCP, Proxool ili C3po).

Ako je jedini razlog korišćenja http sessije u Data access layeru pristup konekciji, onda ti je pristup pogrešan pošto bi u tom slučaju trebalo da koristiš connection pool.
 
Odgovor na temu

antix

Član broj: 8388
Poruke: 265
*.adsl.verat.net.

Jabber: antix@elitesecurity.org


Profil

icon Re: Pristup Session Objektu iz klase koja ne extends HttpServlet28.02.2010. u 15:45 - pre 145 meseci
Kao sto Dejan rece, nema smisla da tvoj DAO sloj zna bilo sta o presentation sloju (HttpSession). DAO sloj bi trebalo da dobije input parametre, nadje Connection instancu (opet kao sto ti je Dejan rekao, najbolje u connection poolu), izvrsi upite i vrati neke rezultate. Ne treba da zna bilo sta o HTTP protokolu itd. Ne moras da koristis Hibernate za ovo, mozes i JDBC i da optimizujes kako zelis. Medjutim pazi da konekcija ne bude otvorena previse dugo, i konekcije ka bazi se sporo otvaraju tako da se trudi da izbjegnes otvaranje/zatvaranje za svaki request.

Mozda Hibernate ne odgovara tvojim zahtjevima u ovom trenutku, ali svakako razmisli za ubuduce da ga koristis. Ja imam prilicno pozitivna iskustva sa njim.

Pozdrav
 
Odgovor na temu

[es] :: Java :: Pristup Session Objektu iz klase koja ne extends HttpServlet

[ Pregleda: 2306 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.