* Сървлети с Jetty
Публикувано на 03 март 2015 в раздел Уеб JSP.
Сървлетите са основната технология за динамични уеб страници в Java. Всъщност простите примери за JSP страници, които показахме досега, в крайната си фаза се компилират до сървлети. Нека направим нашия първи сървлет: В тази статия освен работа със сървлети ще покажем и работа със сесийни променливи и предаване на параметри чрез HTTP POST.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FirstServlet extends HttpServlet { public void doGet(HttpServletRequest reqest, HttpServletResponse response) throws ServletException, IOException{ response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\""); out.print("\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"); out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"bg\">"); out.println("<head><title>Моята първа сървлет страница</title></head><body>"); out.println("<p>Hello world!!!</p>"); out.println("</body></html>"); } }
Нашият първи сървлет е с име "FirstServlet". Виждате, че той наследява клас HttpServlet и предефинира метод "doGet". Този метод получава два параметъра - един HttpServletRequest (от него можем да четем параметри подадени от потребителя чрез заявка от тип HTTP GET) и един HttpServletResponse (изходен поток, с който можем да подаваме отговор към потребителя). Както виждате в нашия първи сървлет ние взимаме обект от тип PrintWriter за изходния поток и отпечатваме елементарна уеб страничка с него. Съществува и втори метод - doPost - който можем да предефинираме. С него можем да обработваме заявки подадени чрез HTTP POST. Работата с този метод е напълно аналогична.
За да изпълним този сървлет, първо трябва да го компилираме. Ще видите, че javax.servlet пакета не е наличен в стандартния JDK. Този пакет идва с уеб сървъра Jetty и трябва да го добавите в classpath на вашия проект. Намира се в <където сте инсталирали Jetty>\lib\servlet-api-3.1.jar. Ето пример как сме го добавили в средата DrJava:
След като компилирате ще получите съответния клас файл FirstServlet.class. Създайте директория C:\Jetty\mybase\webapps\ROOT\WEB-INF\classes (досега нашата база беше mybase - ще я използваме нея) и копирайте class файла там. Финално трябва да създадем файл C:\Jetty\mybase\webapps\ROOT\WEB-INF\web.xml със следното съдържание:
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>FirstServlet</servlet-name> <servlet-class>FirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FirstServlet</servlet-name> <url-pattern>/servlets/FirstServlet</url-pattern> </servlet-mapping> </web-app>
В тага <servlet> посочваме името на сървлета и съответстващия клас, който стои зад това име (в случая сме ги указали едни и същи). Важно е файлът, който сме качили в WEB-INF\classes директорията на приложението да отговаря на името посочето в <servlet-class> тага. В таг <servlet-mapping> се описва по какъв начин ще бъде достъпен дадения сървлет чрез URL.
Сега стартирайте Jetty и отидете на http://localhost:8080/servlets/FirstServlet и ще видите нашето първо сървлет приложение в действие:
Първоначално изглежда очевидно, че писането на сървлет страници е по-сложно, отколкото писането на JSP. В действителност това е така ако ние ще използваме сървлетите за презентационната част на проекта - много по-адекватно би било да използваме JSP ако ще отпечатваме големи обеми от HTML код. Ще забележите впоследствие, че за някои неща JSP не са чак толкова удобни - например когато трябва да се свържем с база от данни, да направим някаква обработка на данните и т.н. Тогава миксирането на java кода с html всъщност "ще пречи". Това е и случая, в който преместването на код в чист сървлет ще бъде по-удобно. Нека дадем един пример - елементарна login форма.
Файл C:\Jetty\mybase\webapps\ROOT\login.jsp:
<% String user = (String)session.getAttribute("Session-username"); if(user!=null){ response.sendRedirect("securearea.jsp"); return; } %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF8" %> <%@ page trimDirectiveWhitespaces ="true" %> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="bg"> <head> <title>Вход</title> </head> <body> <p>Login form</p> <form action="/servlets/CheckLogin" method="POST"> username: <input type="text" name="username" /><br /> password: <input type="password" name="password" /><br /> <input type="submit" name="submit" value="Login" /> </form> </body> </html>
В началото проверяваме дали потребителя вече не е влезнал в системата. Ако е влизал, ще има запис в сесийната променлива "Session-username" и съответно ще го пренасочим директно към securearea.jsp. Ако няма сесия, отпечатваме формата за вход, където човека трябва да въведе своите потребителско име и парола.
Файл C:\Jetty\mybase\webapps\ROOT\securearea.jsp:
<% String user = (String)session.getAttribute("Session-username"); if(user==null){ response.sendRedirect("login.jsp"); return; } %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF8" %> <%@ page trimDirectiveWhitespaces ="true" %> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="bg"> <head> <title>Вход</title> </head> <body> <p>Hello <%= user %></p> </body> </html>
Тук действаме по обратен принцип - ако потребителя НЯМА въведена променлива в сесията, ние ще го върнем към login.jsp. В противен случай той ще е влязъл успешно в системата и ние ще отпечатаме "секретната страница".
Сървлет компилиран и копиран в C:\Jetty\mybase\webapps\ROOT\WEB-INF\classes\CheckLogin.class:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CheckLogin extends HttpServlet { public static String USER_KEY = "Session-username"; public static String POST_USER = "username"; public static String POST_PASSWORD = "password"; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { // Проверяваме дали не сме вече автентикирани HttpSession session = request.getSession(true); String user = (String) session.getAttribute("Session-username"); if (user == null){ // Ако не сме, ще проверяваме какво има в POST String username = request.getParameter(POST_USER); String password = request.getParameter(POST_PASSWORD); // При невалидно име/парола отпечатваме съобщение за грешка if (!validUser(username, password)) { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\""); out.print("\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"); out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"bg\">"); out.println("<head><title>LOGIN FAIL</title></head><body>"); out.println("<p>Въвели сте нелавидно име и/или парола</p>"); out.println("<p>Върнете се обратно и опитайте пак!</p>"); out.println("</body></html>"); out.flush(); return; } // При валидно име и парола записваме името в сесията session.setAttribute(USER_KEY, username); } // Пренасочваме потребителя там, откъдето е дошъл response.sendRedirect("../securearea.jsp"); } protected boolean validUser(String username, String password) { // В тази функция може да се вържете с база данни и т.н... boolean valid = false; if (username.equals("Petar") && password.equals("123456")) return true; else return false; } }
В този сървлет ние първоначално проверяваме дали има въведена сесийната променлива. Ако я има, пренасочваме потребителя директно към securearea.jsp. Ако я няма, четем променливите предадени чрез HTTP POST и проверяваме дали те са валидни име и парола. Ако са валидни, записваме сесийната променлива и пренасочваме човека към securearea.jsp. Ако не са валидни, отпечатваме HTML страница със съобщение за грешка (по-удачно ще е да прехвърлим потребителя към JSP страница със съобщение за грешка - направете го!).
Настройки в C:\Jetty\mybase\webapps\ROOT\WEB-INF\web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>CheckLogin</servlet-name> <servlet-class>CheckLogin</servlet-class> </servlet> <servlet-mapping> <servlet-name>CheckLogin</servlet-name> <url-pattern>/servlets/CheckLogin</url-pattern> </servlet-mapping> </web-app>
Добави коментар