W projekcie utworzono bibliotekę znaczników niestandardowych opartą na klasach prostych wprowadzonych do JSP 2.0, wzorowano się na książkach "Head First Servlets & JSP. Edycja polska. Wydanie II", "Core Java Servlets i JavaServer Pages. Tom II. Wydanie II". Zaprojektowane znaczniki odpowiadają za wyświetlenie menu i listy opublikowanych kategorii z wybranej sekcji. W deskryptorze TLD w znacznikach i atrybutach znaczników zastosowano element <description>. Aby podpowiedzi znaczników były bardziej czytelne w środowisku Eclipse zastosowano kody znaków (Tabela 1.), takie podejście umożliwiło zastosowanie języka HTML (rys. 1.). Artykuł wymaga znajomości bazy danych MySQL i technologii JSP. Opis CSS i HTML w artykule został pominięty. Technologia JSP obecnie wspierana jest przez firmę Google "Google App Engine”. Na samym końcu artykułu podano kilka książek, które pozwolą zapoznać się z wymienionymi technologiami.
Wygląd znaku: | Nazwa znaku: | Kod: | Kod mnemoniczny: |
> | Znak większości | = | > |
< | Znak mniejszości | < | < |
Biblioteka znaczników niestandardowych korzysta z tabel sekcje, kategorie, artykuły, typy_menu, pola_menu, typy_pozycji_menu zaprezentowanych na rysunku 2. Baza danych zaprojektowana za pomocą programu MySQL Workbench.
Rys. 2. Prezentacja relacji pomiędzy tabelami w bazie danych
Nazwa pola: | Opis: |
id_sekcja | Klucz główny przydzielony automatycznie |
nazwa_sekcji | Nazwa sekcji |
opis_sekcji | Opis sekcji |
data_utworzenia | Data utworzenia sekcji |
data_opublikowania | Data opublikowania sekcji |
kolejnosc | Pole przechowuje numer odpowiedzialny za kolejność wyświetlania wybranej sekcji |
Nazwa pola: | Opis: |
id_kategoria | Klucz główny przydzielony automatycznie |
id_sekcja | Klucz obcy z tabeli „sekcje” |
nazwa_kategorii | Nazwa kategorii |
opis_kategorii | Opis kategorii |
data_utworzenia | Data utworzenia kategorii |
data_opublikowania | Data opublikowania kategorii |
kolejnosc | Pole przechowuje numer odpowiedzialny za kolejność wyświetlania kategorii w wybranej sekcji |
Nazwa pola: | Opis: |
id_artykul | Klucz główny przydzielany automatycznie do artykułu |
id_uzytkownik | Klucz obcy z tabeli „uzytkownicy” - tabela pominięta w artykule |
id_kategoria | Klucz obcy z tabeli „kategorie” |
tytul | Tytuł artykułu |
tekst_artykulu | Zawartość artykułu |
data_utworzenia | Data utworzenia artykułu |
data_opublikowania | Data opublikowania artykułu |
data_modyfikacji | Data ostatniej modyfikacji artykułu |
meta_slowa_kluczowe | Słowa kluczowe znaczniku „meta” w HTML |
meta_opis | Opis znaczniku „meta” w HTML |
meta_autor | Autor artykułu, znacznik „meta” w HTML |
kolejnosc | Pole przechowuje numer odpowiedzialny za kolejność wyświetlania w wybranej kategorii |
przeczytano | Pole zawiera liczbę odpowiedzialną za ilość odwiedzin gościa serwisu w danym artykule |
strona_tytulowa | Pole odpowiedzialne za przechowywanie informacji, czy artykuł ma być wyświetlany na głównej stronie serwisu |
Nazwa pola: | Opis: |
id_pole_menu | Klucz główny przydzielony automatycznie |
id_typ_menu | Klucz obcy z tabeli „typy_menu” |
id_typ_pozycji_menu | Klucz obcy z tabeli „typy_pozycji_menu” |
nazwa | Nazwa przycisku w pozycji menu |
opis | Opis przycisku znacznik „title” |
adres_strony | Adres strony internetowej |
okno | Pole zawiera wartość atrybutu „target” znacznika <a href=””></a> |
data_utworzenia | Data utworzenia przycisku w pozycji menu |
data_opublikowania | Data opublikowania przycisku w pozycji menu |
kolejnosc | Pole przechowuje numer odpowiedzialny za kolejność wyświetlenia przycisku w wybranym menu |
komponent_id | Pole nie jest obowiązkowe i przechowuje numer z klucza głównego komponentu, który jest podpinany pod wybrany przycisk w pozycji menu |
Nazwa pola: | Opis: |
id_typ_menu | Klucz główny przydzielony automatycznie |
typ_menu | Unikatowa nazwa tekstowa pozycji menu np.: mainmenu |
tytul | Nazwa menu |
opis | Opis menu |
Nazwa pola: | Opis: |
id_typ_pozycji_menu | Klucz główny przydzielony automatycznie |
nazwa | Pole tekstowe zawierające nazwę typu pozycji menu np.: Artykuły => Sekcje, Pojedynczy artykuł, Łącze zewnętrzne |
opis | Opis typu pozycji menu |
akcja | Pole, dzięki któremu program rozpoznaje typ pozycji menu wybranego dla konkretnego przycisku. Nazwa pola jest unikatowa oraz typu string. Programiście lepiej jest oprogramowywać dodatkowe funkcje korzystając z pola „akcja” niż za pomocą klucza głównego. Przykładowe nazwy: review_articles, single_article, external_link |
Przykładową zawartość tabel typy_menu (Listing 1) i typy_pozycji_menu (Listing 2) przedstawiono poniżej w postaci instrukcji wstawienia INSERT.
Listing 1. Tabela typy_menu
INSERT INTO `typy_menu` (`typ_menu`, `tytul`, `opis`) VALUES ('mainmenu', 'Menu główne', 'Menu główne znajdziemy z lewej strony aplikacji www.');
INSERT INTO `typy_menu` (`typ_menu`, `tytul`, `opis`) VALUES ('topmenu', 'Menu górne', 'Menu górne strony');
Listing 2. Tabela typy_pozycji_menu
INSERT INTO `typy_pozycji_menu` (`nazwa`, `opis`, `akcja`) VALUES ('Artykuły => Sekcje', 'Odpowiada za wyświetlenie z wybranej sekcji wszystkich kategorii w tabelce.', 'review_articles');
INSERT INTO `typy_pozycji_menu` (`nazwa`, `opis`, `akcja`) VALUES ('Pojedynczy artykuł', 'Odpowiada za wyświetlenie tylko jednego wybranego przez nas artykułu.', 'single_article');
INSERT INTO `typy_pozycji_menu` (`nazwa`, `opis`, `akcja`) VALUES ('Łącze zewnętrzne', 'Odpowiada za podłączenie to pozycji menu adresu strony internetowej.', 'external_link');
Zrealizowany projekt posiada dwa menu. Pierwsze poziome (rys. 3.) i menu główne pionowe (rys. 4.). Drugi znacznik zostanie wyświetlony na stronie internetowej, kiedy wybrany zostanie przycisk z menu, do którego podpięto sekcję w panelu pracownika. Lista wszystkich opublikowanych kategorii z wybranej sekcji (rys. 5.).
Rys. 4. Menu główne aplikacji
Pliki potrzebne w bibliotece TLD własnego autorstwa to:
- cms-taglib.tld – plik deskryptora biblioteki znaczników własnego autorstwa. Zawiera dwa skonfigurowane znaczniki specjalnie dla projektu: menu, reviewArticles (Listing 6);
- GuestHeader.jsp – plik odpowiada za górną część strony internetowej wraz ze znacznikiem generującym menu poziome (Listing 7);
- GuestContent.jsp – plik odpowiada za środkową część strony internetowej. Zawiera znacznik menu (odpowiedzialny za wygenerowanie menu głównego strony) i znacznik reviewArticles (wyświetla wszystkie opublikowane kategorie w formie listy z wybranej sekcji) (Listing 8);
- MenuTag.java – klasa odpowiedzialna za obsługę znacznika menu (Listing 9);
- ReviewArticlesTag.java – klasa odpowiedzialna za obsługę znacznika reviewArticles (Listing 10);
- GuestFactory.java – klasa zawiera metody komunikujące się z bazą danych potrzebne do prawidłowego działania znaczników menu, reviewArticles (Listing 11).
Zaprojektowana biblioteka znaczników (specjalnie dla projektu Piksel-Net) została tak przygotowana, aby dodanie nowego typu menu było możliwe jak najmniejszym nakładem pracy (Listing 3).
Listing 3. Dodanie nowego typu menu do systemu
INSERT INTO `typy_menu` (`typ_menu`, `tytul`, `opis`)
VALUES ('bottommenu', 'Menu dolne', 'Menu dolne strony');
Jednak, aby menu po zaprojektowaniu w panelu pracownika było widoczne dla gości odwiedzających serwis, należy znacznik z listingu 4 umieścić w dowolnym pliku w katalogu guest/layout. Opisywany katalog odpowiada za wygląd strony internetowej widocznej dla zwykłego użytkownika systemu.
Listing 4. Umieszczenie nowego typu menu na stronie internetowej
<pn:menu typeMenu="bottommenu" title="Menu dolne" ></pn:menu>
Kod odpowiedzialny za usunięcie nowego typu menu (Listing 5) należy poprzedzić usunięciem wszystkich przycisków w panelu pracownika, inaczej zostanie wygenerowany błąd podczas wykonywania kodu SQL. Tabele w bazie danych są powiązane relacjami, dzięki czemu usunięcie rekordu powiązanego z innymi tabelami zostanie wykryte przez bazę danych MySQL i wykonanie polecenia zostanie zablokowane.
Listing 5. Polecenie odpowiedzialne za usunięcie nowego typu menu
DELETE FROM `typy_menu` WHERE `id_typ_menu`='3';
Konfiguracja biblioteki znaczników niestandardowych znajduje się w deskryptorze TLD (Listing 6), aby opis znaczników był bardziej czytelny utworzono tabelę 8. Przed rozpoczęciem korzystania z biblioteki znaczników należy utworzyć unikatową nazwę URI, która musi być identyczna z dyrektywą taglib z unikatowym przedrostkiem (Listing 7, Listing 8).
Nazwa biblioteki (URI) – http://piksel-net.pl/jstl/cms | ||
Znacznik: | Atrybut: | Opis: |
menu | Znacznik odpowiada za wyświetlenie menu na stronie internetowej utworzonego za pomocą panelu użytkownika systemu. Współpracuje z bazą danych MySQL. | |
typeMenu | Atrybut wymagany, przyjmuje „typ menu”, jaki jest obecnie dodany do programu. Musi się zgadzać z typem menu istniejącym w bazie danych (tabela typy_menu, pole typ_menu) np.: typeMenu=”mainmenu”. | |
classes | Klasa css dla menu. Pominiecie atrybutu powoduje przypisanie domyślnych wartości ustawionych w programie dla wykorzystywanych znaczników html. | |
localization | Atrybut odpowiedzialny za ułożenie menu, są dwie opcje:
|
|
title | Tytuł menu jest opcjonalny. | |
reviewArticles | Odpowiada za wyświetlenie w formie listy wszystkich opublikowanych kategorii z wybranej sekcji. | |
id | Atrybut wymagany, pobiera klucz główny z bazy danych wybranej sekcji (tabela sekcje, pole id_sekcja). | |
classes | Klasa css dla listy kategorii. Pominiecie atrybutu powoduje przypisanie domyślnych wartości ustawionych w programie dla wykorzystywanych znaczników html. |
Na rysunku 6 przedstawiono układ plików potrzebnych podczas pracy ze znacznikami menu (GuestContent.jsp, GuestHeader.jsp), reviewArticles (GuestContent.jsp) skonfigurowanych w pliku cms-taglib.tld. Diagram układu katalogów w projekcie został zrealizowany za pomocą programu „Microsoft Visio Professional 2010”.
Listing 6. Deskryptor TLD WEB-INF/tlds/cms-taglib.tld
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
<description>
Biblioteka znaczników przygotowana specjalnie dla projektu pracy magisterskiej, autor Piotr Klimek.
</description>
<tlib-version>1.0</tlib-version>
<short-name>cms</short-name>
<uri>http://piskel-net.pl/jstl/cms</uri>
<tag>
<description>
Znacznik odpowiada za wyświetlenie menu na stronie internetowej utworzonego za pomocą panelu użytkownika systemu. Współpracuje z bazą danych MySQL.<br/> Atrybuty wymagane znacznika to: <ul> <li>typeMenu - należy podać „typ_menu” przechowywany w bazie danych w tabeli „type_menu” np.: mainmenu.</li> </ul> <br/>
Atrybuty opcjonalne znacznika to:
<ul> <li>classes - istnieje możliwość przypisania do znacznika klasy css;</li> <li>localization - atrybut odpowiedzialny za ułożenie pozycji menu (poziomo, pionowo);</li> <li>title - istnieje możliwość przypisania tytułu do menu.</li> </ul>
</description>
<name>menu</name>
<tag-class>pl.wiedzanaplus.MenuTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>Tytuł menu jest opcjonalny.</description>
<name>title</name>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<description>
Atrybut przyjmuje „typ menu”, jaki jest obecnie dodany do programu. Musi się zgadzać z typem menu istniejącym w bazie danych (tabela typy_menu, pole typ_menu) np.: typeMenu=”mainmenu”.
</description>
<name>typeMenu</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<description>Atrybut odpowiedzialny za ułożenie menu, są dwie opcje:
<ul><li>horizontal (poziomy);</li> <li>vertical (pionowy).</li></ul><br/> Pominięcie atrybutu powoduje przypisanie domyślnej wartości „vertical”.
</description>
<name>localization</name>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<description>
Klasa css dla menu. Pominiecie atrybutu powoduje przypisanie domyślnych wartości ustawionych w programie dla wykorzystywanych znaczników html.
</description>
<name>classes</name>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
<tag>
<description>
Odpowiada za wyświetlenie w formie listy wszystkich kategorii z wybranej sekcji.<br/>
Atrybuty wymagane znacznika to:
<ul>
<li>id - pobiera klucz główny z bazy danych wybranej sekcji (tabela sekcje, pole id_sekcja).</li>
</ul>
<br/>
Atrybuty opcjonalne znacznika to:
<ul>
<li>classes - istnieje możliwość przypisania do znacznika klasy css;</li>
</ul>
</description>
<name>reviewArticles</name>
<tag-class>pl.wiedzanaplus.ReviewArticlesTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>
Atrybut wymagany, pobiera klucz główny z bazy danych wybranej sekcji (tabela sekcje, pole id_sekcja).
</description>
<name>id</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>
Klasa css dla listy kategorii. Pominiecie atrybutu powoduje przypisanie domyślnych wartości ustawionych w programie dla wykorzystywanych znaczników html.
</description>
<name>classes</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
Listing 7. Fragment pliku guest/layout/GuestHeader.jsp
<?xml version="1.0" encoding="utf-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:pn="http://piskel-net.pl/jstl/cms" version="2.0">
…
<pn:menu typeMenu="topmenu" localization="horizontal" classes="topmenu"></pn:menu>
…
</jsp:root>
Listing 8. Fragment pliku guest/layout/GuestContent.jsp
<?xml version="1.0" encoding="utf-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:pn="http://piskel-net.pl/jstl/cms" version="2.0">
...
<pn:menu typeMenu="mainmenu" title="Menu główne" classes="mainmenu"></pn:menu>
...
<pn:reviewArticles id="${param.id}" classes="reviewArticlesSection"/>
...
</jsp:root>
Listing 9. Klasa pl/wiedzanaplus/MenuTag.java
package pl.wiedzanaplus;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* Klasa obsługi znacznika menu. Generuje menu dla gościa serwisu, utworzone za pomocą panelu pracownika.
*/
public class MenuTag extends SimpleTagSupport {
private String title = null;
private String typeMenu = null;
private String localization = "";
private String classes = null;
public void setTypeMenu(String typeMenu) { this.typeMenu = typeMenu; }
public void setLocalization(String localization) {
this.localization = localization; }
public void setTitle(String title) { this.title = title; }
public void setClasses(String classes) { this.classes = classes; }
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
if (this.classes != null) {
if (this.title == null) {
out.print("<div class='"+this.classes+"'><ul>");
}else {
if (this.localization.equals("horizontal")) {
out.print("<div class='"+this.classes+"'><h3 style='float: left;'>"+this.title+"</h3><ul>");
} else {
out.print("<div class='"+this.classes+"'><h3>"+this.title+"</h3><ul>");
}
}
} else {
if (this.title == null) {
out.print("<div><ul>");
}else {
out.print("<div><h3>"+this.title+"</h3><ul>");
}
}
try {
Guest menu = new Guest();
ResultSet result = menu.sqlMenu(this.typeMenu);
int component_id = 0;
// Odczytujemy wybrane menu z bazy danych.
while(result.next()) {
if (this.localization.equals("horizontal")) {
out.print("<li style='float: left;'>");
} else {
out.print("<li>");
}
// Sprawdzamy, czy pozycja menu jest linkiem zewnętrznym.
if (result.getString(2).equals("external_link")) {
out.print("<a href='"+result.getString(5)+"'");
if (result.getString(4) != null) {
out.print(" title='"+result.getString(4)+"' ");
}
out.print("' target='"+result.getString(6)+"'>"+result.getString(3)+"</a>");
} else {
out.print("<a href='index.jsf?action="+result.getString(2)+"&id="+result.getInt(1)+"");
component_id = result.getInt(7);
if(component_id != 0)
out.print("&component="+component_id + "");
if (result.getString(4) != null) {
out.print("' title='"+result.getString(4));
}
out.print("' target='"+result.getString(6)+"'>"+result.getString(3)+"</a>");
}
out.print("</li>");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
out.print("</ul></div>");
} // end method.
} // end class.
Listing 10. Klasa pl/wiedzanaplus/ReviewArticlesTag.java
package pl.wiedzanaplus;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* Klasa obsługi znacznika <pn:reviewArticles />. Generuje listę opublikowanych kategorii z wybranej sekcji, która została podpięta pod
* konkretny przycisk w pozycji menu. Również zlicza liczbę opublikowanych
* artykułów w każdej z wyświetlonych kategorii i wyświetla obok
* nazwy kategorii.
*/
public class ReviewArticlesTag extends SimpleTagSupport {
private int id = 0;
private String classes = null;
public void setId(int id) { this.id = id; }
public void setClasses(String classes) { this.classes = classes; }
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
Guest objReviewArticles;
try {
objReviewArticles = new Guest();
String result = objReviewArticles.sqlGetMenuNameField(this.id);
if (result.equals("error")) {
out.print("<h3 id='error'>Przepraszamy, ale obecnie pod wprowadzonym adresem nie ma dostępnych żadnych informacji!</h3>");
} else {
if (this.classes != null) {
out.print("<div class='"+this.classes+"'>");
} else {
out.print("<div>");
}
out.print("<h2>"+result+"</h2>");
out.print("<span>Lista wszystkich kategorii:</span>");
ResultSet result2 = objReviewArticles.sqlReviewArticlesSection(this.id);
out.print("<ul>");
while(result2.next()) {
out.print("<li>");
out.print("<a href='index.jsf?action="+result2.getString(7)+"&id="+result2.getInt(1)+"&component="+result2.getInt(6)+"&categoryid="+result2.getInt(2)+"'>");
out.print(result2.getString(3));
out.print("</a>, Ilość artykułów ( "+result2.getInt(5)+" )<br />");
if (result2.getString(4) == null) {
out.print("<p> </p>");
} else {
out.print("<p>"+result2.getString(4)+"</p>");
}
out.print("</li>");
}
out.print("</ul>");
out.print("</div>");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} // end method.
} // end class.
Listing 11. Fragment klasy pl/wiedzanaplus/database/GuestFactory.java
…
/**
* Metoda odpowiedzialna za pobranie z bazy danych wszystkich opublikowanych
* pozycji menu z wybranego typu menu.
*/
public ResultSet sqlMenu(String typmenu) throws SQLException {
// Tworzymy polecenie
Statement stmt = conn.createStatement();
// Zapytanie SQL pobiera główne menu.
String query = "SELECT pm.id_pole_menu, tpm.akcja, pm.nazwa, pm.opis, pm.adres_strony, pm.okno, pm.komponent_id FROM `pola_menu` pm, `typy_menu` tm, `typy_pozycji_menu` tpm WHERE pm.id_typ_menu = tm.id_typ_menu AND pm.id_typ_pozycji_menu = tpm.id_typ_pozycji_menu AND tm.typ_menu = '"+typmenu+"' AND pm.data_opublikowania is not null ORDER BY kolejnosc ASC;";
// Wykonujemy zapytanie sql.
ResultSet result = stmt.executeQuery(query);
return result;
} // koniec metody.
…
/**
* Metoda odpowiedzialna za pobranie z bazy danych nazwy pola menu.
*/
public String sqlGetMenuNameField(int id) throws SQLException {
Statement stmt = conn.createStatement();
String query = "SELECT nazwa FROM pola_menu WHERE id_pole_menu = '"+id+"'";
ResultSet result = stmt.executeQuery(query);
result.next();
String name = result.getString(1);
return name;
} // koniec metody.
…
/**
* Metoda odpowiedzialna za pobranie wszystkich opublikowanych kategorii
* z wybranej sekcji. Informuje również o ilości opublikowanych artykułów
* w każdej z kategorii.
*/
public ResultSet sqlReviewArticlesSection(int id) throws SQLException {
// Tworzymy polecenie
Statement stmt = conn.createStatement();
// Zapytanie SQL pobiera główne menu.
String query = "SELECT pm.id_pole_menu, k.id_kategoria, k.nazwa_kategorii, k.opis_kategorii, COUNT(DISTINCT a.id_artykul) AS ilosc_artykulow, pm.komponent_id, tpm.akcja FROM `pola_menu` pm, `typy_pozycji_menu` tpm, `sekcje` s, `kategorie` k, `artykuly` a WHERE s.id_sekcja = pm.komponent_id AND tpm.id_typ_pozycji_menu = pm.id_typ_pozycji_menu AND k.id_sekcja = s.id_sekcja AND k.id_kategoria = a.id_kategoria AND a.data_opublikowania is not null AND id_pole_menu = '"+id+"' GROUP BY k.nazwa_kategorii, k.opis_kategorii, pm.komponent_id, tpm.akcja ORDER BY k.kolejnosc ASC;";
// Wykonujemy zapytanie sql.
ResultSet result = stmt.executeQuery(query);
return result;
} // koniec metody.
…
W artykule bibliotekę znaczników niestandardowych zintegrowano z bazą danych MySQL. Lepszym rozwiązaniem byłoby przekazywanie danych w formie tablicy do znacznika, dzięki czemu biblioteka stałaby się uniwersalna i można byłoby zastosować ją do wielu projektów bez modyfikacji kodu. Jest to bardzo ciekawy temat na pracę inżynierską, czy magisterską, jeśli byłby ktoś zainteresowany tematem zapraszamy do skorzystania z artykułu.
Lista książek, do których odwołano się w artykule:
- Bryan Basham, Kathy Sierra, Bert Bates: Head First Servlets & JSP. Edycja polska. Wydanie II, Wydawnictwo Helion, 2008.
- Marty Hall, Larry Brown, Yaakov Chaikin: Core Java Servlets i JavaServer Pages. Tom II. Wydanie II, Wydawnictwo Helion, 2009.
Warto przeczytać również:
- Wprowadzenie do środowiska programistycznego Eclipse.
- Wprowadzenie do technologii JavaServer Pages (JSP).
- MySQL wprowadzenie.
- MySQL Workbench.
Wybrane książki:
- Vishal Layka: Java. Projektowanie aplikacji WWW, Wydawnictwo Helion, 2015.
- John Viescas, Michael J. Hernandez: Zapytania w SQL. Przyjazny przewodnik, Wydawnictwo Helion, 2015.
- Jon Duckett: HTML i CSS. Zaprojektuj i zbuduj witrynę WWW, Wydawnictwo Helion, 2014.
- Mark C. Chu-Carroll: Google App Engine. Kod w chmurze, Wydawnictwo Helion, 2012.
- Adriaan de Jonge: Google App Engine. Tworzenie wydajnych aplikacji w Javie, Wydawnictwo Helion, 2012.
- Bryan Basham, Kathy Sierra, Bert Bates: Head First Servlets & JSP. Edycja polska. Wydanie II (Rusz głową!), Wydawnictwo Helion, 2008.
Strony internetowe:
- Wszystkie zrealizowane projekty pod marką „Piksel-Net” są zaprezentowane na stronie www.piksel-net.pl.
- Visio 2010 można znaleźć na stronie http://office.microsoft.com/pl-pl/visio.
- Więcej na temat Google App Engine na stronie https://developers.google.com/appengine/