Úvod do webových aplikací

Z FI WIKI
Přejít na: navigace, hledání


Webové aplikace jsou probírány podrobně v předmětu PA165, pro který existují podrobně zpracované materiály pod heslem Kategorie:Webové aplikace.

V předmětu PV168 není prostor probrat webové aplikace dostatečně podrobně. Podobně jako se v semináři probírá JDBC, a ORM nástroje jsou nechány do předmětu PA165, probereme zde jen pevné základy, které se v čase nemění, a různé nadstavby a frameworky, jejichž obliba se mění z roku na rok, ponecháme do PA165.

Tato stránka obsahuje stručnou teorii a tři praktické ukázky, a měla by vystačit na jeden dvouhodinový seminář.

Úvod

Webové aplikace jsou aplikace, kde uživatelským rozhraním je webový prohlížeč. Mají tři obrovské výhody oproti ostatním typům aplikací (desktopové, mobilní, příkazový řádek):

  • uživatel nemusí nic instalovat
  • vývojář se stará jen o jednu verzi aplikace
  • u správně napsaných aplikací existují adresy URL do částí aplikace, např. lze někomu jinému poslat odkaz na stránku s popisem určitého zboží

Sepišme si, co máme k dispozici na straně klienta:

  • ve 100 % případů máme HTML s hyperlinky a formuláři
  • v asi 95 % případů máme JavaScript, a můžeme s ním manipulovat HTML formuláře
  • většinou máme k dispozici Cookies pro ukládání stavu v prohlížeči
  • obvykle máme DOM (Document Object Model) a CSS (Cascading Style Sheets), které lze manipulovat JavaScriptem
  • většinou máme Flash plugin (animovaná vektorová grafika a multimédia, viz YouTube) (98% verze 9)
  • obvykle máme možnost použít Java applety, ale jen na úrovni pokaženého JDK 1.1
  • někdy lze použít Java Web Start pro nastartování desktopové aplikace

Pragmaticky má smysl používat to nejrozšířenější, tj. HTML s CSS a JavaScriptem, zajímavou možností se stává i Flash (s vývojovým nástrojem Flex).

Při tvorbě aplikací pro širokou veřejnost je dobré vystačit si s čistým HTML, kvůli nevidomým uživatelům, zobrazení na mobilech, případně možnosti tisku stránek.

Poslední dobou je trendem tzv. AJAX, jde o tvorbu aplikací běžících v prohlížeči v JavaScriptu. Chovají se podobně jako desktopové aplikace s GUI. Mají jistě své místo, ale je třeba zvážit jejich použití a mít na paměti, že jdou proti principu WWW, jímž je adresovatelnost zdrojů pomocí URL.

Webové aplikace na platformě Java

Platforma Java je pro tvorbu serverové části webových aplikací poměrně vhodná, oproti např. PHP umožňuje psát snadněji udržovatelné aplikace, dobře škáluje, má skvěle zvládnutou internacionalizaci.

Cenou je o něco náročnější učení.

Základem serverové části webových aplikací na platformě Java jsou tzv. Servlety, což jsou třídy obsluhující požadavky HTTP protokolu. Ty tvoří nejnižší vrstvu, nad kterou pak existují další nadstavby. Dalšími vrstvami jsou

  • Java Server Pages (JSP) - obdoba PHP a dalších server-side scripting nástrojů
  • Web Application Frameworks - rámce pro tvorbu složitějsích aplikací
    • rámce pro šablony stránek (Freemarker, WebMacro, Velocity, JSP+JSTL)
    • rámce pro řízení průchodu aplikací (Stripes, Struts)
    • rámce pro tvorbu stránek z komponent (Tapestry, WebWork, JSF)

Rozhraní servletů se časem téměř nemění, naopak webové aplikační rámce podléhají rychlému vývoji i módě.

Managed environment

U servletů se poprvé setkáváme s pojmem managed environment. Servlety nejsou spustitelné aplikace, jak jsme byli dosud zvyklí, ale "žijí" uvnitř určitého prostředí, zvaného servlet container. Podobně například aplikace do mobilních telefonů, tzv. midlety, žijí uvnitř prostředí poskytovaného mobilním telefonem.

Servlet container vytváří instance servletů, při příchodu HTTP požadavků zpracuje příchozí data a volá metody servletů, vygenerovanou odpověd zasílá prohlížeči, a při ukončení aplikace servlety ruší.

Je definováno rozhraní mezi servlet containerem a webovou aplikací tvořenou servlety, tzv. Servlet API, které má různé verze, v současnosti se používají verze 2.4 a 2.5.

Existují různé implementace servlet containerů, např. Apache Tomcat, Jetty, JRun. Dále pak každý server odpovídající specifikaci Java Enterprise Edition musí obsahovat servlet container, např. BEA WebLogic, Oracle Application Server, IBM WebSphere a další.

Díky jednotnému API je možné psát aplikace nezávislé na konkrétním servlet containeru, a tutéž aplikaci používat v servlet containerech různých výrobců.

(Stejně tak je možné psát mobilní aplikace použitelné v každém mobilu podporujícím Midlet API.)

Servlet API

Servletem je každá Java třída, která implementuje interface javax.servlet.Servlet. Protože ale z praktického hlediska má smysl uvažovat pouze servlety obsluhující protokol HTTP, je důležitější vědět, že HTTP servletem je každá třída, která je potomkem třídy javax.servlet.http.HttpServlet.

Obsluha HTTP požadavků servlety je popsána v JavaServlets#Obsluha HTTP pomocí servletů, nemá smysl ji sem opisovat, prosím přečtete si ji tam.

Servlety jsou organizovány do tzv. aplikací, kdy skupina servletů je sdružena v jednom balíčku s příponou .war, což je soubor typu .jar (tedy ZIP archiv). V něm musí být přítomen soubor WEB-INF/web.xml, který popisuje konfiguraci aplikace, zejména mapování URL na servlety.

Podrobnosti viz část JavaServlets#Webová aplikace a kontext servletu, prosím přečtěte si ji.

Důležitá věc, kterou Servlet API poskytuje, je session. Jedná se vlastně o HashMap, do které je možné si ukládat hodnoty mezi jednotlivými požadavky od stejného prohlížeče. Session je udržována pomocí cookies, nebo v případě vypnutých cookies je její identifikátor přidáván do všech generovaných URL.

Praktická ukázka

Teď je asi vhodný čas zkusit si vytvořit servlet.

V NetBeans vytvořte nový projekt typu Web Application (File - New project - Categories: Web - Projects: Web Application). Server zvolte Tomcat 6, Java EE Version zvolte JavaEE 5.

V projektu vytvořte nový servlet zvaný UkazkovyServlet. Pravým tlačítkem klikněte na Source packages, dejte New - Other - Categories: Web - File Types: Servlet, Class Name dejte UkazkovyServlet a package dejte cz.muni.fi.pv168. Je nutné zvolit nějaký package, jinak nebude servlet spustitelný !!! Ponechte nabídnuté nastavení mapování servletu a potvrdte vytvoření servletu.

Naeditujte text do následující podoby:

 
package cz.muni.fi.pv168;
 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class UkazkovyServlet extends HttpServlet {
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
 
        try {
            int n = 10;
            String np = request.getParameter("n");
            if(np!=null) n = Integer.parseInt(np);
        
            for(int i=0;i<n;i++) {
                out.println("i="+i+"<br/>");
            }
        } finally {
            out.close();
        }
    } 
    
}

Pozor, NetBeans se snaží skrýt metody doGet() a doPost() do sbaleného bloku, nenechte se tím zmást.

Spusťte aplikaci. Servlet zavoláte na URL http://localhost:8084/WebApplication1/UkazkovyServlet.

Můžete přidat parametr n pomocí http://localhost:8084/WebApplication1/UkazkovyServlet?n=6.

JSP

Psát delší sekvence HTML v servletech je poměrně nepohodlné, proto každý servlet container poskytuje tzv. Java Server Pages - JSP.

Jedná se o psaní servletů naruby - každý soubor s příponou .jsp je před spuštěním konvertován na servlet, který je za běhu překompilován a spuštěn.

Do JSP lze psát přímo Java kód, tzv. scriptlety:

  • běžný kód je možné psát mezi znaky <% a %>, je umístěn do metody service() servletu
  • tisk výrazu lze napsat pomocí <%= a %>, je to ekvivalentní <%out.print(vyraz)%>
  • kód mimo metodu service() lze napsat pomocí <%! a %>.

Podrobná dokumentace viz JSP 1.2 syntax card.

Nejlépe je to vidět na ukázce.

Praktická ukázka

Vymažte ve vytvořeném projektu obsah souboru index.jsp, a nahradte ho následujícím:

 
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
 
<%! //kód mimo metodu service()
   public String prictiJedna(String a) {
       return Integer.toString(Integer.parseInt(a)+1);
   }
%>
<html>
<body>
  <%  //kód uvnitř metody service()
      if(request.getMethod().equals("GET")) {
  %>
  <form method="post">
      Zadejte číslo: <input name="cislo" value="">
      <input type="submit" >
  </form>
  <%
      } else if (request.getMethod().equals("POST")) {
          String cislo = request.getParameter("cislo");
          String plusjedna = prictiJedna(cislo);
   %>
      Výsledek <%out.println(cislo);%> + 1 je <%=plusjedna%> 
  <%
      }
  %>
</body>
</html>

a spusťte aplikaci.

JSTL a knihovny značek

Psaní scriptletů je nedoporučovaný způsob, protože takto vytvořené programy mají stejnou nectnost jako PHP programy - špatně se udržují.

Lepší je rozdělit aplikaci na část zpracovávající data, a část zobrazující data, tzv. MVC architektura. JSP se pak používají pouze pro zobrazení dat, a místo scriptletů se používá knihovna JSTL (JSP Standard Tag Library).

Podrobnosti viz Java Server Pages#Použití JSP.

Praktická ukázka

Přidejte do projektu knihovnu JSTL 1.1. Klikněte pravým tlačítkem na Librarries - Add Library - JSTL 1.1.

Vytvořte v projektu nový servlet, např. UkazkaJSTL.

Upravte ho na následující obsah:

 
package cz.muni.fi.pv168;
 
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class UkazkaJSTL extends HttpServlet {
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
 
        Map<String, Object> m = new TreeMap<String, Object>();
        
        for(Locale l :Locale.getAvailableLocales()) {
            Map<String, Object> v = new HashMap<String, Object>();
            v.put("name", l.getDisplayName());
            v.put("origname", l.getDisplayName(l));
            v.put("loc", l);
 
            m.put(l.toString(), v);
        }
        request.setAttribute("jazyky", m);
        
        request.getRequestDispatcher("/stranka.jsp").forward(request, response);
    } 
 
}

Vytvořte nový soubor stranka.jsp. Klikněte pravým tlačítkem na Web Pages - New - JSP, pozor jméno zadejte bez přípony .jsp !

 
<%@page contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
    <body>
 
    <table border="1">
    <c:forEach items="${jazyky}" var="j">
        <tr>
            <td><c:out value="${j.key}"/></td>
            <td><c:out value="${j.value.name}"/></td>
            <td><c:out value="${j.value.origname}"/></td>
            <td><c:out value="${j.value.loc.ISO3Language}"/></td>
            
        </tr>    
    </c:forEach>
    </table>
 
    </body>
</html>

Spusťte aplikaci a zavolejte tento nový servlet na URL http://localhost:8084/WebApplication1/UkazkaJSTL

V této ukázce servlet negeneruje žádný výstup, jen připraví data, uloží je do requestu a předá řízení na JSP stránku. JSP stránka si vyzvedne data z requestu, a pomocí značek z JSTL provede cyklus nad všemi položkami předané mapy (jsou typu java.util.Map.Entry). Jazyk EL s tečkovou notací je použit pro zpřístupnění vnořených objektů, tj. např.

${j.value.loc.ISO3Language}

je ve skutečnosti provedeno jako

 
 pageContext.findAttribute("j").getValue().get("loc").getISO3Language()

V rámci výuky jsou dostupné pro vyzkoušení i další aplikační servery Aplikacni servery