* Сървлети с 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>
Добави коментар