Java 11: Budowa aplikacji serwerowej do testowania HTTP/2
Budowa aplikacji serwerowej do testowania HTTP/2
Wstępny opis
Nasza aplikacja ma strukturę przedstawiona na Rys. 140:
Na razie jest to klasyczna aplikacja składająca się z 2 stron JSP i serwletu.
Na stronie getfibo.jsp znajduje się formularz, w którym klient wpisuje, który wyraz ciągu Fibonacciego należy obliczyć.
Dane z formularza przekazywane są na serwer do serwletu. Serwlet weryfikuje dane i oblicza podany wyraz ciągu. Wynik obliczenia jest wpisywany na stronie wynikfibo.jsp i wysyłany do przeglądarki klienta.
Strony JSP są wyłącznie dla celów testowych. Przeglądarka jest niezbędna do pracy ze stronami JSP.
Naszym końcowym zadaniem będzie budowa aplikacji Java, która zastąpi przeglądarkę i strony JSP, łącząc się z serwerem przy użyciu protokołu HTTP/2.
Do budowy aplikacji i wstępnych testów użyłam Netbeans 8.2 działających na JDK 8u191 i sprzężonych z Tomcatem 8.0.27. Wygenerowany plik fiboservlet.war zostanie umieszczony na serwerze Tomcat 9.0.12 działającym na OpenJDK-11 – również jako serwer lokalny. Jest to niezbędne ze względu na to, że protokół HTTP/2 jest obsługiwany (w tym module i pakiecie) dopiero od Java 11.
Aplikacja końcowa zostanie napisana w IntelliJ IDEA v. Community z wykorzystaniem OpenJDK-11.
Pliki
context.xml
<?xml version="1.0" encoding="UTF-8"?> <Context path="/fiboservlet"/>
Plik fibo.css
#content2 { font-family: Arial, Helvetica, sans-serif; width: 400px; margin: 10px auto; padding: 5px 20px; background: #FFFFFF; border: 1px solid #000000; } .center { text-align: center; } fieldset { margin-top: 1em; margin-bottom: 1em; } legend { color: black; font-weight: bold; font-size: 85%; } .formLayout { padding-top: 1em; } .formLayout label { float: left; width: 10em; text-align: right; } .formLayout input, .formLayout select { margin-left: 0.5em; margin-bottom: 0.5em; } .formLayout select { width: 11em; } .formLayout br { clear: both; } .error { color: red; } .notice { color: red; font-size: 67%; text-align: right; }
Plik web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <servlet-name>FiboServlet</servlet-name> <servlet-class>fibo.FiboServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FiboServlet</servlet-name> <url-pattern>/fibo</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <session-config> <session-timeout>10</session-timeout> </session-config> </web-app>
getfibo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="styles/fibo.css"> <title>Podaj numer wyrazu ciągu Fibonacciego</title> </head> <body> <div id="page1"> <div id="content2"> <p class="notice">Podaj numer ≤ 100 000</p> <form action="fibo" method="get" name="fibo_form" id="fibo_form"> <fieldset> <legend>Numer wyrazu ciągu Fibonacciego</legend> <div class="formLayout"> <label for="fibon">Numer:</label> <input type="text" name="fibon" id="fibon" value="${fibon}" size="20" maxlength="60"> <font size="2" color="#FF0000">${wiadFibo}</font><br> </div> </fieldset> <fieldset> <legend>Podaj wynik</legend> <div class="formLayout"> <label> </label> <input type="submit" id="register" value="Oblicz"> </div> </fieldset> </form> </div> </div> </body> </html>
wynikfibo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="styles/fibo.css"> <title>Twoje wyniki</title> </head> <body> <div> <p><%=session.getAttribute("fibon")%> wyraz ciągu Fibonacciego</p> <p><%=session.getAttribute("fibofull")%></p> </div> </body> </html>
FiboServlet.java
package fibo; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class FiboServlet extends HttpServlet { protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); HttpSession session; RequestDispatcher dispatcher; String url; String fi = request.getParameter("fibon"); String wiadFibo = VerifyFibo.isFibo(fi); if (wiadFibo.length() > 0) { url = "/getfibo.jsp"; session = request.getSession(); session.setAttribute("wiadFibo", wiadFibo); dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); session.invalidate(); } else { session = request.getSession(); session.setAttribute("fibon", fi); session.setAttribute("fibofull", FiboUtil.fibonacci(Long.parseLong(fi))); url = "/wynikfibo.jsp"; dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doProcess(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doProcess(request, response); } }
FiboUtil.java
package fibo; import java.math.BigInteger; public class FiboUtil { private FiboUtil() { } public static String fibonacci(long n) { BigInteger[] tabl = {BigInteger.ONE, BigInteger.ONE, BigInteger.ONE, BigInteger.ZERO}; BigInteger[] tablKonc = {BigInteger.ONE, BigInteger.ONE, BigInteger.ONE, BigInteger.ZERO}; if (n == 0) { return BigInteger.ZERO.toString(); } if (n == 1) { return BigInteger.ONE.toString(); } for (long i = 0; i < n; i++) { tablKonc = multi(tablKonc, tabl); } return tablKonc[3].toString(); } /** * z domeny publicznej 'Wikipedii' */ private static BigInteger[] multi(BigInteger[] a, BigInteger[] b) { BigInteger[] t = new BigInteger[4]; t[0] = (a[0].multiply(b[0])).add(a[1].multiply(b[2])); t[1] = (a[0].multiply(b[1])).add(a[1].multiply(b[3])); t[2] = (a[2].multiply(b[0])).add(a[3].multiply(b[2])); t[3] = (a[2].multiply(b[1])).add(a[3].multiply(b[3])); return t; } }
VerifyFibo.java
package fibo; public class VerifyFibo { public static final String GIVE_NUMBER = " Podaj numer. "; public static final String IMPR_NUMBER = " Nieprawidłowy numer. "; private VerifyFibo() { } public static String isFibo(String fibo) { if (fibo == null || fibo.length() == 0) { return GIVE_NUMBER; } if (Long.parseLong(fibo) < 0 || Long.parseLong(fibo) > 100000L) { return IMPR_NUMBER; } return ""; } }
Testowanie aplikacji
Gdy w Netbeans klikniemy dwukrotnie plik getfibo.jsp i z rozwijanego menu wybierzemy
Run File zostanie uruchomiony serwer Tomcat, a ustawiona przeglądarka wyświetli
formularz (Rys. 141)
Po wpisaniu liczby np. 30 i kliknięciu przycisku Oblicz wpisana liczba zostanie
przekazana do serwera, serwlet wykona obliczenie, a w przeglądarce, na stronie wynikfibo.jsp pokaże się wynik (Rys 142).
Jeśli ciągle mamy uruchomiony serwer Tomcat możemy zignorować stronę JSP i używając dowolnej przeglądarki połączyć się bezpośrednio z aplikacja na serwerze. W pasek adresu wpisujemy (Rys. 143)
Otrzymamy dokładnie taki sam wynik.
Plik fiboservlet.war
Gdy w oknie aplikacji w Netbeans klikniemy Run/Click and Build Project (fiboservlet) i zmienimy zakładkę Projects na Files w folderze dist zobaczymy plik fiboservlet.war (Rys. 144).
Użyjemy tego pliku w następnym etapie.
Servlet w akcji możesz obejrzeć i wypróbować tutaj: „http://javer.org/fiboservlet/” – jednak pamiętaj, że mój serwer jest przez większość czasu wyłączony, ze względu na koszty energii elektrycznej :-).
Zajrzyj też Java 11: HTTP Client (Standard)
Kompletną aplikację Apache Netbeans 15 dla Apache 10.0.23 znajdziesz tutaj.
Aplikację umieściłem na własnym serwerze, czynnym okresowo ze względu na koszty energii elektrycznej: fiboserlet