Java EE, tworzenie projektu w Eclipsie i pisanie aplikacji.

0

Pytanie 1:

Witam. Dotąd pisałem w Netbeansie, ale postanowiłem się przesiąść na Eclipse. W Netbeansie żeby napisać aplikację w Javie EE tworzyłem po prostu projekt EAR i tworzył mi się projekt z podziałem na podprojekt EJB i WAR. Nie wiem jak to prawidłowo stworzyć w Eclipsie, ale chyba wg. tego tutorialu będzie ok? http://mkorwel.blogspot.com/2010/05/ejb-servlet-prosta-aplikacja-enterprise.html
Mam też pytanie do osób, które znają się bardziej na pisaniu tego typu apliakcaji. Z ilu modułów powinna się taka aplikacja składać? Z EJB i WAR tylko? Jeśli będę korzystał z Hibernate to gdzie umieścić jego pliki? Raczej w EJB?

Pytanie 2:

To już pytanie bardziej konkretne bo dotyczące realizacji projektu. Mianowicie mam system przychodni i planuję go trochę udoskonalić.
Przykładowo mam JSFowego ManagedBeana LoginMB, w którym jest metoda do logowania do systemu. Jeśli logowanie się powiedzie to zapisuję do sesji id tego użytkownika:

session.setAttribute("myId", user.getId());

Potem z tego ID korzystam w różnych sytuacjach np. podczas edycji swoich danych, jeśli lekarze jest zalogowany to podczas dodawania swoich wizyt, jeśli pacjent to do zapisu na wizytę itp. Czy jest to dobre rozwiązanie? Tak pomyślałem, że skoro bean jest i tak sesyjny więc żyje cały czas to po prostu mógłbym np. go wstrzyknąć do JSFowego beana z wizytami, w którym mi to ID jest potrzebne za pomocą

java napisał(a)

@Inject
zamiast pobierać go z sesji:

myId = (Integer) session.getAttribute("myId");

Która z opcji wydaje się być lepsza? Może są jeszcze jakieś inne?

Druga sprawa, dość podobna do powyższej. Przykładowo lekarz ma możliwość przejrzenia historii choroby pacjenta. Więc klikam wyświetl listę pacjentów i po najechaniu na któregoś z nich wywoływana jest metoda getUser z JSFowego ManagedBeana UserMB

    public User getUser() {
        if (user == null) {
            user = new User();
        }
        session.setAttribute("userId", user.getId());
        return user;
    }

Zapisuję wtedy do sesji id tego użytkownika

session.setAttribute("userId", user.getId());

ponieważ UserMB ma zasięg request więc przy przejściu na dalszą stronę gdzie również jest mi potrzebna informacja o userze straciłbym ją. Czy to rozwiązanie również jest dobre?

I trzecia sprawa, również podobna do poprzednich. Mam sekretarkę, która może zapisać pacjenta na wizytę do wybranego lekarza, zanim dokonam zapisu w bazie to te ID gdzieś muszę przechowywać więc robię podobnie jak poprzednio. Wyświetlam listę pacjentów wybieram pacjenta i zapisuję jego ID przed przejściem do listy lekarzy za pomocą metody:

    public String goDoctorVisitsList() {
        session.setAttribute("patientId", user.getId()); //ustawienie id aktualnie przeglądanego pacjenta
        return "visitList";
    }

potem przy wyborze lekarza korzystam z wcześniejszego rozwiązania:

<code class="java">    public User getUser() {
        if (user == null) {
            user = new User();
        }
        session.setAttribute("userId", user.getId());
        return user;
    }

I w taki sposób mam oba ID i mogę dokonać zapisu w bazie wizyty z wybranym lekarzem i pacjentem:

```java
        patientId = (Integer) session.getAttribute("patientId");
        doctorId = (Integer) session.getAttribute("userId");
        visit.setPatientId(userDao.find(patientId));
        visit.setDoctorId(userDao.find(doctorId));
        visitDao.update(visit);

Czy takie rozwiązania są dobre? Jak to inaczej zrealizować? Osobiście nic lepszego mi do głowy nie przychodzi.

Pytanie 3

Trzecie pytanie dotyczy zabezpieczenia strony. Dotąd realizowałem proces dostępu do poszczególnych paneli w taki sposób, że w sesyjnym LoginMB miałem metodę logującą, która przeszukiwała bazę w celu znalezienia użytkownika i zwracała jego rolę. Np. "admin". Co powodowało przejście na stronę AdminPanel, z której mogłem przechodzić na kolejne strony dostępne tylko dla admina. To zabezpieczenie jednak wydaję mi się niezbyt dobrym rozwiązaniem. Czytałem coś o JAAS. Czy jest to lepsza opcja? Czego powinno się używać do zabezpieczenia dostępu.

    public String validate() {
        user = userService.findUserAccount(login, password);
        if (user != null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(true);
            session.setAttribute("myId", user.getId());
            return user.getRole();
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Niepoprawny login lub hasło", "Sprawdź poprawność loginu oraz hasła"));
            return null;
        }
    }

Pytanie 4

Ostatnie pytanie dotyczy nawigacji na stronach. Zrealizowałem to raczej w dość głupi sposób ponieważ do każdego nawet najgłupszego przejścia na inną stronę pisałem metodę np przejście na głupią stronę z galerią:

    public String goGallery() {
        return "gallery";
    }

i na stronie kod:

<p:menuitem styleClass="navigation" value="#{msg.gallery}" action="#{userMB.goGallery()}" icon="ui-icon-star"/>  

Przez co faces-config rozrósł mi się do niebotycznych rozmiarów i ma ponad 5000 linijek.
Słyszałem o metodzie dzięki, której nie będą potrzebne wpisy w faces-config jeśli w action wpiszę nazwę strony to wtedy nastąpi przekierowanie na nią np:

<p:menuitem styleClass="navigation" value="#{msg.gallery}" action="gallery" icon="ui-icon-star"/>  

Czy to jest lepsze rozwiązanie aby zmniejszyć wielkość faces-config, w którym można się potem naprawdę pogubić.

1
  1. Aplikacja powinna składać się z tylu cześci ile ci potrzebne. Możesz mieć tam kilka osobnych projektów z EJB na przykład jeśli ma to sens. Możesz też osobno mieć na przykład całą warstwę persystencji jeśli uznasz że ma to sens. Jak jakaś warstwa robi się za duża to dzielisz.
  2. Faktycznie nie ma specjalnie sensu pchać id do sesji skoro masz sesyjnego managed beana.
    Jeśli nie widzisz innego sposobu niż pchanie tego do sesji to miałbyś ciężkie życie pisząc w jakimś SpringMVC ;) Przecież to nie problem przesyłać przez formularz argumenty (i nie zapychać sesji :P), szczególnie jeśli scope to request.
0

Dzięki za odpowiedzi. Jeśli ktoś jeszcze jest w stanie mi pomóc to prosiłbym o odpowiedzi na pytani 3 i 4.

Poza tym chciałem jeszcze spytać. Bo załóżmy w projekcie mam opcję usuwania administratora, pacjenta, lekarza, wizyty itp. Jednak usłyszałem, że nie jest dobrą praktyką usuwanie danych z bazy. Tylko odznaczać je np. jako nieaktywne. Czyli np. zamiast faktycznie usuwać wpis z bazy, dodać do niego pole np. active i ustawiać je na false. Czy faktycznie taką praktykę się stosuje?

1

Niestety z 3 nie mogę ci pomóc, z tego zakresu mam doświadczenia tylko ze Spring Security.
Jeśli chodzi o 4 to to jest odwieczny problem z serii czy pchać konfiguracje do XMLa czy zaszyć w kodzie. Ostatnio moda jest taka żeby jednak nie robić tego w xmlu.

Co do usuwania danych to zależy głównie od tego co za dane przechowujesz.
Wyobraźmy sobie że przechowujesz historię wizyt pacjentów u lekarzy. Masz wpisy w bazie które mówią że Pacjent X był u Doktora Y tego i tego dnia, dostał taką diagnozę i takie leki etc. I teraz wyobraźmy sobie że lekarz zostaje zwolniony i co? Chcesz go usunąć z bazy? To zostaną ci wizyty bez "lekarza". A jak pacjent przyjdzie się procesować że go źle zdiagnozowaliście to co? :P To nie wiesz kto diagnozował.
Analogicznie, jak chcesz usunąć pacjenta to zostaną ci wizyty bez pacjenta. A jak będziesz jednak chciał się skontaktować z danym pacjentem, nawet jeśli już nim nie jest to co?

Zasadniczo nie możesz usuwac żadnych danych które jakoś wiążą się z danymi historycznymi które trzymasz. Nie ma za to problemu z wywaleniem użytkownika z systemu, o ile nigdzie nie logujesz informacji o tym który uzytkownik kiedy i co robił.

0

Ok dzięki za odpowiedź. Taka jeszcze jedna rzecz mnie męczy. Mianowicie Eclipse stworzył mi EJB i EJB Client. Po co właściwie jest ten EJB Client? Do czego go się wykorzystuje. Dotąd miałem tylko jeden projekt EJB i w nim interfejsy oraz jego implementacje. Więc do czego mi jest potrzebny ten EJB Client co tam umieszczać? Znalazłem coś takiego: http://javahowto.blogspot.com/2007/11/simple-ejb-3-on-jboss-application.html

Ale wiele mi to nie wyjaśniło po co to jest.

1

Do niczego specjalnego. Ot masz tam pokazane jak można z aplikacji standalone się do tego EJB odwoływać. Widocznie tak sobie kliknąłeś żeby wygenerował ci oba. Jeśli korzystasz z webowego interfejsu i z CDI to w ogóle możesz tego klienta wyrzucić ;)

1

Ja w JSF nie uzywalem w ogole nawigacji w pliku XML, bo uznalem ja za niewygodna i trudna w utrzymaniu. Da sie wygodnie programowac requestami.

Aplikacje mam tak zaprojektowana, ze robie redirect korzystajac z FacesContext, a potem ExternalContext. Troche nie w duchu JSF, ale dziala naprawde dobrze pod warunkiem, ze opakuje sobie to w metody (kto mi zabroni?). Ogolnie np. po akcji w formularzu mozna robic redirect i tez dziala. Gdy akcja jest np. edycja to po prostu podaje w URL id i na jego podstawie rekonstruuje sobie obiekt (troche jak we frameworkach jak Spring MVC). Oczywiscie moglbym dorobic navigation-rules, ale ja tego nie kupuje. Szczerze nienawidze tej opcji JSF to jej nie uzywam jesli nie musze. Poza tym bardzo fajny i przyjemny framework: duzo fajnych komponentow, prosty podzial na layout przez facelety.

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