Servlets - Java EE6
- Einleitung - Teil 1
- Servlets - Teil 2
- JSP-Seiten - Teil 3
- JSP-Seiten mit JSTL - Teil 4
- JSF-Seiten - Teil 5
- JSF-Seiten mit Ajax - Teil 6
- JSF-Templates - Teil 7
20.01.2013
In diesem Artikel wird kurz beschrieben, wie ein Servlet aufgebaut ist und wie es verwendet werden kann. Dies wird an dem "bekannten" Beispiel eines Einkaufswagens (Shopping-Cart) erklärt. Dieser Artikel ist keine Einführung in die Servlet-Programmierung. Er soll vielmehr zeigen, wie fehleranfällig und umständlich das Erstellen von Servlets ist. In den folgenden Artikeln zum Thema Java EE6 Web-Client werden andere Technologien vorgestellt, um einfacher Web-Oberflächen und Web-Clients zu erstellen.
Die fertige Anwendung, die in diesem Artikel erstellt wird, sieht im Browser folgendermaßen aus:
Auf der linken Seite lassen sich in dem Textfeld Artikelbezeichnungen eintragen und über die ComboBox wird eine Menge von 1 bis 5 ausgewählt. Mit dem Button Hinzufügen wird der Artikel in den Warenkorb gelegt und in einer Liste oberhalb angezeigt. Mit dem Button Warenkorb leeren werden alle Artikel aus dem Warenkorb entfernt und die Liste wird nicht mehr angezeigt.
Die folgende Abbildung zeigt den Ablauf einer Anfrage an den Servlet-Container und die Antwort an den Client.
Man sieht, dass ein Request vom Browser, in dem der Web-Client läuft, an den Web-Container, in dem das Servlet läuft, gestellt wird. Als Antwort sendet das Servlet eine Response zurück an dem Browser. In der Response enthalten ist die komplette HTML-Seite, die der Browser anzeigt.
Der zugehörige Quellcode sieht folgendermaßen aus:
package org.hameister.shoppingcarts; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; 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.http.HttpSession; /** * * @author hameister */ @WebServlet(name = "CartServlet", urlPatterns = {"/CartServlet"}) public class CartServlet extends HttpServlet { /** * Processes requests for both HTTP * <code>GET</code> and * <code>POST</code> methods. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { //Get items in Cart for the Session HttpSession session = request.getSession(); List<String> items = (List<String>)session.getAttribute("items"); if(items == null) { items = new ArrayList<String>(); session.setAttribute("items", items); } // Reset Cart String reset = request.getParameter("reset"); if(reset!=null) { items.clear(); } out.println("<html>"); out.println("<head>"); out.println("<title>Warenkorb</title>"); out.println("</head>"); out.println("<body>"); String name = request.getParameter("item"); if(name != null) { String quantity = request.getParameter("quantity"); //Add item to list items.add(quantity+" × "+name); } // List output if(items.size()>0) { out.println("<h2>Artikel im Warenkorb:</h2>"); out.println("<ul>"); for(String item : items) { out.println("<li>"+item+"</li>"); } out.println("</ul>"); } out.println("<strong>Artikel zum Warenkorb hinzufügen:</strong>"); // Add button out.println("<form method=\"POST\" action=\"CartServlet\" >"); out.println("<input type=\"text\" name=\"item\" >"); out.println(" <select name=\"quantity\" size=\"1\">"); out.println(" <option selected>1</option>"); out.println(" <option>2</option>"); out.println(" <option>3</option>"); out.println(" <option>4</option>"); out.println(" <option>5</option>"); out.println(" </select>"); out.println("<input type=\"submit\" value=\"Hinzufügen\" >"); out.println("</form>"); // Reset button out.println("<form method=\"POST\" action=\"CartServlet\" >"); out.println("<input type=\"submit\" name=\"reset\" value=\"Warenkorb leeren\" >"); out.println("</form>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } /** * Handles the HTTP * <code>GET</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP * <code>POST</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Shopping Cart Servlet"; } }
Wie man sieht, erbt das Servlet (CartServlet
) von der Klasse HttpServlet
und überschreibt die drei Methoden doGet
, doPost
und getServletInfo
. Die Methode getServletInfo
liefert eine kurze Beschreibung des Servlets zurück. Wichtiger sind die beiden anderen Methoden, die die Anfragen an das Servlet verarbeiten. Also den Request. Da in dem Beispiel nicht zwischen HTTP-GET
und HTTP-POST
unterschieden wird, werden die Anfragen an die Methode processRequest
weitergeleitet. In dieser Methode wird aus dem Request-Objekt die HttpSession
abgefragt, um festzustellen, ob sich schon items
im Warenkorb befinden. Ggf. muss eine neue ArrayList
angelegt und in der Session abgelegt werden.
Falls der Reset-Button angeklickt wurde, wird der Warenkorb durch den Aufruf von clear
zurückgesetzt.
Anschliessend wird die HTML-Seite Element für Element erstellt. Dazu wird als erstes der HTML-Rahmen mit HEAD
und BODY
angelegt. Dann wird der hinzugefügte Artikel aus dem Request ausgelesen und inklusive der Menge in der items
-Liste ergänzt. Danach wird für alle schon im Warenkorb befindlichen Artikel ein <LI>
-Elemente angelegt, so dass sie in einer Liste angezeigt werden können.
Abschließend wird noch das Eingabeformular in der HTML-Seite ergänzt, so dass weitere Artikel erfasst werden können.
Das wirklich unschöne an Servlets ist, dass die HTML-Ergebnisseite, die zurück an den Browser geschickt wird, per Hand zusammengebaut werden muss. Man kann sich leicht vorstellen, dass dies extrem fehleranfällig ist. Deshalb sollte man im Java EE-Umfeld auch eher JSF-Seiten und falls notwendig JSP-Seiten verwendet werden.
Weitere Informationen zu Web-Clients findet man in den folgenden Artikeln: