Architektura aplikacji

Opublikowano: 2018-07-15 12:28:16


article
Jak już wspominałem, architektura serwletów bardzo mnie zachwyciła, ponieważ od razu skumałem, o co w niej chodzi. Spełnia ona paradygmat Model-View-Controller, jest przejrzysta i zrozumiała, doskonale nadaje się do projektowania aplikacji webowych.

Przyjrzyjmy się jej bliżej. Załóżmy, że chcemy obsłużyć request /article/id (czyli taki, jak dla otwartej właśnie strony z postem). Tworzymy więc Kontroler (serwlet) o nazwie Article_Servlet.java z następującym kodem:


@WebServlet("/article/*")

public class Article_Servlet extends HttpServlet {
   
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
      Article_Dao article = null;
      Article_Model modelObject = new Article_Model();
      
      String path = request.getPathInfo();
      String id = path != null ? path.substring(1) : "0";
      
      try {
         article = modelObject.getArticle(Integer.parseInt(id));
      } 
      catch (SQLException e) {
         e.printStackTrace();
      }
      catch (NumberFormatException e) {
         e.printStackTrace();
      }
      
      request.setAttribute("article", article);
      RequestDispatcher dispatcher = request.getRequestDispatcher("/jsp/templates/article.jsp");
      dispatcher.forward(request, response);
   }
   
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      doGet(request, response);
   }
}

Mamy tu adnotację, dzięki której requesty o tej postaci są tu przekierowywane. Każdy serwlet ma dwie najważniejsze metody doGet() oraz doPost(). Jak się można domyślić, pierwsza służy do obsługi requestów typu GET, zaś druga - requestów typu POST. W naszym przypadku nie potrzebujemy mieć obsługi POST-ów (bo te pochodzą z formularzy), a jedynie obsługę GET-ów. I teraz popatrzmy, co się dzieje z naszym requestem. Trafia on do metody doGet(), a tu najpierw analizowany jest parametr URL-a (id), następnie wołana jest metoda getArticle() obiektu Modelu, która pobiera informacje z bazy danych i zwraca nam obiekt opisujący artykuł, a na koniec przekazujemy go do szablonu (czyli Widoku) wyświetlającego stronę z artykułem.

Tak więc w naturalny sposób w następnym kroku należy stworzyć Model o nazwie Article_Model.java z następującym kodem:


public class Article_Model {

   public Article_Dao getArticle(int index) throws SQLException {

      Connection conn = null;
      PreparedStatement st = null;
      ResultSet rs = null;

      Article_Dao article = new Article_Dao();

      try {
         String query = "SELECT * FROM pages WHERE id = ?";
         conn = db.Database_Connection.open();
         st = conn.prepareStatement(query);
         st.setInt(1, index);
         rs = st.executeQuery();
         if (rs.next()) {            
            article.setId(rs.getInt("id"));
            article.setIndex(rs.getString("index"));
            article.setTitle(rs.getString("title"));
            article.setImage(rs.getString("image"));
            article.setIntro(rs.getString("intro"));
            article.setContent(rs.getString("content"));
            article.setModified(rs.getTimestamp("modified"));
         }
      } 
      catch (SQLException e) {
         System.out.println(e.getMessage());
      } 
      finally {
         rs.close();
         st.close();
         conn.close();
      }
      
      return article;
   }
}   

Tu jest chyba wszystko jasne, nie trzeba niczego tłumaczyć. Ale dla przyzwoitości wspomnę tylko, że deklarujemy obiekt article mapowania relacyjnego klasy Article_Dao, następnie wykonujemy zapytanie do bazy danych, które w wyniku zwraca obiekt rs klasy ResultSet. Odczytujemy po kolei wszystkie pola tego obiektu i zapisujemy odpowiadające im pola obiektu mapowania relacyjnego, który na koniec zwracamy.

Teraz ten zwrócony obiekt wstawiamy (wstrzykujemy) do szablonu. Musimy więc teraz stworzyć nasz szablon (Widok) o nazwie article.jsp z następującym kodem:


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

<h1 class="page-title"><c:out value="${article.getTitle()}" /></h1>
<h4 class="page-date">Opublikowano: <c:out value="${fn:substringBefore(article.getModified(), '.')}" /></h4>
<hr class="page-separator">
<div class="page-content">
   <section class="article-image">
      <img src="<c:out value="${article.getImage()}" />" alt="article">
   </section>
   <section class="article-intro">
      <c:out value="${article.getIntro()}" escapeXml="false" />
   </section>
   <section class="article-content">
      <c:out value="${article.getContent()}" escapeXml="false" />
   </section>
</div>

I znowu chyba wszystko jasne, prawda? Wstawiliśmy do naszego szablonu obiekt article, z którego wydobywamy odpowiednie informacje (posługując się jego metodami: getTitle(), getModified(), getImage(), getIntro() oraz getContent()) i wyświetlamy w odpowiednich miejscach. Atrybut escapeXml="false" umożliwia renderowanie HTML-a.

Reasumując, sami widzicie, jakie to wszystko jasne, proste i przejrzyste. I dlatego właśnie architektura serwletów tak mnie ujęła i przekonała do siebie. Mam nadzieję, że Was również. :)