PA165/Cvičení webové aplikace 1 - Servlet API 3.0: Porovnání verzí

Z FI WIKI
Přejít na: navigace, hledání
(Komentáře)
(JSP - Java Server Page)
Řádka 136: Řádka 136:
 
   <title>JSP stránka</title>
 
   <title>JSP stránka</title>
 
   <style>
 
   <style>
   #nadpis { color: navy; }   
+
   #nadpis { color: red; }   
 
   table.zakladni { border-collapse: collapse; margin: 10px; }
 
   table.zakladni { border-collapse: collapse; margin: 10px; }
 
   table.zakladni th, table.zakladni td {  border: solid 1px black; padding: 4px; }
 
   table.zakladni th, table.zakladni td {  border: solid 1px black; padding: 4px; }
Řádka 171: Řádka 171:
 
* v JSP vždy existuje implicitní proměnná '''pageContext''' typu [http://docs.oracle.com/javaee/6/api/index.html?javax/servlet/jsp/PageContext.html PageContext]
 
* v JSP vždy existuje implicitní proměnná '''pageContext''' typu [http://docs.oracle.com/javaee/6/api/index.html?javax/servlet/jsp/PageContext.html PageContext]
 
* v JSP vždy existuje implicitní proměnná '''out''' typu [http://docs.oracle.com/javaee/6/api/index.html?javax/servlet/jsp/JspWriter.html JspWriter]
 
* v JSP vždy existuje implicitní proměnná '''out''' typu [http://docs.oracle.com/javaee/6/api/index.html?javax/servlet/jsp/JspWriter.html JspWriter]
* místo <%out.print(i);%> lze zkráceně psát <%=i%>
+
* místo '''<%out.print(i);%>''' lze zkráceně psát '''<%=i%>'''
 +
* přímé vypisování textů je nebezpečné, mohou obsahovat speciální znaky z HTML &lt;&gt;&amp; ale není standardní třída pro HTML-encoding pomocí entit &amp;lt; &amp;gt; &amp;amp;

Verze z 5. 11. 2012, 12:36


Prostředí

  • NetBeans 7.2
  • Oracle JDK 7
  • Tomcat 7
  • Maven 3
module add netbeans-7.2 jdk-1.7.0_03 maven-3.0.4

Vytvoření projektu

Vytvořte v NetBeans nový projekt pro webovou aplikaci typu Maven tj. File - New project - Categories:Maven - Project: Web Application, položku Package zvolte jako cz.muni.fi.pa165.web1.

Vytvořený projekt zkuste spustit (klávesa F6), měl by se otveřít prohlížeč a v něm stránka s nápisem Hello World!.


úvodní stránka

Zeditujte soubor index.jsp a vyměňte jeho obsah za následující HTML5:

 
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <title>Domov</title>
    </head>
    <body>
        <h1>Sláva, funguje to!</h1>
        <ul>
            <li><a href="${pageContext.request.contextPath}/text/primo?a=1&b=ccc">text přímo ze servletu</a></li>
            <li><a href="${pageContext.request.contextPath}/text/zjsp">text z JSP</a></li>
            <li><a href="${pageContext.request.contextPath}/soubor">soubor</a></li>
            <li><a href="${pageContext.request.contextPath}/presmerovani">přesměrování</a></li>
            <li><a href="${pageContext.request.contextPath}/text/ble">chyba</a></li>
        </ul>
    </body>
</html>

Výraz ${pageContext.request.contextPath} vkládá před relativní odkazy prefix servletové aplikace.

Servlet

V package cz.muni.fi.pa165.web1 vytvořte novou třídu servletu kliknutím pravým tlačítkem na balík, vyberte New - Java class a pojmenujte ji MyDemoServlet.

Přepište zdrojový kód třídy na:

 
package cz.muni.fi.pa165.web1;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
 
@WebServlet(urlPatterns = {"/text/*", "/soubor/*", "/presmerovani/*"})
public class MyDemoServlet extends HttpServlet {
 
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if ("/text".equals(request.getServletPath()) && "/primo".equals(request.getPathInfo())) {
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.println("<pre>text přímo ze servletu");
            out.println("serverInfo=" + getServletContext().getServerInfo());
            out.println("parametry:");
            for (String p : Collections.list(request.getParameterNames())) {
                out.println(p + "=" + request.getParameter(p));
            }
            return;
        } else if ("/text".equals(request.getServletPath()) && "/zjsp".equals(request.getPathInfo())) {
            request.setAttribute("seznam", Arrays.asList("mléko", "rohlíky", "salám"));
            request.getRequestDispatcher("/stranka.jsp").forward(request, response);
            return;
        } else if ("/soubor".equals(request.getServletPath())) {
            response.setContentType("application/zip");
            response.setHeader("Content-disposition", "attachment; filename=\"neco.zip\"");
            ServletOutputStream sos = response.getOutputStream();
            ZipOutputStream zos = new ZipOutputStream(sos);
            zos.putNextEntry(new ZipEntry("neco.txt"));
            zos.write("nějaký text".getBytes());
            zos.putNextEntry(new ZipEntry("necojineho.txt"));
            zos.write("jiný text".getBytes());
            zos.close();
            return;
        } else if ("/presmerovani".equals(request.getServletPath())) {
            String url = request.getContextPath() + "/text/primo?z=" + URLEncoder.encode("?/ =", "utf-8");
            response.sendRedirect(response.encodeRedirectURL(url));
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "Nerozpoznane URL");
            return;
        }
    }
}

Opět spusťte aplikaci a proklikejte si odkazy.

Komentáře

Povšimněte si ve výše uvedeném kódu servletu následujících věcí:

  • třída servletu je mapována na URL pomocí anotace @WebServlet
  • mapované URL se skládá ze tří částí - contextPath, servletPath a pathInfo
  • metoda request.getParameterNames() vrací z historických důvodů java.util.Enumeration, na Iterable ji zkonvertujeme pomocí Collections.list()
  • všechny parametry requestu jsou typu String
  • při přeposlání (forward) na jiný servlet/JSP se data předávají pomocí metody setAttribute()
  • při zasílání binárního obsahu můžeme pomocí HTTP hlavičky Content-disposition určit, zda se má přímo zobrazit (hodnota inline) nebo uložit (hodnota attachment)
  • při přesměrování (redirect) je nutné před URL přidat contextPath, URL prohnat metodou encodeRedirectURL() a hodnoty případných parametrů musí být URL-encoded
  • místo obsahu a přesměrování můžeme poslat prohlížeči chybové hlášení metodou sendError()

JSP - Java Server Page

V předchozí ukázce nefungoval odkaz /text/zjsp, protože zatím neexistovala JSP stránka, na kterou se předávalo řízení.

Nyní vytvořte v adresáři src/main/webapp soubor stranka.jsp a zeditujte mu obsah na následující:

 
<%@page import="java.util.List"%>
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
  <title>JSP stránka</title>
  <style>
   #nadpis { color: red; }   
   table.zakladni { border-collapse: collapse; margin: 10px; }
   table.zakladni th, table.zakladni td {  border: solid 1px black; padding: 4px; }
  </style>
  <script>
      console.log("ahoj");
  </script>
</head>
<body>
  <h1 id="nadpis">JSP stránka</h1>
  <p>seznam</p>
  <table class="zakladni">
      <% List<String> seznam = (List<String>) pageContext.findAttribute("seznam");
      for(int i=0,n=seznam.size();i<n;i++) { %>          
      <tr>
          <td><%=i%></td>
          <td><%=seznam.get(i)%></td>
      </tr>
      <% } %>
  </table>
</body>
</html>

Spusťte znovu aplikaci z vyzkoušejte stránku. Ve Firefoxu po zmáčknutí Ctrl+Shift+K nebo v Chrome po zmáčknutí F12 můžete vidět JavaScriptovou konzolu z výpisem skriptu.

Komentáře

  • na začátku JSP stránky je důležité definovat kódování výstupu parametrem charset, jinak se použije iso-8859-1
  • pomocí CSS selektoru #nadpis nastavujeme vzhled právě jednoho prvku s atributem id="nadpis"
  • pomocí CSS selektoru .zakladni nastavujeme vzhled všech prvků s atributem class="zakladni"
  • v JavaScriptu můžeme psát trasovací výpisy pomocí console.log()
  • příkazy v jazyce Java se vkládají mezi <% %>
  • v JSP vždy existuje implicitní proměnná pageContext typu PageContext
  • v JSP vždy existuje implicitní proměnná out typu JspWriter
  • místo <%out.print(i);%> lze zkráceně psát <%=i%>
  • přímé vypisování textů je nebezpečné, mohou obsahovat speciální znaky z HTML <>& ale není standardní třída pro HTML-encoding pomocí entit &lt; &gt; &amp;