Commit d1ff09c2 by Patryk Czarnik

Ostatnie przykłady serwletowe

parent 794888fd
package serwlety.beans;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/* Klasa jest "Java Bean" jeśli:
* 1) posiada publiczny konstruktor bezargumentowy (tzw. "default constructor")
* 2) dostęp do własności ("properties") udostępniony poprzez gettery i settery (nie ma obowiązku aby zawsze była para)
* ... wzorzec Java Bean opisuje też technikę powiadamiania o zdarzeniach (korzysta się z tego przede wszystkim w GUI), ale w większości przypadków wystarczają te dwie powyższe cechy
*/
// konstruktor domyślny jest tworzony automatycznie
public class ExampleBean {
private String napis = "Ala ma kota";
private int licznik = 0;
private final List<String> lista = new ArrayList<>(List.of("Warszawa", "Kraków", "Wrocław", "Gdańsk"));
public String getNapis() {
return napis;
}
public void setNapis(String napis) {
this.napis = napis;
}
public synchronized int getLicznik() {
return ++licznik;
}
public void setLicznik(int licznik) {
this.licznik = licznik;
}
// Metoda może wyglądać jak getter, ale zamiast po prostu zwracać wartość pola z obiektu,
// może pobrać dane z innego źródła: bieżący czas, dane z pliku, z bazy danych, obliczona na podstawie innych wartości.
// W skryptach JSP, Thymeleaf itp. można ten getter wywołać pisząc bean.currentTime
public LocalDateTime getCurrentTime() {
return LocalDateTime.now();
}
public List<String> getLista() {
return lista;
}
@Override
public String toString() {
return "ExampleBean z napisem " + napis + " i aktualną wartością licznika " + licznik;
}
}
package serwlety.kalkulator;
import java.io.IOException;
import java.util.List;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/kalkulator9")
public class Kalkulator9 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Tylko wyświetl formularz - po stronie Javy nie ma żadnej logiki do wykonania
// Przekierowanie obsługi zapytania do innego elementu aplikacji (do serwletu, skryptu jsp, zwykłej strony...)
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/kalkulator_view.jsp");
dispatcher.forward(request, response);
// sterowanie tu wraca - można coś jeszcze zrobić
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Obsługa wypełnionego formularza. Zanim przekażemy sterowanie do skryptu JSP, wcześniej wykonujemy działania "logiki".
String parametr1 = request.getParameter("liczba1");
String parametr2 = request.getParameter("liczba2");
String operacja = request.getParameter("operacja");
if (parametr1 != null && parametr2 != null && operacja != null) {
try {
long liczba1 = Long.parseLong(parametr1);
long liczba2 = Long.parseLong(parametr2);
long wynik = LogikaKalkulatora.oblicz(liczba1, liczba2, operacja);
// Jeśli serwlet chce przekazać jakieś dane do JSP,
// (patrząc bardziej ogólnie: z wcześniejszego etapu obsługi zapytania chcemy coś przekazać do następnego etapu)
// możemy użyć obiektu request, który pełni rolę schowka podobnego do servletContext i HttpSession.
request.setAttribute("wynik", wynik);
String tekst = String.format("%d %s %d = %d", liczba1, operacja, liczba2, wynik);
ServletContext servletContext = this.getServletContext();
List<String> historiaGlobalna = (List<String>) servletContext.getAttribute(ListenerHistorii.HISTORIA_GLOBALNA);
historiaGlobalna.add(tekst);
HttpSession sesja = request.getSession();
List<String> historiaKlienta = (List<String>) sesja.getAttribute(ListenerHistorii.HISTORIA_KLIENTA);
historiaKlienta.add(tekst);
} catch (NumberFormatException e) {
request.setAttribute("error", "Niepoprawny format liczby " + e.getMessage());
} catch (Exception e) {
request.setAttribute("error", String.valueOf(e));
}
}
// Prezekazujemy dalszą obsługę zapytania do innego "zasobu", np. do pliku JSP
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/kalkulator_view.jsp");
dispatcher.forward(request, response);
}
}
package serwlety.kalkulator;
public class KalkulatorBean {
private int arg1, arg2;
private String operacja;
public int getArg1() {
return arg1;
}
public void setArg1(int arg1) {
this.arg1 = arg1;
}
public int getArg2() {
return arg2;
}
public void setArg2(int arg2) {
this.arg2 = arg2;
}
public String getOperacja() {
return operacja;
}
public void setOperacja(String operacja) {
this.operacja = operacja;
}
public int getWynik() {
switch(operacja) {
case "+" : return arg1 + arg2;
case "-" : return arg1 - arg2;
case "*" : return arg1 * arg2;
case "/" : return arg1 / arg2;
default : return 0;
}
}
}
package serwlety.techniczne;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* Servlet implementation class Ello
*/
@WebServlet(asyncSupported = true, urlPatterns = { "/async" })
public class Asynchroniczny extends HttpServlet {
private static final long serialVersionUID = 1L;
public Asynchroniczny() {
System.out.println("Ello konstr");
}
@Override
public void init() {
System.out.println("Ello init");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
final AsyncContext asyncContext = request.startAsync();
System.out.println("Puszczone");
asyncContext.start(new Runnable() {
public void run() {
try {
PrintWriter out = asyncContext.getResponse().getWriter();
Thread.sleep(1000);
out.println("Jeden");
out.flush();
Thread.sleep(3000);
out.println("Dwa");
out.flush();
Thread.sleep(3000);
out.println("Trzy");
Thread.sleep(1000);
asyncContext.complete();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
package serwlety.techniczne;
import java.io.IOException;
import serwlety.beans.ExampleBean;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
@WebFilter("/zakresy_filtr.jsp")
public class FiltrZwiekszajacy implements Filter {
public void init(FilterConfig fConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("filtr - początek");
ExampleBean obiekt = new ExampleBean();
obiekt.setLicznik(100);
request.setAttribute("req", obiekt);
// pass the request along the filter chain
chain.doFilter(request, response);
// sterowanie wraca do filtru już po wysłaniu treści z jsp (w tym przypadku)
System.out.println("licznik = " + obiekt.getLicznik());
}
}
package serwlety.techniczne;
import serwlety.beans.ExampleBean;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.annotation.WebListener;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
@WebListener
public class Listener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
// wykonywane po uruchomieniu aplikacji na serwerze
public void contextInitialized(ServletContextEvent ev) {
System.out.println("start aplikacji");
// dodaję atrybut do kontekstu aplikacji (do "application scope")
ExampleBean obiekt = new ExampleBean();
obiekt.setLicznik(500);
obiekt.setNapis("servlet context");
ev.getServletContext().setAttribute("licznik-app", obiekt);
}
// wykonywane podczas "kontrolowanego" zamykania aplikacji
public void contextDestroyed(ServletContextEvent ev) {
System.out.println("koniec aplikacji");
}
// gdy jest tworzona nowa sesja
public void sessionCreated(HttpSessionEvent ev) {
System.out.println("utworzenie sesji " + ev.getSession().getId());
// timeout sesji w sekundach
// ev.getSession().setMaxInactiveInterval(60);
ExampleBean obiekt = new ExampleBean();
obiekt.setLicznik(600);
obiekt.setNapis("sesja");
ev.getSession().setAttribute("licznik-ses", obiekt);
}
public void sessionDestroyed(HttpSessionEvent ev) {
System.out.println("koniec sesji " + ev.getSession().getId());
}
public void requestInitialized(ServletRequestEvent ev) {
System.out.println("przyszedł request");
ExampleBean obiekt = new ExampleBean();
obiekt.setLicznik(700);
obiekt.setNapis("request");
ev.getServletRequest().setAttribute("licznik-req", obiekt);
}
public void requestDestroyed(ServletRequestEvent ev) {
System.out.println("obsługa requestu zakończona");
}
}
package serwlety.techniczne;
import java.io.IOException;
import java.io.PrintWriter;
import serwlety.beans.ExampleBean;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/zakresy")
public class Zakresy extends HttpServlet {
private static final long serialVersionUID = 1L;
// Standard nie gwarantuje nam żadnego zachowania jeśli chodzi o zmienne instancyjne w serwletach.
// Nie wiemy kiedy i ile obiektów klasy serwlet będzie tworzył serwer.
// W praktyce zazwyczaj tworzony jest jeden wspólny obiekt dla wszystkich zapytań, ale nie możemy tego zakładać.
private ExampleBean instancyjna = new ExampleBean();
// Zmienna statyczna będzie istniała do restartu serwera albo redeploy aplikacji.
private static ExampleBean statyczna = new ExampleBean();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ExampleBean lokalna = new ExampleBean();
HttpSession sesja = request.getSession();
ExampleBean req = (ExampleBean) request.getAttribute("licznik-req");
ExampleBean ses = (ExampleBean) sesja.getAttribute("licznik-ses");
ExampleBean app = (ExampleBean) getServletContext().getAttribute("licznik-app");
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("lokalna : " + lokalna.getLicznik());
out.println("instancyjna: " + instancyjna.getLicznik());
out.println("statyczna : " + statyczna.getLicznik());
out.println();
out.println("request : " + req.getLicznik());
out.println("sesja : " + ses.getLicznik());
out.println("aplikacja : " + app.getLicznik());
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dodawanie w JSP</title>
<link rel="stylesheet" type="text/css" href="styl.css">
</head>
<body>
<h1>Dodawanie w JSP</h1>
<form>
<input type="number" name="arg1" value="${param.arg1}">
+
<input type="number" name="arg2" value="${param.arg2}">
<button>=</button>
</form>
<div class="wynik">
Sumą jest: ${param.arg1 + param.arg2}
</div>
</body>
</html>
\ No newline at end of file
...@@ -36,5 +36,22 @@ ...@@ -36,5 +36,22 @@
<li><a href="kalkulator9">Kalkulator 9</a> - wersja z <code>forward</code> i widokiem JSP</li> <li><a href="kalkulator9">Kalkulator 9</a> - wersja z <code>forward</code> i widokiem JSP</li>
</ul> </ul>
<h3>Kalkulator w JSP</h3>
<ul>
<li><a href="dodaj.jsp">dodaj.jsp</a> - minimalna wersja w czystym JSP (tylko dodawanie)</li>
<li><a href="kalkulator_tylko_jsp.jsp">kalkulator</a> - zrobiony w czystym JSP</li>
<li><a href="kalkulator_bean.jsp">kalkulator bean</a> - wersja z pomocniczą klasą w Javie</li>
<li><a href="rozmowa.jsp">rozmowa.jsp</a></li>
</ul>
<h3>Sprawy techniczne</h3>
<ul>
<li><a href="ping">Ping</a> - serwlet prezentujący zawartość <code>Request</code>, nagłówki, ciasteczka itp.</li>
<li><a href="async">Async</a> - serwlet obługujący zapytania asynchronicznie</li>
<li><a href="zakresy">Zakresy</a> - zakresy zmiennych w serwlecie</li>
<li><a href="zakresy.jsp">zakresy.jsp</a> - zakresy zmiennych w JSP</li>
<li><a href="zakresy_filtr.jsp">zakresy.jsp</a> - zakresy zmiennych w JSP - wersja z filtrem</li>
</ul>
</body> </body>
</html> </html>
\ No newline at end of file
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Kalkulator w JSP</title>
<link rel="stylesheet" type="text/css" href="styl.css">
</head>
<body>
<h1>Kalkulator w JSP</h1>
<form class="kalkulator" method="post">
<input type="number" name="arg1" value="${param.arg1}">
<select name="operacja">
<c:forEach var="op" items="+,-,*,/">
<c:choose>
<c:when test="${op == param.operacja}">
<option value="${op}" selected="selected">${op}</option>
</c:when>
<c:otherwise>
<option value="${op}">${op}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
<input type="number" name="arg2" value="${param.arg2}">
<button style="color:red;font-weight:bold">Oblicz</button>
</form>
<jsp:useBean id="kalkulatorBean" class="serwlety.kalkulator.KalkulatorBean"/>
<jsp:setProperty name="kalkulatorBean" property="arg1" param="arg1"/>
<jsp:setProperty name="kalkulatorBean" property="arg2" param="arg2"/>
<jsp:setProperty name="kalkulatorBean" property="operacja" param="operacja"/>
<c:if test="${not empty param.operacja}">
<div class="wynik">
${kalkulatorBean.arg1} ${kalkulatorBean.operacja} ${kalkulatorBean.arg2} =
<strong>${kalkulatorBean.wynik}</strong>
</div>
</c:if>
</body>
</html>
\ No newline at end of file
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dodawanie w JSP</title>
<link rel="stylesheet" type="text/css" href="styl.css">
</head>
<body>
<h1>Dodawanie w JSP</h1>
<form class="kalkulator" method="post">
<input type="number" name="arg1" value="${param.arg1}">
<select name="operacja">
<c:forEach var="op" items="+,-,*,/">
<c:choose>
<c:when test="${op == param.operacja}">
<option value="${op}" selected="selected">${op}</option>
</c:when>
<c:otherwise>
<option value="${op}">${op}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
<input type="number" name="arg2" value="${param.arg2}">
<button style="color:red;font-weight:bold">Oblicz</button>
</form>
<c:if test="${not empty param.operacja}">
<div class="wynik">
${param.arg1} ${param.operacja} ${param.arg2} =
<strong><c:choose>
<c:when test="${param.operacja == '+'}">${param.arg1 + param.arg2}</c:when>
<c:when test="${param.operacja == '-'}">${param.arg1 - param.arg2}</c:when>
<c:when test="${param.operacja == '*'}">${param.arg1 * param.arg2}</c:when>
<c:when test="${param.operacja == '/'}">${param.arg1 / param.arg2}</c:when>
</c:choose></strong>
</div>
</c:if>
</body>
</html>
\ No newline at end of file
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Kalkulator w JSP</title>
<link rel="stylesheet" type="text/css" href="styl.css">
</head>
<body>
<h1>Kalkulator w JSP</h1>
<form class="kalkulator" method="post">
<input type="number" name="liczba1" value="${param.liczba1}">
<select name="operacja">
<c:forEach var="op" items="+,-,*,/">
<c:choose>
<c:when test="${op == param.operacja}">
<option value="${op}" selected="selected">${op}</option>
</c:when>
<c:otherwise>
<option value="${op}">${op}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
<input type="number" name="liczba2" value="${param.liczba2}">
<button style="color:red;font-weight:bold">Oblicz</button>
</form>
<%-- Obiekty zapisane w ServletContext, HttpSession i HttpRequest są dostępne "tak po prostu" poprzez ${expression language} --%>
<c:if test="${not empty wynik}">
<div class="wynik">
${param.liczba1} ${param.operacja} ${param.liczba2} = <strong>${wynik}</strong>
</div>
</c:if>
<h3>Historia globalna</h3>
<ul>
<%-- Nazwy historia_globalna i historia_klienta muszą być dokładnie takie, jak stałe zdef. w ListenerHistorii --%>
<c:forEach var="dzialanie" items="${historia_globalna}">
<li>${dzialanie}</li>
</c:forEach>
</ul>
<h3>Historia klienta</h3>
<ul>
<c:forEach var="dzialanie" items="${historia_klienta}">
<li>${dzialanie}</li>
</c:forEach>
</ul>
</body>
</html>
\ No newline at end of file
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="jakarta.tags.core" %> <%@taglib prefix="c" uri="jakarta.tags.core" %>
<html> <html>
<head> <head>
......
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Rozmowa JSP</title>
</head>
<body>
<h1>Rozmowa JSP</h1>
<form>
<label for="imie">Jak masz na imię?</label>
<input type="text" name="imie">
<button>Wyślij</button>
</form>
<p>Witaj ${param.imie}!</p>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Zakresy</title>
</head>
<body>
<h1>Zakresy zmiennych</h1>
<p>Wersja bez filtru.</p>
<p>Odświeżaj stronę i zobacz, które zmienne się zmieniają. Działanie seji można sprawdzić otwierając inną przeglądarkę lub profil prywatny.</p>
<jsp:useBean id="domyslnie" class="beans.ExampleBean"/>
<jsp:useBean id="strona" class="beans.ExampleBean" scope="page"/>
<jsp:useBean id="req" class="beans.ExampleBean" scope="request"/>
<jsp:useBean id="sesja" class="beans.ExampleBean" scope="session"/>
<jsp:useBean id="app" class="beans.ExampleBean" scope="application"/>
<h2>Domyślnie</h2>
<p>${domyslnie.licznik}</p>
<p>${domyslnie.licznik}</p>
<h2>Page</h2>
<p>${strona.licznik}</p>
<p>${strona.licznik}</p>
<h2>Request</h2>
<p>${req.licznik}</p>
<p>${req.licznik}</p>
<h2>Session</h2>
<p>${sesja.licznik}</p>
<p>${sesja.licznik}</p>
<h2>Application</h2>
<p>${app.licznik}</p>
<p>${app.licznik}</p>
</body>
</html>
\ No newline at end of file
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Zakresy</title>
</head>
<body>
<h1>Zakresy zmiennych</h1>
<p>Zawartość ta sama co <code>zakresy.jsp</code>, ale ten adres przechodzi przez filtr.</p>
<p>Odświeżaj stronę i zobacz, które zmienne się zmieniają. Działanie seji można sprawdzić otwierając inną przeglądarkę lub profil prywatny.</p>
<jsp:useBean id="domyslnie" class="beans.ExampleBean"/>
<jsp:useBean id="strona" class="beans.ExampleBean" scope="page"/>
<jsp:useBean id="req" class="beans.ExampleBean" scope="request"/>
<jsp:useBean id="sesja" class="beans.ExampleBean" scope="session"/>
<jsp:useBean id="app" class="beans.ExampleBean" scope="application"/>
<h2>Domyślnie</h2>
<p>${domyslnie.licznik}</p>
<p>${domyslnie.licznik}</p>
<h2>Page</h2>
<p>${strona.licznik}</p>
<p>${strona.licznik}</p>
<h2>Request</h2>
<p>${req.licznik}</p>
<p>${req.licznik}</p>
<h2>Session</h2>
<p>${sesja.licznik}</p>
<p>${sesja.licznik}</p>
<h2>Application</h2>
<p>${app.licznik}</p>
<p>${app.licznik}</p>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment