Una web application è un programma eseguito all’interno di un web server, generalmente il programma è contenuto in un file WAR ed installato in un Servlet Container come Tomcat, JBoss, etc. Le web application generalmente si compongono di un back-end e di un front-end. Il primo è responsabile della implementazione della logica applicativa, mentre il secondo dell’interazione con l’utente finale. Il modo più semplice di implementare il back-end è attraverso l’uso delle Servlet a meno che non si utilizzino framework applicativi come struts, spring o JSF (che comunque utilizzano servlet specifiche per il loro funzionamento). Il front-end, invece, si realizza utilizzando linguaggi e tecnologie interpretate dai browser client quali: HTML, CSS e Javascript.
Tralasciamo gli aspetti di dettaglio per concentrarci invece sul nostro obiettivo, ovvero realizzare da zero una web application in java che utilizza Bootstrap, che è un framework per lo sviluppo di interfacce Web, mutuato da Twitter, diventato ormai uno standard de facto per la realizzazione di interfacce responsive.
Nel seguito del post mostriamo i passi necessari per la realizzazione dell’applicazione che è comunque scaricabile interamente in fondo al post.
Configurazione del progetto
Il primo passo è il set-up dell’applicazione. Per farlo utilizziamo Maven, nella versione 3 o superiore, quindi apriamo una shell di comando e posizioniamoci nella cartella in cui vogliamo creare il progetto. Quindi utilizziamo la seguente istruzione, valorizzando opportunamente artifactId
e groupId
:
1 2 3 4 |
mvn archetype:generate -DgroupId={project-packaging} -DartifactId={project-name} -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false |
1 2 3 4 |
mvn archetype:generate -DgroupId=it.inspiredsoft.employees -DartifactId=employees -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false |
Quando Maven ha terminato il suo lavoro, aprire Eclipse, dove sarà stato precedentemente configurato Maven, ed importare il progetto (File -> Import -> Maven-> Existing Maven Project). Noterete immediatamente che Maven ha generato un progetto del tipo Dynamic Web Module ma con la tipica struttura di un progetto Maven (conforme al suo Standard Directory Layout). Prima di procedere apriamo il file web.xml
collocato nella cartella src/main/webapp/WEB-INF
che dovrebbe apparire così:
1 2 3 4 5 6 7 |
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app> |
DOCTYPE
il progetto creato è un Dynamic Web Module versione 2.3 e se non volete perdere ore cercando di comprendere perché le vostre JSP non interpretano le espressioni EL vi consiglio vivamente di aggiornare la versione almeno alla 2.5. In alternativa dovrete inserire in tutte le vostre JSP la direttiva:
1 |
<jsp:directive.page isELIgnored="false"/> |
In questo post abbiamo preferito la prima soluzione quindi il nostro file web.xml
è diventato:
1 2 3 4 5 6 |
<web-app 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-app_2_5.xsd" version="2.5"> <display-name>employees</display-name> </web-app> |
Completiamo la procedura aggiornando anche la versione nel Project Facets. Se Eclipse ve lo impedisce potete disabilitare la facet Dynamic Web Module e quindi eseguire Maven->Update Projec
t e Maven provvederà a abilitare la facet nella versione corretta.
Aggiornamento del POM
Siamo finalmente pronti per configurare il nostro progetto attraverso l’aggiornamento del file POM di Maven collocato nella root del nostro progetto. In sintesi si tratta di è un file XML che contiene tutte le informazioni di configurazione del nostro progetto ed in particolare le sue dipendenze ed i dettagli per la compilazione e l’impacchettamento dello stesso. Apriamo quindi il pom.xml
ed aggiungiamo le due dipendenze necessarie nella sezione dependencies
:
1 2 3 4 5 6 7 8 9 10 11 |
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>7.0.70</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> |
Tornando al nostro POM inseriamo i plugin maven-compiler-plugin
e tomcat7-maven-plugin
, il primo per la compilazione del nostro codice, il secondo per il deploy a caldo su Tomcat 7. Inseriamo quindi nella sezione plugins
il seguente XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <inherited>true</inherited> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <url>http://localhost:8080/manager/text</url> <server>tomcat7</server> <path>/${project.build.finalName}</path> </configuration> </plugin> |
Si noti che il plugin tomcat7-maven-plugin
necessita di una ulteriore configurazione di Tomcat e Maven. Innanzitutto aprite il file tomcat-users.xml
nella directory conf
di Tomcat 7 e configurate un utente per eseguire script nella sua consolle come mostrato di seguito:
1 2 |
<role rolename="manager-script"/> <user password="admin" username="admin" roles="manager-script"/> |
Quindi aprite il file settings.xml di Maven, presente nella cartella .m2 (quella dove sono presenti tutte le dipendenze scaricate dal framework) e definite il vostro server di deploy Tomcat, inserendo le credenziali definite sopra. Notate che il server id tomcat7
è lo stesso definito nel plugin del POM
.
1 2 3 4 5 6 7 |
<servers> <server> <id>tomcat7</id> <username>admin</username> <password>admin</password> </server> </servers> |
Creazione della logica applicativa
Siamo finalmente pronti per implementare la logica applicativa del nostro progetto. Poiché non utilizziamo un database procediamo creando un model Employee
, una EmployeeList
che contiene la lista di tutti i dipendenti noti ed un servizio di ricerca EmployeeService
. Nel codice riportato sono tralasciati i dettagli implementativi che comunque possono essere ricavati dal progetto che può essere scaricato in fondo alla pagina.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Employee { private long id; private String name; private String lastName; private String birthDate; private String role; private String department; private String email; private static final AtomicLong counter = new AtomicLong(100); public Employee(String name, String lastName, String birthDate, String role, String department, String email) { this.name = name; this.lastName = lastName; this.birthDate = birthDate; this.role = role; this.department = department; this.email = email; this.id = counter.incrementAndGet(); } /* Getter and Setter */ } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class EmployeeList { private static final List employeeList = new ArrayList(); static{ employeeList.add(new Employee("John","Smith","12-12-1980","Manager","Sales","john.smith@abc.com")); employeeList.add(new Employee("Laura","Adams","02-11-1979","Manager","IT","laura.adams@abc.com")); employeeList.add(new Employee("Peter","Williams","22-10-1966","Coordinator","HR","peter.williams@abc.com")); employeeList.add(new Employee("Joana","Sanders","11-11-1976","Manager","Marketing","joana.sanders@abc.com")); employeeList.add(new Employee("John","Drake","18-08-1988","Coordinator","Finance","john.drake@abc.com")); employeeList.add(new Employee("Samuel","Williams","22-03-1985","Coordinator","Finance","samuel.williams@abc.com")); } public static List getInstance(){ return employeeList; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class EmployeeService { List<Employee> employeeList = EmployeeList.getInstance(); // Get all employees. public List<Employee> getAllEmployees() { return employeeList; } // Get all employees whose Name or Last Name match the searchParam, order by // name and last name. public List<Employee> searchEmployeesByName(String searchParam) { ... } // Get the employee by id public Employee getEmployee(long id) throws Exception { .... } } |
Implementazione della Servlet
Nel nostro semplice esempio il servizio (di ricerca) è esposto al front-end JSP attraverso l’utilizzo della seguente Servlet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
public class EmployeeServlet extends HttpServlet { EmployeeService employeeService = new EmployeeService(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action = req.getParameter("searchAction"); if (action != null) { switch (action) { case "searchById": searchEmployeeById(req, resp); break; case "searchByName": searchEmployeeByName(req, resp); break; } } else { List<Employee> result = employeeService.getAllEmployees(); forwardListEmployees(req, resp, result); } } private void searchEmployeeById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { long idEmployee = Integer.valueOf(req.getParameter("idEmployee")); Employee employee = null; try { employee = employeeService.getEmployee(idEmployee); } catch (Exception ex) { Logger.getLogger(EmployeeServlet.class.getName()).log(Level.SEVERE, null, ex); } req.setAttribute("employee", employee); req.setAttribute("action", "edit"); String nextJSP = "/jsp/new-employee.jsp"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP); dispatcher.forward(req, resp); } private void searchEmployeeByName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String employeeName = req.getParameter("employeeName"); List<Employee> result = employeeService.searchEmployeesByName(employeeName); forwardListEmployees(req, resp, result); } private void forwardListEmployees(HttpServletRequest req, HttpServletResponse resp, List<Employee> employeeList) throws ServletException, IOException { String nextJSP = "/jsp/list-employees.jsp"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP); req.setAttribute("employeeList", employeeList); dispatcher.forward(req, resp); } } |
Per poterla utilizzare dobbiamo configurarla nel descrittore della nostra applicazione. Apriamo quindi il web.xml
ed inseriamo il seguente xml:
1 2 3 4 5 6 7 8 9 |
<servlet> <servlet-name>EmployeeServlet</servlet-name> <servlet-class>it.inspired.employees.EmployeeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>EmployeeServlet</servlet-name> <url-pattern>/employee</url-pattern> </servlet-mapping> </servlet> |
Creazione dell’interfaccia utente
La maschera che abbiamo implementato per il nostro progetto è una semplice maschera di ricerca con un campo di testo per l’inserimento del nome del dipendente richiesto. Per fornire un po’ di “stile” alla nostra maschera andiamo finalmente ad inserire Bootstrap al nostro progetto. Andiamo quindi sul sito http://getbootstrap.com/ e scarichiamo la versione Compiled and minified
che è versione compatta del framework e quindi più leggera da scaricare una volta inclusa nelle nostre applicazioni.
Aprire lo zip scaricato e copiare le directory js
, css
e fonts
nella cartella webapp
del progetto. Se volete potete anche cancellare le versioni non minified dei file css
e js
.
Creiamo quindi il file list-employees.jsp
in una nuova cartella jsp
sotto la cartella webapp
. In particolare nella jsp dovranno essere inseriti i riferimenti ai file di Bootstrap attraverso i tag link
e script
nell’header
. Il file risultante sarà:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <link rel="stylesheet" href="css/bootstrap.min.css"/> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container"> <h2>Employees</h2> <!--Search Form --> <form action="employee" method="get" id="seachEmployeeForm" role="form"> <input type="hidden" id="searchAction" name="searchAction" value="searchByName"> <div class="form-group col-xs-5"> <input type="text" name="employeeName" id="employeeName" class="form-control" required="required" placeholder="Type the Name or Last Name of the employee"/> </div> <button type="submit" class="btn btn-info"> <span class="glyphicon glyphicon-search"></span> Search </button> <br></br> <br></br> </form> <!--Employees List--> <form action="/employee" method="post" id="employeeForm" role="form" > <c:choose> <c:when test="${not empty employeeList}"> <table class="table table-striped"> <thead> <tr> <td>#</td> <td>Name</td> <td>Last name</td> <td>Birth date</td> <td>Role</td> <td>Department</td> <td>E-mail</td> </tr> </thead> <c:forEach var="employee" items="${employeeList}"> <c:set var="classSucess" value=""/> <c:if test ="${idEmployee == employee.id}"> <c:set var="classSucess" value="info"/> </c:if> <tr class="${classSucess}"> <td>${employee.id}</td> <td>${employee.name}</td> <td>${employee.lastName}</td> <td>${employee.birthDate}</td> <td>${employee.role}</td> <td>${employee.department}</td> <td>${employee.email}</td> </tr> </c:forEach> </table> </c:when> <c:otherwise> <br> <div class="alert alert-info"> No people found matching your search criteria </div> </c:otherwise> </c:choose> </form> </div> </body> </html> |
index.jsp
generato da Maven, cancelliamone il contenuto ed inseriamo il seguente forward:
1 |
<jsp:forward page="/employee" /> |
Deploy dell’applicazione
per eseguire l’applicazione è necessario innanzitutto avviare tomcat. Potete farlo sia da riga di comando che inserendo il server su Eclipse. In quest’ultimo caso ricordate di selezionare l’opzione “Use Tomcat installation” nel panel “Server Locations” della maschera delle proprietà di tomcat, come mostrato in figura.
Eseguiamo quindi la compilazione ed il deploy dell’applicazione utilizzando Maven ed i due plugin configurati precedentemente. Anche in questo caso potete farlo da riga di comando o da Eclipse selezionando Run As->Maven build
ed eseguendo i goal:
1 |
clean compile tomcat7:redeploy |
Se tutto è andato correttamente aprendo il browser ed inserendo l’url http://localhost:8080/employees dovrebbe comparire la maschera di ricerca in figura. Provatela inserendo John
nel campo di testo e cliccando sul pulsante di ricerca
.
Download del progetto
Im progetto completo è scaricabile per intero al link Progetto Employees.
Molto interessante, grazie mille!
Prego 🙂