Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

Archiwum: 'Java' Kategorie

SQLite i szyfrowanie kolumn, pomaga MyBatis i Jasypt

Autor: Krzysztof Nielepkowicz o 23. kwietnia 2012

    Niedawno, pisząc wieczorami dla siebie aplikacje w .NET natrafiłem na bardzo przyjemną i lekką bazę danych – SQLite. Tak mi się ta baza spodobała, że postanowiłem sprawdzić czy z poziomu Javy i JDBC uda się do niej dostać. SQLite ma jednak jedną wadę – brak szyfrowania i zabezpieczenia hasłem. Baza SQLite mieści się w jednym pliku, który nie jest w jakikolwiek sposób zabezpieczony. Jako że na codzień pracuję w firmie tworzącej oprogramowanie dla banków i policji brak szyfrowania jest dość poważną wadą nawet w bardzo prostych narzędziach jak program do fakturowania.
    Z jakiego powodu potrzebne jest szyfrowanie samych danych? Wiadomo że błędem w sztuce jest trzymanie haseł w bazie danych – co najwyżej można trzymać posolone hashe. Zaszyfrowanie całej bazy danych (pliku sqlite) również nie wydaje się być dobrym pomysłem z powodów wydajnościowych. Dlatego należy rozpatrzyć szyfrowanie poszczególnych kolumn z danymi wrażliwymi. Jako przykład podam program do faktur gdzie są dane naszych kontrahentów. Co jeśli konkurencja przekupi naszego pracownika by zgrał na dysk USB plik z bazą naszych klientów? Ten problem dotyczy wszelkich aplikacji typu standalone, gdzie przetwarzane są wrażliwe dane. Częściowo ten problem jest rozwiązany w aplikacjach typu klient-serwer lecz nie zawsze jest sens stawiania takiej infrastruktury.

Czytaj więcej »

Tags: , , , , , , , , , ,
Napisany w Bazy danych, Java, Języki programowania | Brak komentarzy »

O LambdaJ i Guavie i mojej prelekcji na JUG

Autor: Krzysztof Nielepkowicz o 13. kwietnia 2012

    Witam pod dłuższej przerwie. Dzisiejszy wpis będzie trochę inny niż pozostałe, dlatego iż nie będzie typowo technicznym wpisem. Przez ostatnie tygodnie, „po godzinach” przygotowywałem się do prelekcji którą wygłosiłem 03.04.2012. Dzięki mojemu osobistemu fotografowi, Annie Mazińskiej, mogę pokazać również parę zdjęć 🙂

 

Czytaj więcej »

Tags: , , , , , , , , ,
Napisany w Java | Brak komentarzy »

Dynamiczne tworzenie obiektów w GWT + MVP4G

Autor: Krzysztof Nielepkowicz o 22. lutego 2012

    GWT jest dość udanym produktem, jednak ma swoje ograniczenia – głównie w dziedzinie refleksji. Najbardziej przydatną cechą jest tworzenie nowych obiektów oraz wnioskowanie typów obiektów. O ile w stosunku do drugiego problemu sprawę, w większości przypadków, rozwiązuje java generics to rozwiązanie pierwszego problemu za pomocą GWT.create(<class literal>) jest mocno ogranczone. Szczególnie bolesny staje się ten problem w aplikacjach gdzie część obiektów jest tworzonych z łańcuchów znaków – np pochodzących z formularzy które są generowane na podstawie klasy obiektów. Prosty scenariusz przewiduje iż chcemy wyświetlić w tabeli obiekty z bazy danych – tu z pomocą przychodzi MyBatis umożliwiający  mapowanie rekordów na obiekty, ale pojawia się wymaganie wprowadzania nowych rekordów przez generowaną formatkę (nikomu nie będzie się chciało pisać 50 formularzy dla każdej klasy osobno – nie uwierzę!). Formatka zawiera etykietowane pola/comboboxy/slidery – jednak zwracać potrafi tylko zestawy typów prymitywnych. Dla ułatwienia formatka zwraca jedynie tablicę stringów, by nowy „rekord” umieścić w tabelce (CellTable jest parametryzowana typem i wymaga obiektów) musimy uzyskać obiekt. Wiemy jakiej klasy chcemy mieć owy obiekt – pierwszą myślą jest stworzenie nowego obiektu za pomocą konstruktora bezparametrowego a następnie ustalenie pól tego  obiektu. Naturalnym rozwiązaniem wydaje się zastosowanie GWT.create( class clazz) – tu czeka nas niemiła niespodzianka – metoda ta przyjuje jedynie literały klas. Nie zadziała w momencie gdy parametrem jest obiekt Class<T>! Krótkie poszukiwania naprowadziły mnie na trop dwóch bibliotek GWT Reflection oraz GWT ENT. Pierwszy projekt niestety już od dłuższego czasu nie jest rozwijany, drugi wydawał się rokować większe nadzieje – niestety w połączeniu z GWT 2.4 owa biblioteka powoduje błędy, rozwiązaniem okazało się wrócenie do GWT wersji 2.2 – kompletnie nieakceptowalne rozwiązanie! Kolejne poszukiwania doprowadziły mnie do wniosku że trzeba samodzielnie wygenerować klasę fabrykującą obiekty, na rozwiązanie naprowadził mnie temat na stackOverflow oraz jednego z jugowiczów (dzięki Michał!).
    Plan działania jest stosunkowo prosty. Należy oznaczyć klasy, których obiekty mają być tworzone za pomocą interfejsu, który dosłownie nic nie robi, służy jedynie jako znacznik. Następnie należy stworzyć interfejs z jedyną metodą – instantiate(Class<T> clazz) i napisać klasę-generator, która będzie generowała klasę implementującą ten interfejs. Na koniec należy zmodyfikować deskryptor projektu *.gwt.xml. Tyle teorii – pora na częśćpraktyczną.

Czytaj więcej »

Tags: , , , , , ,
Napisany w Java, WWW | Brak komentarzy »

GUAVA – integrujemy z GWT i MVP4G

Autor: Krzysztof Nielepkowicz o 10. lutego 2012

    W poprzednim poście przedstawiłem sposób na szybkie i efektywne tworzenie aplikacji webowych dzięki tandemowi GWT i MVP4G. Jednak arsenał wspomagający jest o wiele większy. Kolejną rzeczą, którą chętnie by widział developer są generyczne operacje na kolekcjach. Parę miesięcy temu miałem okazję skorzystać z LambdaJ przy okazji poprzedniego projektu, chciałem skorzystać z tej biblioteki dla celów obecnego projektu opartego właśnie na GWT i MVP4G (oraz MyBatis). Niestety, spotkało mnie przykre rozczarowanie – LambaJ korzysta z aop’a i refleksji, co skutecznie uniemożliwia współpracę z GWT – na co również wskazuje  JRE Emulation Reference. Jakakolwiek próba użycia LambdaJ kończyła się wyjątkami. To zachęciło mnie to do zapoznania się z niejako zamiennikiem dla LambdaJ – z bibliotekami Google GUAVA.

Czytaj więcej »

Tags: , , , , , ,
Napisany w Java, WWW | Brak komentarzy »

MVP4G – implementacja wzorca MVP dla GWT

Autor: Krzysztof Nielepkowicz o 2. lutego 2012

    Dzisiejszy wpis, będzie niejako przygotowaniem dla kolejnego wpisu. Zaprezentuję połączenie GWT oraz frameworku MVP4G co samo w sobie nie jest niczym niezwykłym, aczkolwiek jest to konfiguracja bardzo owocna.
Dlaczego warto łączyć GWT z innymi frameworkami? Otóż surowe GWT nie ułatwia szybkiego tworzenia większych aplikacji. Sami twórcy GWT polecają stosowanie wzorca MVP (Model View Presenter), jednak nie dostarczają implementacji, gdyż to co jest proponowane w oficjalnym tutorialu dla GWT woła o pomstę do Nieba! Wystarczy spojrzeć na hierarchię klas :
    Dla każdego zdarzenia konieczne jest stworzenie dwóch klas. Nie trudno się domyślić że pisanie aplikacji bardziej skomplikowanej witanie użytkownika po naciśnięciu przycisku spowoduje wykładniczy przyrost klas. Taki sposób pisania aplikacji nie przypadł mi do gustu, zapytałem jugowiczów jak ugryźć temat. Tak się dowiedziałem o MVP4G – implementacji owego wzorca. Nie będę tutaj się rozpisywał na temat zalet i wad – po prostu pokażę jak stworzyć projekt.
Potrzebne biblioteki/narzedzia :
Na początek tworzymy nowy projekt w Eclipse – aplikacja GWT wraz z sample code :
  W następnym kroku odznaczamy „Use Google App Engine” bo nie będzie nam potrzebny ale za to zaznaczamy opcję „Generate Project Sample Code”. Eclipse wygeneruje nam całą infrastrukturę projektu, która się przyda – przynajmniej w większości. Ja swój projekt nazwałem tutek_MVP4G. Zaczynamy od usunięcia niepotrzebnych plików i odwołań do nich w kodzie :
  • FieldVerifier
  • Tutek_MVP4G (wygenerowana klasa domyślnego entryPoint’a)
    Wyżej wymienione rzeczy są zbędne – usuwamy je. Jednak skoro usunęliśmy nasz entry point to jak rozpocznie się aplikacja? następny krok rozwiązuje ten problem – edycja  pliku konfiguracyjnego xml – tutek_MVP4G.gwt.xml :
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='tutek_mvp4g'>
  <!-- Inherit the core Web Toolkit stuff.                        -->
  <inherits name='com.google.gwt.user.User'/>

  <!-- Inherit the default GWT style sheet.  You can change       -->
  <!-- the theme of your GWT application by uncommenting          -->
  <!-- any one of the following lines.                            -->
  <inherits name='com.google.gwt.user.theme.clean.Clean'/>
  <!-- <inherits name='com.google.gwt.user.theme.standard.Standard'/> -->
  <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
  <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->

  <inherits name='com.mvp4g.Mvp4gModule' />

  <!-- Other module inherits                                      -->

  <!-- Specify the app entry point class.                         -->

  <!-- Specify the paths for translatable code                    -->
  <source path='client'/>
  <source path='shared'/>

</module>

Następnie przystępujemy do tworzenia struktury pakietów projektu. W pakiecie „tutek.client” tworzymy kolejno pakiety „view”, „presenter” oraz „bean”.

    Pora utworzyć pierwszy widok (kolejność nie jest wymuszona) – w pakiecie „tutek.client.view” tworzymy widok – do tego celu wykorzystamy UIBinder. Oczywiście widokiem może być dowolna klasa rozszerzająca Composite, jednak użycie UIBindera nieco więcej nas nauczy na temat mechanizmów MVP4G i tworzenia przez framework widoków oraz wiązania ich z prezenterami.
    Po utworzeniu widoku otwieramy „designera”, jeśli otworzy się okienko projektowania UI wraz z paletą kontrolek to znaczy, że do tej pory nie popełniliśmy błędu, w przeciwnym razie warto sprawdzić czy zostały dodane wszystkie wymagane biblioteki. Kolejnym krokiem jest utworzenie bean’a – będzie to kultowa klasa „Person”. Wiem, wiem – w innych tutorialach mamy przycisk i pole tekstowe. W tym jednak potrzebna jest nam tabelka i przycisk – przyda się do kolejnego wpisu 😉 Wróćmy jednak do tworzenia klasy danych, która powinna wyglądać mniej więcej tak :
package tutek.client.bean;

public class Person
{
 public String name;
 public String surName;

 public Person(String name, String surName)
 {
  super();
  this.name = name;
  this.surName = surName;
 }
}

 

    Wracamy do tworzenia widoku. Dużą zaletą UIBindera jest deklaratywny sposób tworzenia interfejsu z użyciem XML, co doskonale wpasowuje się we wzorzec MVP. Poniżej XML do widoku, wystarczy go skopiować do własnego projektu :

 

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
 xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:p1="urn:import:com.google.gwt.user.cellview.client">
 <ui:style>

 </ui:style>
 <g:HTMLPanel>
  <g:VerticalPanel>
   <p1:CellTable ui:field="cellTable"/>
   <g:FlowPanel>
    <g:Button ui:field="btn_filter" text="Filtruj Wacków"/>
   </g:FlowPanel>
  </g:VerticalPanel>
 </g:HTMLPanel>
</ui:UiBinder>

 

 Jednak UIBinder to nie tlyko XML, towarzyszy mu klasa rozszerzająca „com.google.gwt.user.client.ui.Composite”, podobnie jak XML, jest ona generowana podczas pracy z designerem. Jednak wymaga zmian – należy właściwie sparametryzować tabelkę wcześniej stworzoną klasą „Person”.
package tutek.client.view;

import tutek.client.bean.Person;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.client.ui.Button;

public class TutekView extends Composite
{

 private static TutekViewUiBinder uiBinder = GWT.create(TutekViewUiBinder.class);

 @UiField(provided=true)
 public CellTable<Person> cellTable = new CellTable<Person>();
 @UiField
 public Button btn_filter;

 interface TutekViewUiBinder extends UiBinder<Widget, TutekView>
 {
 }

 public TutekView()
 {
  initWidget(uiBinder.createAndBindUi(this));
 }

}

Ok, mamy już widok, brakuje teraz prezentera – czegoś co by kontrolowało widok zgodnie z ideą wzorca. Jednak zanim stworzymy klasę rozszerzającą „com.mvp4g.client.presenter.BasePresenter” musimy się zatroszczyć o EventBus – oś wokół której obraca się cały framework MVP4G. Tworzymy zatem interfejs rozszerzający „com.mvp4g.client.event.EventBus”:

package tutek.client;

import com.mvp4g.client.event.EventBus;

public interface TutekEventBus extends EventBus
{
    //pusty interfejs!!
}

Teraz gdy w projekcie mamy obecny eventBus można stworzyć klasę prezentera kontrolującą widok, w skład którego wchodzi tabelka i przycisk. Presenter będzie wypełniał tabelkę danymi oraz definiował obsługę zdarzenia kliknięcia na przycisku.

package tutek.client.presenter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import tutek.client.TutekEventBus;
import tutek.client.bean.Person;
import tutek.client.view.TutekView;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.view.client.ListDataProvider;
import com.mvp4g.client.annotation.Presenter;
import com.mvp4g.client.presenter.BasePresenter;

@Presenter(view = TutekView.class)
public class TutekPresenter extends BasePresenter<TutekView, TutekEventBus>
{
 private ListDataProvider<Person> dataProvider;

Teraz czas na omówienie poszczgólnych fragmentów powyższego kodu. Najpierw za pomocą @Presenter określamy widok który będzie kontrolowany następnie deklarując klasę parametryzujemy ją eventBusem stworzonym w poprzednim kroku oraz widokiem. Następnie przeciążamy metodę „bind” :

 @Override
 public void bind()
 {
  GWT.log("bind");
  //tworzymy kolumny
  TextColumn<Person> name = new TextColumn<Person>()
  {
   @Override
   public String getValue(Person object)
   {
    return object.name;
   }
  };

  TextColumn<Person> surName = new TextColumn<Person>()
  {
   @Override
   public String getValue(Person object)
   {
    return object.surName;
   }
  };

  //dodajemy kolumny
  view.cellTable.addColumn(name);
  view.cellTable.addColumn(surName);

  //obsługa zdarzeń
  view.btn_filter.addClickHandler(new ClickHandler()
  {
   @Override
   public void onClick(ClickEvent event)
   {
    List<Person> lst = dataProvider.getList();
    List<Person> newLst = new ArrayList<Person>();
    for(Person prs : lst)
    {
     if(prs.name.toLowerCase().equals("wacek"))
     {
      newLst.add(prs);
     }
    }
    dataProvider.setList(newLst);
   }
  });
 }

Metoda „bind” jest wywoływana przy pierwszym odwołaniu do prezentera – jest to dobre miejsce na zainicjowanie kontrolek. Najpierw tworzymy kolumny dla tabeli, dodajemy je oraz na koniec definiujemy obsługę zdarzeń – przefiltrowanie wszystkich Wacków, mało eleganckie – ale zaradzimy temu w kolejnym poście ;). Pora wrócić do EventBus i uzupełnić interfejs o anotacje oraz zdarzenia :

package tutek.client;

import tutek.client.presenter.TutekPresenter;
import com.mvp4g.client.annotation.Event;
import com.mvp4g.client.annotation.Events;
import com.mvp4g.client.annotation.Start;
import com.mvp4g.client.event.EventBus;

@Events(startPresenter = TutekPresenter.class)
public interface TutekEventBus extends EventBus
{

 @Start //obowiązkowe zdarzenie startowe
 @Event(handlers = {TutekPresenter.class})
 public void onStart();

}

Trochę kodu przybyło. Pierwszą sprawą jest określenie inicjalnego prezentera – stanu początkowego. Następnie definiujemy zdarzenia zachodzące w aplikacji. Zdarzenie to nic innego jak metoda interfejsu. Wśród zdarzeń musi być wyszczególnione anotacją @Start zdarzenie startowe – łatwo zapamiętać- tylko jedno zdarzenie może posiadać tą anotację, która z koleji musi wystąpić. Dla każdego zdarzenia obowiązkowa jest anotacja @Event i to ona stanowi, że metoda interfejsu jest zdarzeniem. W parametrach tej anotacji określamy obsługujące prezentery – w tym przypadku tylko jeden, w którym musi być metoda obsługująca to zdarzenie o nazwie onOnStart(). Zasada jest prosta, trochę jak z java beans, do nazwy metody z iterfejsu EventBus dodajemy przedrostek „on” a pierwszą literę pierwotnej nazwy zmieniamy na wielką. Pora wrócić do prezentera i zobaczyć jak wygląda obsługa zdarzenia :

 public void onOnStart()
 {
  GWT.log("onStart()");
  //tworzymy dane
  Person persons[] = new Person[]{new Person("Wacek", "Kowalski"), new Person("Wacek", "Siczek"), new Person("Marcel", "Plusk"),
   new Person("Bronek", "Ogonek"), new Person("Wacek", "wachowski")};

  dataProvider = new ListDataProvider<Person>();
  dataProvider.addDataDisplay(view.cellTable);

  dataProvider.setList( new ArrayList<Person>(Arrays.asList(persons) ) );
 }
}

Wywołanie metody „onOnStart” następuje po wygenerowaniu zdarzenia – odpowiada za to anotacja @Start, następuje po wywołaniu metody „bind” podczas inicjalizacji prezentera. Pozostałe zdarzenia są inicjowane w prezentererze za pomocą wywołania eventBus.<zdarzenie> – w tym momencie jest generowane zdarzenie, trafia na szynę gdzie rozjeżdża (obrazowo ;)) je prezenter zadeklarowany w parametrze „handlers” anotacji @Event . Wracając do naszego zdarzenia, jako że jest to zdarzenie generowane automatycznie w ramach inicjalizacji całej aplikacji, wypełniamy tabelkę danymi.

To już wszystko. Pozostaje jedynie uruchomić projekt. Jak widać korzystanie z MVP4G nie jest ani trudne, ani nie generuje kodu tempie wykładniczym – wręcz przeciwnie. Gotowy projekt Eclipsa również umieściłem   w moim magazynku plików do ściągnięcia. Następny wpis będzie rozwinięciem tego co teraz zostało zrobione.

Tags: , , , , , , , ,
Napisany w Java, WWW | Brak komentarzy »