niedziela, 1 lutego 2009

Dramat w czterech aktach - WebService (na szczęście z happyendem)

Jako dopełnienie serii postów związanych z technologiami JEE zaprezentuje wam przykładowe użycie WebSerwisów, wszystko oczywiście przy wykorzystaniu JBoss'a 5.0. Zaczynamy

Akt I

W przykładzie zostanie użyta prosta, lekko okrojona encja z mojego projektu zaliczeniowego.

package org.gen2.biblioteka.encje;

@Entity
public class Autor implements Serializable {


private static final long serialVersionUID = 1L;

private int id;
private String imie;
private String nazwisko;

public Autor() {
super();
}

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getImie() {
return imie;
}

public void setImie(String imie) {
this.imie = imie;
}

public String getNazwisko() {
return nazwisko;
}

public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}

public String toString() {
return imie + " " + nazwisko;
}
}


Akt II

Definiujemy prosty interfejs (z jedna metoda) dla bean'a który będzie naszym WebSerwisem (tudzież Usługą Sieciową)


package org.gen2.biblioteka.beany;

@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface AutorWSInterface {
ArrayList pobierzAutora(int idAutora);
}


@WebService - oznacza, ze intefejs będzie służył do implementacji WebSerwisu
@SOAPBinding - definiuje sposób komunikacji pomiędzy 'klientem' a 'serwerem', nie zaleca sie mieszanie style = RPC z use = LITERAL (JBoss w wersji 5.0 nie obsługuje tego jeszcze poprawnie)

Akt III

A teraz sama implemetacja bean'a.

package org.gen2.biblioteka.beany;

@Stateless
@WebService(endpointInterface = "org.gen2.biblioteka.beany.AutorWSInterface")
@SOAPBinding(style = Style.DOCUMENT)
public class AutorWSBean {

private @PersistenceContext(unitName="BibliotekaEJB")
EntityManager em;

@WebMethod
public ArrayList pobierzAutora(int idAutora) {
Query query = em.createQuery("select a from Autor as a where a.id = " + idAutora);
ArrayList autor = new ArrayList();
Autor temp = (Autor) query.getSingleResult();

autor.add(temp.getImie());
autor.add(temp.getNazwisko());

return autor;
}
}


@WebService(endpointInterface = "org.gen2.biblioteka.beany.AutorWSInterface") - musi wskazywać na intefejs który klasa ma implementować.
@WebMethod - jest użyteczne gdy mamy wiecej metod w beanie i chcemy żeby tylko niektóre były "eksportowane" do WSDL'a.

Akt IV

A teraz jak tego użyc?
Najpierw musimy wrzucić nasz projekt na serwer, następnie tworzymy w eclipsie nowy projekt, naciskamy Ctrl + N, z menu wybieramy 'Web Services', 'Web Service Client', w 'Service Definition' wklejamy link do naszego WSDL (link możemy znalezć na stronie, nie musimy sie przekopywać przez tony logów tak jak np. w Geronimo), klikamy 'Finish' i mamy utworzony interfejs do połączenia z naszym WebSerwisem, teraz napiszemy klase w ktorej przetesujemy jego dzialanie.

public class Test {

public static void main(String[] args) {

AutorWSBeanService abs = new AutorWSBeanServiceLocator();

try {
AutorWSInterface asi = abs.getAutorWSBeanPort();
String[] autor = asi.pobierzAutora(1);
System.out.println(autor[0] + " " + autor[1]);
} catch (ServiceException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}

}


Happyend

Uruchamiamy powyższą aplikacje lokalnie. A poniżej mamy wynik działania programu.

Adam Mickiewicz



Tu byl wielki babol rzeczowy;)

piątek, 30 stycznia 2009

Encje, Managery i MBeany Część 3

Witam!
Pozostały nam już tylko:

Managed Beany

Są to beany warstwy webowej. Służą przede wszystkim do przechowywania danych, zarówno tych wprowadzonych przez użytkownika w formularzach, jak i innych potrzebnych przy wyświetlaniu naszych stron, pobranych na przykład z bazy danych.
Co wydaje mi się być warte podkreślenia, NIE MA TUTAJ ŻADNYCH BEZPOŚREDNICH ODNIESIEŃ DO BAZY DANYCH!
Nie definiujemy tutaj żadnych relacji, zapytań, entityManagere-ów, inicjalizacji "Lazy" pól.
Po prostu niczego co by w sposób bezpośredni sczytywało lub zapisywało dane do bazy.
Wszystkie te czynności powinny być wykonywane przez Session Beany lub encje, a MBeany tylko z nich korzystać.
Mamy trzy rodzaje MBeanów: session, request, application. Nazwy te oznaczają zasięg (scope) w jakim one istnieją.

Przykładowy MBean mógłby wyglądać tak:
public class OsobaBean {

  /* Definicje wymaganych przez nas Session Beanów z warstwy biznesowej
   * Adnotacja @EJB musi się znaleźc przy każdym z osobna!
   */
  @EJB
  protected OsobaManagerLocal om; /* Podajemy nazwe interfejsu nie implementacji! */

  /* Pola MBeana powinny byc prywatne */
  private String imie;
  private String login;

  /* Metody wykorzystujące metody biznesowe.
   * Ich implementacje znajdziecie w poprzedniej części cyklu.
   */
  public void zarejestruj(){
    Osoba o = new Osoba(); /* Powiedzmy, że Osoba jest prostą encją mającą tylko dwa pola */
    o.setImie(imie);
    o.setLogin(login);
    om.dodajUsera(o);
  }

  public void usun(){
    Osoba o = new Osoba();
    o.setImie(imie);
    o.setLogin(login);
    om.usunUsera(o);
  }

  public List<Osoba> szukaj(String login){
    return om.szukajUsera(login);
  }

  /* Skoro pola są prywatne to konieczne są settery gettery
   * (chyba, że nie chcemy by były dostępne na stronach)
   */
  public void setImie(String imie) {
    this.imie = imie;
  }

  public String getImie() {
    return imie;
  }

  public String getLogin() {
    return login;
  }

  public void setLogin(String login) {
    this.login = login;
  }

}
Więc idąc od góry mamy...
Adnotacja @EJB pozwala "wstrzykiwać" Managery do naszych MBeanów. Wystarczy podać Interfejs, a implementacja zostanie automatycznie znaleziona.
Pola mogą być zarówno typami prostymi jak i klasami czy encjami nie ma tutaj ograniczeń. Powinny być jednak prywatne. Settery i gettery i tak będą musiały być stworzone jeśli chcemy by strona mogła się z naszym MBeanem komunikować.
Metody, zależnie od tego do czego służą mogą zwracać dowolne typy. Jednak warto zauważyć, że można w faces-config.xml zdefiniować przekierowania (navigation-rule) do innych podstron, na podstawie zwracanego przez metodę String-a.

Aby móc korzystać z naszego MBean-a należy dodać jeszcze wpis do faces-config.xml:
<managed-bean>
  <managed-bean-name>osobaBean</managed-bean-name>
  <managed-bean-class>com.blogspot.javazpiwnicy.bean.OsobaBean</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
managed-bean-name jest to nazwa przez, którą będziemy mogli odwoływać się na stronach do naszego MBean-a.
managed-bean-class klasa naszego beana.
managed-bean-scope czyli wspomniany wcześniej zasięg istnienia naszego beana.

Teraz już na naszych stronach możemy odwoływać się do naszych pól i metod przez EL.
Naprzykład <h:outputText value="#{osobaBean.imie}" /> czy <h:inputText value="#{osobaBean.imie}" />.
Można też w pewien sposób oszukać MBean-a. Jeśli chcemy zwracać jakąś wartość bezpośrednio z bazy i nie przechowywać jej w MBean-ie wystarczy stworzyć metodę przedrostkiem get.
Przykładowo public String getAllImiona() i odwoływać się do niej przez #{osobaBean.allImiona}.

Zazwyczaj metody wykorzystujemy w formularzach jako akcje przycisków.
<h:commandButton value="Zarejestruj" action="#{osobaBean.zarejestruj}" />

To już koniec tej trylogii ;)
Miłego pisania i zapraszam do komentowania.

środa, 28 stycznia 2009

Dostęp do JBoss-a spoza komputera lokalnego

Dzisiaj postanowiłem pokazać wynik mojej pracy koledze. Niestety po wpisaniu przez niego adresu http://<moj_ip>:8080/itd pokazywała się informacja o niemożliwości połączenia. Po chwili poszukiwania okazało się, że problem można łatwo rozwiązać. Wystarczy dodać parametr "-b 0.0.0.0" do parametrów uruchamiania serwera. Jeśli mamy Eclipsa z wtyczka od Jbossa klikamy 2x na nasz serwer->Open launch configuration i wpisujemy powyższy parametr do arguments w miejsce "-b localhost". Czyniąc to powinniśmy pamiętać o bezpieczeństwie naszego serwera, w tym celu zachęcam do zapoznania się z tą stroną.

Dominik:
U mnie okazało się to być niewystarczające i w ustawieniach serwera (2x click na serwerze) musiałem zamienić Host name z localhost na 0.0.0.0 .
Pozdrawiam