Przesyłanie obiektów w RMI

0

Witam! Mam aplikację, która łączy się z bazą i pobiera z bazy danych tabele i wypełnia tymi danymi tabelę JTable w moim oknie (JFrame)...Oto kod:

public class Pobranie_tabel
{
private JComboBox combo_sortowanie;
private String selectedItem;

public Pobranie_tabel(JComboBox combo)
{
    combo_sortowanie=combo;
    //System.out.println("ddddd "+combo_sortowanie.getName().toString());
    combo_sortowanie.removeAllItems();
}



static String relacja;

public DefaultTableModel Pobierz_model(String zapytanie, String tableName) throws SQLException
{
    String query=zapytanie;
    relacja=new String(tableName);
    CachedRowSetImpl crs=new CachedRowSetImpl();
    DefaultTableModel tModel=null;
          

    try
    {
        rs = Polaczenie.conn.createStatement().executeQuery(query);
        ResultSetMetaData rsmd = rs.getMetaData();
        int colCount = rsmd.getColumnCount();

        String[] colHeaders = new String[colCount];
        tModel = new DefaultTableModel()
        {   
            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex)
            {
                if(relacja.equals("Stanowisko"))
                {
                    if(columnIndex==0) return false;
                }
                else if(relacja.equals("Dzial"))
                {
                    if(columnIndex==0) return false;
                }
                else if(relacja.equals("Pracownik"))
                {
                    if(columnIndex==0) return false;
                	if(columnIndex==1) return false;
                	if(columnIndex==2) return false;
                	if(columnIndex==3) return false;
                	if(columnIndex==4) return false;
                	if(columnIndex==5) return false;
                	if(columnIndex==6) return false;
                	if(columnIndex==7) return false;
                	if(columnIndex==8) return false;
                	if(columnIndex==9) return false;

                }
                else if(relacja.equals("L_godzin"))
                {
                    if(columnIndex==0) return false;
                    if(columnIndex==1) return false;
                }
                return true;
            }
        };
        
        for(int i=0;i<colCount;i++)
        {
            colHeaders[i] = rsmd.getColumnName(i+1);
            combo_sortowanie.addItem(colHeaders[i]);
        }

        tModel.setColumnIdentifiers(colHeaders);

        while(rs.next())
        {
            Object[] obj = new Object[colCount];
            for(int i=0;i<colCount;i++)
            {
                obj[i] = rs.getObject(i+1);
            }

            tModel.addRow(obj);

        } 
        
        
    }
    catch(Exception ex)
    {
        JOptionPane.showMessageDialog(null,"Nie mozna pobrac danych z bazy: "+ex.getMessage(),"ERROR", JOptionPane.ERROR_MESSAGE);
    }
    return tModel;
}

}

Problem jest taki, że teraz ten mój cały program muszę przerobić na RMI (Remote Method Invocation), czyli muszę ResultSet zamienić na CachedRowSetImpl...Pytanie jak to tutaj zastosować, np do resultSetMetaData...Ktoś zna się na tym? Szukam eksperta w tej dziedzinie...

0

Witam

Według mnie daj sobie spokój z tym CachedRowSet. Jakiego rodzaju są dane które chcesz przesłać?
To dane osobowe czy co?, czemu nie zawrzesz tego w jakies klasie typu Person + Serializable czy cos takiego, po tym przerzuczasz wyniki z RS(obiekty klasy Person) do arraylisty, a pozniej wysylasz ja do klienta, a dokladnie do jakies implementacji AbstractTableModel, podpinasz to do JTable i wsio.
Chociaż z tego co pisze w dokumentacji CachedRowSet. mógłbyś tego użyć i w kliencie stworzyć odpowiednią kolekcję obiektów powiedzmy klasy Person czy coś takiego, ze względów wydajnościowych ale po co się w to bawić, jeśli Ci chodzi tylko o jakiś przykładowy program RMI to takie coś wystarczy i będzie łatwiejsze do zrobienia.

0

A można jaśniej? Wiem, że można to zrobić za pomocą CachedRowSetImpl, tylko nie wiem do końca JAK...Może ianczej...CO PROPONUJECIE ODNOŚNIE KOMUNIKACJI MIĘDZY SERWEREM RMI A BAZĄ DANYCH?

0

Zwykłe JDBC będzie chyba najlepsze w Twoim wypadku, a kodzisz to w taki sam sposób jak zwykłą "jednorodną" aplikację bazodanową, program działający na serwerze to osobny proces, z tym że
warstwa prezentacji tego wszystkiego posiada klient, serwer wysyla mu potrzebne dane.
Już masz chyba wszystko napisane co do teorii w tym temacie a i przykładowych kodów znajdziesz mnóstwo...

0
GhostDog napisał(a)

Zwykłe JDBC będzie chyba najlepsze w Twoim wypadku, a kodzisz to w taki sam sposób jak zwykłą "jednorodną" aplikację bazodanową, program działający na serwerze to osobny proces, z tym że
warstwa prezentacji tego wszystkiego posiada klient, serwer wysyla mu potrzebne dane.
Już masz chyba wszystko napisane co do teorii w tym temacie a i przykładowych kodów znajdziesz mnóstwo...

Na pewno tak jak "jednolita aplikacja"? Tak chyba nie pójdzie...A co z serializacją?

0

Chodziło mi o program działający na serwerze. Wiadomo, że dane które pobiera z bazy muszą zostać z serializowane przed wysłaniem ich do klienta.

Dopóki operujesz na ogólnie "typach prostych" (text, liczby), to się nią nie przejmujesz, ewentualnie do swoich klas dodajesz Serializable i gra gitara, w RMI wszystko się samo dzieje, łatwiej się to robi niż zwykłą aplikacją klient-serwer, bo nie przejmujesz się niższym poziomami programu. Schody zaczynają się gdy chciałbyś przesłać jakiś np jpeg przez RMI wtedy trochę zabawy jest z z serializowaniem jego.

0
GhostDog napisał(a)

Chodziło mi o program działający na serwerze. Wiadomo, że dane które pobiera z bazy muszą zostać z serializowane przed wysłaniem ich do klienta.

Dopóki operujesz na ogólnie "typach prostych" (text, liczby), to się nią nie przejmujesz, ewentualnie do swoich klas dodajesz Serializable i gra gitara, w RMI wszystko się samo dzieje, łatwiej się to robi niż zwykłą aplikacją klient-serwer, bo nie przejmujesz się niższym poziomami programu. Schody zaczynają się gdy chciałbyś przesłać jakiś np jpeg przez RMI wtedy trochę zabawy jest z z serializowaniem jego.

Czyli zaraz, bo sie zamotam: mam sobie program z metodą, która ma odczytać np jakis rekord z bazy danych...Dobrze zrozumiałem, że ResultSet mogę zostawić i tylko do klasy dopisać implements Serializable? Mógłbyś tak bardziej szczegółowo to opisać?

0

Implementowac Serializable musisz wtedy gdy chcesz przeslac przez siec obiekty swoich klasy, typu Person czy coś tam, w JDBC bez ResultSet danych z bazy nie wyciągniesz, a zeby przeslac jakies obiekty przez siec musza zostac zapakowane do ramek i dzieki z serializowaniu takich obiektow jest to mozliwe.
Jesli operujesz na suchych Stringach itp, to sie tym nie musisz "przejmowac".

0

Widać, że jestes obyty w tym temacie...Tzn ja nie mam zamiaru przesylac zadnych Jpeg, ani txt, tylko np. wyniki zapytania do bazy danych (czym zreszta zajmuje się serwer)...te wyniki chcę przesłać z serwera np. do JTable w aplikacji klienta...Czyli co: nie muszę uzywac zadnego cachedRowSet ani dopisywać imlementsSerializable? Dobrze rozumiem?

0

Obyty? ;-)
W przypadku string itd nie musisz sie przejmowac serializacją, klasy te implementują serializable, a serializacją zajmuje się sama JVM:

Zobacz: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

Musisz miec jakieś teoretyczne podstawy, poczytaj:

http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
http://java.sun.com/docs/books/tutorial/rmi/index.html

A co do samego stylu kodowania to w google:

Single Responsibility Principle
DRY

Pozdrawiam

0

A więc jednak będę przesyłał obiekt mojej klasy - obiekt reprezentujący model tabeli...Pytanie zatem jak zrobić w takim przypadku serializację? Mam klasę Pobranie_tabel - czy wystarczy do niej dopisać class Pobranie_tabel implements Serializable? Czy to jest bardziej skomplikowane...Nie wiem do jakiego stopnia serializacja bardziej złożonych obiektów przeprowadzana jest automatycznie (bez wiedzy programisty)...Wszystkie uwagi i pomysły są dla mnie bardzo cenne...I proszę o wyrozumiałość - po raz pierwszy tworzę aplikację rozproszoną w oparciu o RMI...Pozdrawiam

0

Co muszę zrobić by przesłać z serwera obiekt mojej klasy? Proszę o pomoc

0

Może bardziej sprecyzuję problem:

  1. Po stronie klienta jest okno, w którym jest tabela JTable...
  2. Klient chce wywołać zdalną metodę (będącą oczywiście w interfejsie)...Metoda nazywa się Pobierz_model...Metoda ta zwraca obiekt typu DefaultTableModel potrzebny do wypełnienia danymi tabelę w oknie JFrame klienta
  3. Problem jest taki: powiedzcie czy moje myślenie idzie w dobrą drogę: w zdalnym interfejsie (interface Moj_interfejs extends Remote) mam metode Pobierz_model...

public DefaultTableModel Pobierz_model(String zapytanie, String tableName) throws RemoteException
{
try
{
return new Pobranie_tabel().Pobierz_model(zapytanie, tableName);
}
catch (SQLException ex)
{
Logger.getLogger(SerwerImpl.class.getName()).log(Level.SEVERE, null, ex);
return null;
}

Metoda ta odwołuje się do zwykłej klasy będącej na serwerze (class Pobranie_tabel) ale w ogóle niezwiązanej z RMI....Czyli chcę, żeby Pobierz_model zwracała z klasy Pobranie_tabel (dokładniej poprzez metodę Pobierz_model) obiekt typu DefaultTableModel

public class Pobranie_tabel implements Serializable
{
private JComboBox combo_sortowanie;
private String selectedItem;

public Pobranie_tabel(JComboBox combo) throws RemoteException
{
    combo_sortowanie=combo;
    //System.out.println("ddddd "+combo_sortowanie.getName().toString());
    combo_sortowanie.removeAllItems();
    System.out.println("Wychodze z konstruktora Pobranie_tabel");
}

public Pobranie_tabel() throws RemoteException
{

}


static String relacja;

public DefaultTableModel Pobierz_model(String zapytanie, String tableName) throws SQLException
{

     String query=zapytanie;
    relacja=new String(tableName);
    ResultSet rs = null;
    DefaultTableModel tModel=null;


    try
    {
        Class.forName("org.firebirdsql.jdbc.FBDriver");
        Polaczenie.ConnectionOpen("Kartoteka", "SYSDBA", "masterkey", "org.firebirdsql.jdbc.FBDriver", "jdbc:firebirdsql://localhost:3050/");
        rs = Polaczenie.conn.createStatement().executeQuery(query);
        ResultSetMetaData rsmd = rs.getMetaData();
        int colCount = rsmd.getColumnCount();

        String[] colHeaders = new String[colCount];
        tModel = new DefaultTableModel()
        {
            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex)
            {
                if(relacja.equals("Stanowisko"))
                {
                    if(columnIndex==0) return false;
                }
                else if(relacja.equals("Dzial"))
                {
                    if(columnIndex==0) return false;
                }
                else if(relacja.equals("Pracownik"))
                {
                    if(columnIndex==0) return false;
                	if(columnIndex==1) return false;
                	if(columnIndex==2) return false;
                	if(columnIndex==3) return false;
                	if(columnIndex==4) return false;
                	if(columnIndex==5) return false;
                	if(columnIndex==6) return false;
                	if(columnIndex==7) return false;
                	if(columnIndex==8) return false;
                	if(columnIndex==9) return false;

                }
                else if(relacja.equals("L_godzin"))
                {
                    if(columnIndex==0) return false;
                    if(columnIndex==1) return false;
                }
                return true;
            }
        };

        for(int i=0;i<colCount;i++)
        {
            colHeaders[i] = rsmd.getColumnName(i+1);
            combo_sortowanie.addItem(colHeaders[i]);
        }

        tModel.setColumnIdentifiers(colHeaders);

        while(rs.next())
        {
            Object[] obj = new Object[colCount];
            for(int i=0;i<colCount;i++)
            {
                obj[i] = rs.getObject(i+1);
            }

            tModel.addRow(obj);

        }


    }
    catch(Exception ex)
    {
        JOptionPane.showMessageDialog(null,"Nie mozna pobrac danych z bazy: "+ex.getMessage(),"ERROR", JOptionPane.ERROR_MESSAGE);
    }
    return tModel;</i>

Pytanie czy tak można i jak przesłać obiekt typu defaultTableModel z serwera do klienta? Czy wystarczy tylko gdzies dopisać implements Serializable czy coś jeszcze?

0

No jak już się tak uparłeś to możesz przesłać TableModel, tylko że nie wysyłaj całego obiektu PobranieTableModel czy coś tam, sam obiekt klasy DefaultTableModel, jest on serializowany, popatrz czasem do dokumentacji to się nie będziesz pytał o takie pierdoły i weź ten kod popraw bo jest tragiczny delikatnie mówiąc, popatrz się na Twoje instr warunkowe, szału nie robią co nie? nie mówiąc o reszcie

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1