JavaEE JSP, Servlet

JavaEE JSP és Servlet-eket fogjuk megnézni.

A webcontent WEB-INF mappában található web xml fájl tartalmát nézzük most meg. Az előző leírásban létrehozott FirstTestProject web.xml tartalma:
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>FirstTestProject</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

Ebben a fájlban az látszik, hogy a kezdőoldal lehet index.html, htm vagy jsp, vagy lehet default.html htm vagy jsp. A fájl helye a webcontent mappa gyökerében van, persze átírhatjuk itt az elérési utat. Majdnem mint egy routing fájl, de mégse :) Ha csinálunk egy fájlt a webcontent mappában mondjuk index.html néven (new->other ( web mappa -> html File) ) és a tartalmát így módosítjuk:
 
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test web application</title>
</head>
    <body>
        Ez egy teszt oldal!
    </body>
</html>
és elindítjuk az tomcat-et, akkor máris látni fogjuk a kezdő oldalunkat. http://localhost:8080/FirstTestProject

Akkor készítsünk most servlet-et. A servlet HTTP kéréseket dolgoz fel(request) és HTTP kimenetet ad vissza (response). A src mappán jobb klikk new->servlet menüpontot válasszuk és tölsük ki így a következő ablakot:



A második fülön pl megváltoztathatjuk az elérési utat:



Az utolsó ablakon kiválaszthatjuk hogy milyen metódusokat generáljon le nekünk alapból:



A létrejött TestServlet.Java fájlunk tartalma így néz ki:
 
package org.test.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class TestServlet
 */
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

A böngészőben így tudjuk elérni: http://localhost:8080/FirstTestProject/TestServlet
A doGet metódus fog lefutni és ez fogja kiírni nekünk ezt: " Served at: /FirstTestProject " a böngészőben.
Megváltoztathatjuk az url-t is ha így módosítjuk a sorokat:
 
//@WebServlet("/TestServlet")
@WebServlet(description = "A test servlet", urlPatterns = { "/NewTestServlet" })

Ekkor már csak ezzel az új url-el érhetjük el: http://localhost:8080/FirstTestProject/NewTestServlet

Megtehetjük azt is, hogy nem írunk annotációt a servletbe, hanem a web.xml fájlba definiáljuk a servlet elérési útját
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>FirstTestProject</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
      <servlet-name>TestServlet</servlet-name>
      <servlet-class>org.test.servlet.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>TestServlet</servlet-name>
      <url-pattern>/NewTestServlet</url-pattern>
  </servlet-mapping>
</web-app>

A TestServlet doGet metódusát fogjuk most módosítani. A System.out.println -al a konzolra tudunk kiíratni. Ha a böngésző számára megjeleníthető html kimenetet szeretnénk, akkor pedig a response paraméter getWriter metódusát példányosítva tudunk a println-al kiírni a böngészőbe adatokat.
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //response.getWriter().append("Served at: ").append(request.getContextPath());
        
        //console output
        System.out.println("konzol teszt üzenet.");
        //html output
        PrintWriter writer = response.getWriter();
        writer.println("<h1>Teszt html üzenet</h1>");
    }

Próbáljunk adatokat "GET"-el lekérdezni a böngésző url-jéből. Módosítsuk tovább a doGet metódust. Beállíthatjuk a content type, de az url-ből is kinyerhetjük a paramétereket a request.getParameter metódusával:
 
		//set content type
		response.setContentType("text/html");
		
		// get userName
		String userName = request.getParameter("userName");
		writer.println("Felhasználó neve:  " + userName);

Ha a böngészőbe ezt írjuk: http://localhost:8080/FirstTestProject/NewTestServlet?userName=teszt
akkor válaszként ezt kell a böngészőnek adnia: " Felhasználó neve: teszt "

Próbáljunk adatokat "POST-"al lekérdezni, de ehhez csináljunk egy form.html nevű fájlt a webcontent mappába. Legyen a tartalma a következő:
 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post" action="NewTestServlet">
	Felhasználó neve: <input name="userName" />
	<br />
	Rádiógombok:
	<input type="radio" name="radioButton" value="1">1
	<input type="radio" name="radioButton" value="2">2
	<br />
	Városok
	<select name="city" multiple size="3">
		<option value="budapest">budapest</option>
		<option value="debrecen">debrecen</option>
		<option value="szeged">szeged</option>
		<option value="miskolc">miskolc</option>
	</select>
	<br />
	<input type="submit" />
</form>
</body>
</html>

Ezen az oldalon bekérjük a felhasználó nevét, választhatunk egy számot a két rádió gomb közzül, és egy select mezőből kiválaszthatunk egy vagy több várost. A gomb megnyomása után megkapjuk a doPost megtódusban az el post-olt/elküldött adatokat, amiket kiíratunk a képernyőre:
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//doGet(request, response);
		
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		String userName = request.getParameter("userName");
		out.println("Felhasználó neve: " + userName);
		
		// radio
		String radioButton = request.getParameter("radioButton");
		out.println("Rádiógomb száma: " + radioButton);
		
		//select single
		//String location = request.getParameter("location");
		//select multi
		String[] city = request.getParameterValues("city");
		out.println("Kiválasztva " + city.length + " Városok: ");
		for(int i=0;i<city.length;i++){
			out.println(city[i]);
		}		
	}

A metódus elején lekérdezzük a felhasználó nevét és kiíratjuk majd, rádiógomb számát kérdezzük le. Végül a select mező értékét/értékeit kapjuk meg. Benne hagytam példának azt ha csak 1 mezőt választhatunk ki egyszerre. A második esetben egy tömbbe kerülnek a kiválasztott mezők és sorban kiírjuk őket a képernyőre.
A böngészőbe http://localhost:8080/FirstTestProject/Form.html ezt írva bejön a form, rajta a mezők. A gombot megnyomva átkerülünk a http://localhost:8080/FirstTestProject/NewTestServlet oldalra és láthatjuk az általunk megadott adatokat.

Próbáljuk ki a session és context kezelést is. Térjünk vissza egy kicsit a doGet metódushoz. A végére írjuk az alábbi sorokat:
		// set session & context
		HttpSession session = request.getSession();
		ServletContext context = request.getServletContext();
		if(userName != "" && userName != null){
			session.setAttribute("savedUserName",userName);
			context.setAttribute("savedUserName",userName);
		}
		
		writer.println("request username: " + userName);
		writer.println("session username: " + (String) session.getAttribute("savedUserName"));
		writer.println("context username: " + (String) context.getAttribute("savedUserName"));
Előbb példányosítottunk egy egy session és context objektumot. Ezután ellenőriztük, hogy van-e tartalma a userName változónak. Ha van elmentünk egy session és egy context változóba is az adatot. Ezután kiíratjuk az értékét.

Az eclipse böngészőjében kipróbálhatjuk ezt az url-t: http://localhost:8080/FirstTestProject/NewTestServlet?userName=teszt
Ekkor a következőt fogja kiírni: Felhasználó neve: teszt request username: teszt session username: teszt context username: teszt
Ebben az esetben mind a 3 változónak van értéke, mert az url-ból kiolvastuk és elmentettük a session és context változóba is.

Ha ezután ezt az url-t írjuk be: http://localhost:8080/FirstTestProject/NewTestServlet
akkor ez látszódik: Felhasználó neve: null request username: null session username: teszt context username: teszt
Ebben az esetben már a sima userName mezőnek nincs értéke, de a session és a context értéke megmaradt.

Ezután pedig ha nyitunk egy másik böngészőt mondjuk egy firefox-ot és beírjuk az url-t http://localhost:8080/FirstTestProject/NewTestServlet
akkor ez fog látszódni: Felhasználó neve: null request username: null session username: null context username: teszt
A másik böngészőben már csak a context értéke maradt meg.

Most a jsp fájlokat fogjuk egy kicsit közelebbről megnézni. Végül is a megjelenítésért felelős, egyszerűsítsük így le a dolgot. A jsp fájlokban keveredhet a html és a java kód. Azt érdemes lehet tudni, hogy a jsp fájlok servlet fájlokká fordulnak le a háttérben. Készítsünk egy test.jsp fájl a webcontent mappába. Webcontent mappán jobb klikk->new->other->JSP file.



A fájl tartama legyen a következő:
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.util.Date"%>
<!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>Insert title here</title>
</head>
<body>
<h3>testing jsp</h3>

<%!
public int add (int a, int b){
	return a+b;
}
%>
<br />
-------------------------------------------------------
<br />

Adjunk össze számokat!<br /><br />

<% 

int i = 1;
int j = 2;
int k;

k = i + j;
out.println("i+j=k, k értéke: " + k);

%>
<br />
<% 

int i2 = 3;
int j2 = 4;
int k2;

k2 = i2 + j2;
%>
Rövid kiíratási forma: <%=k2 %>

<br />
Egyszerű összeadás 232+543=<%=232+543 %>
<br />
add metódus: <%=k=add(32423, 54645)%>
<br />
-------------------------------------------------------
<br />
<%@ include file="/Form.html" %>
<br />
-------------------------------------------------------
<br />
Az aktuális idő:<%=new Date() %>
</body>
</html>
Itt most egy kicsit sok minden történik, de nézzük sorban. A "konfigurációk" a jsp fájlokban <%@ %> tagok közzé kerülnek. A fájl elején lehet importálni más osztályokból. Mi most a java.util.date osztályt importáltuk be, mert majd kiíratjuk az aktuális időt.
Ha deklarálni szeretnénk valamilyen metódust függvényt stb akkor azok a <%! %> tagok közzé kerülnek. Mi egy add metódust írtunk ami összead két számot. Ezután minden java kód <% %> tagok közzé fog kerülni. Lehet használni egyszerűsített formában is kiírni adatokat pl: <%=k2 %> A fájl végén még be include-oljuk a Form.html-t de jsp fájl is lehetne. Végül kiíratjuk az aktuális időt.

https://hu.wikipedia.org/wiki/JavaServer_Pages
https://hu.wikipedia.org/wiki/Servlet
https://hu.wikipedia.org/wiki/Deployment_descriptor
A tutorial nagyrészt a következő videósorozat alapján készült:
https://www.youtube.com/watch?v=b42CJ0r-1to&list=PLB9B7412C6A8CBCF7
2015.08.10.