JSP - JavaServer Pages
Java ekosistemində web application hazırlamaqdan danışarkən, JSP (JavaServer Pages) adı qaçınılmazdır. JSP, dinamik veb səhifələri yaratmaq üçün HTML, XML və ya digər markup dillərinin içərisinə Java kodunu yerləşdirməyə imkan verən bir server-side texnologiyadır. Əsas məqsədi presentation layer-i business logic-dən ayırmağa kömək etməkdir, baxmayaraq ki, bu ayrılığın nə qədər effektiv olması sizin JSP-dən necə istifadə etdiyinizdən çox asılıdır.
Servletlərlə müqayisədə, JSP daha çox frontend developer-lər və ya dizaynerlər üçün rahat bir mühit təmin edir, çünki əsasən HTML-ə bənzəyir və dinamik hissələr xüsusi tags və ya minimal Java kodu ilə əlavə edilir. Amma arxa planda baş verənləri anlamaq hər bir ciddi Java web developer üçün vacibdir.
JSP-nin Arxasında Nə Baş Verir: The Lifecycle
Bir JSP səhifəsi ilk dəfə request alanda və ya web application başladığında (konfiqurasiyadan asılı olaraq) bir lifecycle-dan keçir. Bu prosesi başa düşmək, JSP-nin necə işlədiyini və potensial problemləri anlamaq üçün kritikdir:
- Translation Phase: JSP container (məsələn, Tomcat, Jetty içərisindəki Jasper)
.jsp
faylını oxuyur və onu ekvivalent bir Java Servlet source code faylına (.java
) çevirir. Bu mərhələdə bütün JSP elementləri (scriptletlər, expressionlar, directive-lər, action-lar) uyğun Java koduna transformasiya olunur. Statik HTML/markup isəout.println()
kimi statements-ə çevrilir. - Compilation Phase: JSP container yaradılmış
.java
faylını standart Java compiler (javac
) vasitəsilə Java bytecode (.class
) faylına kompayl edir. Hər hansı bir sintaksis xətası bu mərhələdə ortaya çıxacaq. - Loading Phase: Kompayl edilmiş
.class
faylı JVM-ə (Java Virtual Machine) yüklənir. - Instantiation Phase: Yüklənmiş class-dan bir instance (obyekt) yaradılır. Hər bir JSP səhifəsi üçün adətən yalnız bir instance yaradılır (lakin fərqli konfiqurasiyalar mümkündür).
- Initialization Phase: Container, Servlet specification-da olduğu kimi,
jspInit()
metodunu çağırır. Bu metod yalnız bir dəfə, instance yaradıldıqdan dərhal sonra çağırılır və database connection-ları açmaq və ya digər one-time setup işləri üçün istifadə edilə bilər. Bunu override etmək üçün JSP declaration elementindən istifadə edə bilərsiniz. - Request Processing Phase: Hər bir client request-i üçün container yeni bir thread yaradır və həmin thread üzərindən
_jspService()
metodunu çağırır. Sizin JSP faylındakı bütün scriptlet kodu, expression-lar və HTML bu metodun içərisinə yerləşdirilir. Bu metodrequest
vəresponse
obyektlərini parametr olaraq qəbul edir.- ⚠️ Vacib:
_jspService()
metodu multithreaded mühitdə işlədiyi üçün instance variables (declaration ilə yaradılanlar) istifadə edərkən thread safety məsələlərinə diqqət yetirmək lazımdır. Local variables (scriptlet içində yaradılanlar) isə hər request üçün ayrı olduğundan thread-safe-dir.
- ⚠️ Vacib:
- Destruction Phase: Web application dayandırıldıqda və ya JSP container shutdown edildikdə, container
jspDestroy()
metodunu çağırır. Bu metod da yalnız bir dəfə çağırılır vəjspInit()
də açılmış resources-ları (məsələn, database connection-ları) bağlamaq üçün istifadə edilə bilər.
➡️ Əsas Çıxarış: Hər bir JSP faylı, əslində, arxa planda işləyən bir Servlet-dir! Bu faktı anlamaq, JSP-nin davranışını və Servlet konteksti ilə əlaqəsini dərk etmək üçün fundamentaldır.
JSP Sintaksisi:
Bir JSP səhifəsi statik markup (HTML, XML) və dinamik JSP elementlərinin qarışığından ibarətdir. JSP container bu elementləri emal edərək nəticəni client-ə göndərir.
Scripting Elements (The "Old" Way - Ehtiyatla İstifadə Edin!)
Bu elementlər JSP səhifələrinə birbaşa Java kodu yerləşdirməyə imkan verir. Modern JSP təcrübələrində (EL və JSTL ilə) bunlardan mümkün qədər qaçınmaq tövsiyə olunur, çünki presentation ilə logic-i qarışdırır və kodu oxunmaz hala gətirir. Ancaq onları tanımaq vacibdir:
-
Declarations (
<%! ... %>
):- Generated Servlet class-ının səviyyəsində variables (member variables) və methods elan etmək üçün istifadə olunur.
- Burada elan edilən variables bütün requests-lər arasında paylaşılır və thread-safe deyil! Çox diqqətli olmaq lazımdır.
- Metodlar (məsələn, helper methods və ya
jspInit
/jspDestroy
u override etmək) elan etmək üçün daha çox istifadə olunur.
example/Declarations.jsp -
Scriptlets (
<% ... %>
):- Generated Servlet-in
_jspService()
metodu içərisinə yerləşdiriləcək Java kod bloklarıdır. - İstənilən qədər Java kodu (variable elanları, loops, conditionals, method calls) burada yazıla bilər.
- Burada elan edilən local variables hər request üçün yenidən yaradılır və thread-safedir.
- ⚠️ Əsas Problem: HTML markup ilə Java kodunun qarışması (Spaghetti code), oxunaqlılığı və maintainability-ni kəskin şəkildə azaldır. Bundan qaçının!
example/Scriptlet.jsp - Generated Servlet-in
-
Expressions (
<%= ... %>
):- Bir Java expression-ının dəyərini hesablayır, onu String-ə çevirir və birbaşa response output stream-inə (
out.print(...)
kimi) yazır. - Kod blokunun sonunda nöqtəli vergül (
;
) qoyulmur. - Scriptlet-lərdə
out.println()
istifadə etməkdən daha qısa və oxunaqlıdır.
example/Expressions.jsp - Bir Java expression-ının dəyərini hesablayır, onu String-ə çevirir və birbaşa response output stream-inə (
Directives (<%@ ... %>
)
Directive-lər JSP container-a translation phase-də səhifənin necə emal ediləcəyi barədə təlimatlar verir. Onlar runtime-da birbaşa çıxış yaratmırlar.
-
page
Directive: Ən çox istifadə olunan directive-dir və səhifə səviyyəsində müxtəlif atributları təyin edir. Bir səhifədə çoxlupage
directive-i ola bilər, amma bəzi atributlar (məsələn,language
) yalnız bir dəfə təyin edilə bilər. Əsas atributlar:import="package.Class, package.*, ..."
: Java class-larını import etmək üçün. Birdən çox import vergüllə ayrılır.java.lang.*
,javax.servlet.*
,javax.servlet.http.*
,javax.servlet.jsp.*
paketləri avtomatik import edilir.contentType="mimeType; charset=encoding"
: Göndərilən response-un MIME type-ını və character encoding-ni təyin edir (məsələn,"text/html; charset=UTF-8"
). Düzgün encoding (UTF-8) Azərbaycan hərfləri üçün vacibdir.session="true|false"
: Bu səhifənin HTTP session-larında iştirak edib-etməyəcəyini müəyyən edir. Default dəyəritrue
dur. Əgər session-a ehtiyac yoxdursa,false
təyin etmək performansı artıra bilər.false
olduqda, implicit objectsession
mövcud olmur.errorPage="relativeURL"
: Səhifədə tutulmamış (uncaught) bir exception baş verdikdə, request-in yönləndiriləcəyi səhifəni göstərir.isErrorPage="true|false"
: Bu səhifənin başqa bir səhifədən yönləndirilən xətaları qəbul edən bir error page olub olmadığını göstərir. Defaultfalse
dur.true
olarsa, implicit objectexception
mövcud olur.buffer="none|sizekb"
: Output stream (out
obyekti) üçün buferləmə ölçüsünü təyin edir. Default adətən8kb
olur.none
buferləməni ləğv edir (performansa mənfi təsir edə bilər).autoFlush="true|false"
: Bufer dolduqda avtomatik olaraq client-ə göndərilib-göndərilməyəcəyini təyin edir. Defaulttrue
dur.false
və bufer dolarsa, exception baş verəcək.language="java"
: İstifadə olunan scripting language-i təyin edir. Hal-hazırda yalnız"java"
dəstəklənir və default-dur.
directives/page-directive.jsp -
include
Directive: Başqa bir faylın məzmununu (text, HTML, JSP kodu) cari JSP səhifəsinə translation phasedə statik olaraq daxil edir. Daxil edilən faylın məzmunu sanki əsas faylın bir hissəsiymiş kimi emal olunur. Fayl yolu relative olmalıdır.- Fərq:
<jsp:include>
action-ından fərqli olaraq, bu directive faylı yalnız bir dəfə, kompaylasiyadan əvvəl daxil edir. Əgər daxil edilən fayl dəyişərsə, əsas JSP faylının yenidən kompayl olunması lazımdır. - Əsasən headers, footers kimi statik və ya təkrar istifadə olunan kod parçaları üçün
.jspf
(JSP Fragment) faylları ilə birlikdə istifadə olunur.
directives/include-directive.jsp - Fərq:
-
taglib
Directive: Custom tag libraries (o cümlədən JSTL) istifadə etmək üçün kitabxananı səhifəyə daxil edir.prefix
atributu teqləri istifadə edərkən hansı namespace-dən istifadə ediləcəyini,uri
isə Tag Library Descriptor (TLD) faylının yerini və ya known URI-ni göstərir.directives/taglib-directives.jsp (JSTL və custom tags haqqında daha sonra ətraflı danışacağıq.)
JSP Implicit Objects
JSP container hər bir JSP səhifəsi üçün (daha doğrusu, onun _jspService
metodu üçün) avtomatik olaraq bir sıra obyektləri əlçatan edir. Bu obyektlər scriptlet və expression-lar daxilində birbaşa istifadə edilə bilər.
request
(javax.servlet.http.HttpServletRequest
): Cari HTTP request-i təmsil edir. Parameters, headers, cookies, attributes, session kimi məlumatları əldə etmək üçün istifadə olunur.response
(javax.servlet.http.HttpServletResponse
): Cari HTTP response-u təmsil edir. Headers təyin etmək, cookies əlavə etmək, redirect etmək üçün istifadə olunur. Birbaşa output stream-ə yazmaq üçünresponse.getWriter()
istifadə edilsə də, adətənout
obyekti daha rahatdır.out
(javax.servlet.jsp.JspWriter
): Response body-sinə məzmun yazmaq üçün istifadə olunan buferlənmiş writer obyekti.println()
,print()
,newLine()
kimi metodları var.session
(javax.servlet.http.HttpSession
): Cari client üçün session obyektini təmsil edir. İstifadəçi məlumatlarını requests-lər arasında saxlamaq üçün (setAttribute
,getAttribute
). Yalnız<%@ page session="true" %>
(default) olduqda mövcuddur.application
(javax.servlet.ServletContext
): Bütün web application üçün context-i təmsil edir. Bütün istifadəçilər və requests-lər arasında paylaşılan məlumatları (application scope attributes), initialization parameters-ı saxlamaq və resource-lara çatmaq üçün istifadə olunur.config
(javax.servlet.ServletConfig
): Cari JSP səhifəsi (generated Servlet) üçün configuration məlumatlarını saxlayır (məsələn,web.xml
də təyin edilmiş init parameters).pageContext
(javax.servlet.jsp.PageContext
): Bütün digər implicit objects-ə və müxtəlif scopes-lara (page, request, session, application) proqramatik çıxış təmin edən mərkəzi obyektdir. Həmçinin attribute idarəçiliyi, request forwarding və including üçün metodlar saxlayır. Custom tag handlers içərisində çox istifadə olunur.page
(java.lang.Object
): Cari JSP səhifəsinin instance-ını təmsil edir (this
referansı). Nadir hallarda birbaşa istifadə olunur.exception
(java.lang.Throwable
): Yalnız error page-lərində (<%@ page isErrorPage="true" %>
) mövcuddur və orijinal səhifədə baş vermiş exception-ı saxlayır.
JSP Standard Actions (<jsp:...>
)
Standard Actions scripting elements-ə XML-əsaslı alternativlər təqdim edir. Onlar daha oxunaqlıdır, presentation logic-i daha yaxşı ayırır və container tərəfindən idarə olunur.
-
<jsp:useBean>
: JavaBeans komponentlərini idarə etmək üçün istifadə olunur. Ya mövcud bir bean-i müəyyən bir scope-da tapır, ya da yenisini yaradır.id
: Bean-ə JSP səhifəsi daxilində müraciət etmək üçün istifadə olunacaq variable adı.class
: Bean-in tam qualified class name-i (əgər yeni instance yaradılmalıdırsa).scope
: Bean-in saxlanılacağı və axtarılacağı scope. Dəyərlər:page
(default),request
,session
,application
. Container əvvəlcə göstərilən scope-daid
ilə bean-i axtarır, tapmazsa yenisini yaradır (class
atributu varsa) və həmin scope-a yerləşdirir.
actions/useBean.jsp -
<jsp:setProperty>
:<jsp:useBean>
ilə tapılmış və ya yaradılmış bean-in property-lərini təyin etmək üçün istifadə olunur.name
: Hədəf bean-in<jsp:useBean>
dəkiid
si.property
: Təyin ediləcək property-nin adı. Bean-də uyğun setter metodu (məsələn,setPropertyName()
) olmalıdır.property="*"
: Xüsusi dəyərdir. Request parameters-ın adları ilə bean property-lərinin adlarını uyğunlaşdıraraq avtomatik olaraq bütün uyğun property-ləri təyin etməyə çalışır (type conversion avtomatik edilir). Çox güclü, lakin ehtiyatla istifadə edilməlidir.value
: Property-yə təyin ediləcək sabit dəyər (String, expression ola bilər).param
: Property-nin dəyərini hansı request parameter-dən götürəcəyini göstərir. Əgərparam
vəvalue
göstərilməzsə,property
adı ilə eyni adda olan request parameter-dən dəyər götürülür.
actions/setProperty.jsp -
<jsp:getProperty>
: Bean-in property-sinin dəyərini əldə edib output-a yazır (getter metodunu çağırır). Nadir hallarda istifadə olunur, çünki EL (Expression Language) daha rahatdır.name
: Bean-inid
si.property
: Əldə ediləcək property-nin adı.
actions/getProperty.jsp -
<jsp:include>
: Başqa bir resource-u (JSP, Servlet, HTML) cari səhifəyə request timeda dinamik olaraq daxil edir. Daxil edilən resource ayrıca emal olunur və onun nəticəsi əsas səhifənin nəticəsinə əlavə edilir.page
: Daxil ediləcək resource-un relative URL-i. Runtime expression ola bilər.flush="true|false"
: Daxil etməzdən əvvəl əsas səhifənin buferini flush edib-etməyəcəyini göstərir. Defaultfalse
dur, ancaqtrue
olması bəzi container-larda daha stabil işləyə bilər.- Fərq:
<%@ include ... %>
directive-dən fərqli olaraq, bu action hər request zamanı işləyir və daxil edilən resource-un ən son versiyasını əlavə edir. Bu, daha çox dinamizm təmin edir. - Parametrlər
<jsp:param>
ilə ötürülə bilər.
actions/include.jsp -
<jsp:forward>
: Cari request-i başqa bir resource-a (JSP, Servlet, HTML) yönləndirir. Yönləndirmə tamamilə server-sideda baş verir, client browser-in xəbəri olmur (URL dəyişmir). Cari səhifənin output buffer-i təmizlənir və icra forward edildiyi yerdə dayanır.page
: Yönləndiriləcək resource-un relative URL-i. Runtime expression ola bilər.- Parametrlər
<jsp:param>
ilə əlavə edilə bilər (orijinal request parameters-a əlavə olunur). - Əsasən MVC (Model-View-Controller) arxitekturasında Controller-dən (Servlet) View-a (JSP) yönləndirmək üçün istifadə olunur.
actions/forward.jsp
<jsp:param>
<jsp:include>
və <jsp:forward>
actions-ları daxilində istifadə olunaraq daxil edilən və ya yönləndirilən resource-a request parameters əlavə etməyə imkan verir.
name
: Parametrin adı.value
: Parametrin dəyəri.
Expression Language (EL): JSP-ni Sadələşdirmək
Scriptlet-lərin yaratdığı qarışıqlıqdan qaçmaq üçün JSP 2.0 ilə birlikdə Expression Language (EL) təqdim edildi. EL, JSP səhifələrindən JavaBeans properties-inə, collections-a, implicit objects-ə və request parameters-a asan və oxunaqlı şəkildə çatmaq üçün nəzərdə tutulmuşdur. Sintaksisi ${expression}
şəklindədir. EL, müasir JSP inkişafının əsasını təşkil edir.
-
Əsas Sintaksis:
${...}
-
JavaBeans Property Access:
${beanName.propertyName}
(Arxa plandagetBeanName().getPropertyName()
çağırır). -
Collection/Array Access:
${myList[0]}
,${myMap.keyName}
,${myMap['key-with-hyphen']}
. -
Implicit Objects (EL için xüsusi):
pageScope
,requestScope
,sessionScope
,applicationScope
: Müvafiq scope-dakı attributes-ə birbaşa çatmaq üçün (məsələn,${requestScope.user}
). Əgər scope göstərilməzsə (məsələn,${user}
), EL avtomatik olaraq page, request, session, application scopes-larını bu ardıcıllıqla axtarır.param
: Request parameters-ə çatmaq üçün (məsələn,${param.userId}
).request.getParameter()
ə ekvivalentdir.paramValues
: Eyni adda olan çoxsaylı request parameters-i String massivi olaraq əldə etmək üçün (məsələn,${paramValues.interests[0]}
).request.getParameterValues()
a ekvivalentdir.header
: HTTP request headers-ə çatmaq üçün (məsələn,${header['User-Agent']}
).headerValues
: Eyni adda olan çoxsaylı headers-i String massivi olaraq əldə etmək üçün.cookie
: Cookies-ə çatmaq üçün (məsələn,${cookie.userPref.value}
). Adı verilən cookie-nin obyektini qaytarır.initParam
: Web application-ın deployment descriptor-ında (web.xml
) təyin edilmiş context initialization parameters-ə çatmaq üçün (məsələn,${initParam.adminEmail}
).servletContext.getInitParameter()
ə ekvivalentdir.pageContext
:PageContext
obyektinin özünə çıxış verir (məsələn,${pageContext.request.contextPath}
ilə context path-i əldə etmək).
-
Operators:
- Arithmetic:
+
, , ,/
(və yadiv
),%
(və yamod
). - Logical:
&&
(və yaand
),||
(və yaor
),!
(və yanot
). - Relational:
==
(və yaeq
),!=
(və yane
),<
(və yalt
),>
(və yagt
),<=
(və yale
),>=
(və yage
). empty
: Bir dəyərinnull
, boşString
, boşcollection
və ya boşmap
olub olmadığını yoxlayır (məsələn,${empty param.search}
).- Conditional:
A ? B : C
(məsələn,${user.isAdmin ? 'Admin' : 'User'}
).
- Arithmetic:
-
Nümunələr:
views/el-examples.jsp -
EL-i Ignor Etmək: Nadir hallarda lazım olsa da,
<%@ page isELIgnored="true" %>
directive-i ilə səhifədə EL emalını söndürmək olar.
Servlet və JSP İnteqrasiyası: MVC Rəqsi (Ətraflı İzah)
Daha əvvəl də qeyd etdiyimiz kimi, JSP Servlet-ə çevrilir. Ancaq real dünya tətbiqlərində onlar adətən birlikdə, Model-View-Controller (MVC) arxitekturası çərçivəsində işləyirlər:
- Model: Tətbiqin məlumatlarını və business logic-i saxlayan obyektlər (JavaBeans, POJOs, Entities).
- View: Məlumatları istifadəçiyə təqdim edən komponent (Adətən JSP + EL + JSTL). View mümkün qədər az logic saxlamalıdır.
- Controller: Gələn requests-ləri qəbul edən, istifadəçi girişini emal edən, Model-i yeniləyən və nəticəni göstərmək üçün uyğun View-u seçib ona yönləndirən komponent (Adətən Servlet).
Ən Yayılmış Model: Servlet Controller kimi, JSP View kimi
Bu, standart və ən çox tövsiyə edilən yanaşmadır:
-
Request Gəlir: Client bir URL-ə request göndərir (məsələn,
/users?action=list
). -
Controller (Servlet) Emal Edir: Deployment Descriptor (
web.xml
) və ya@WebServlet
annotation-ı bu URL pattern-ini müvafiq Servlet-ə yönləndirir.- Servlet request-i qəbul edir (
doGet
,doPost
metodları). - Request parameters-i oxuyur (
request.getParameter("action")
). - Lazımi business logic-i çağırır (məsələn,
UserService
dən istifadəçilərin siyahısını alır). - Əldə edilmiş məlumatları (Model) request scopeuna attribute olaraq yerləşdirir:
request.setAttribute("userList", listOfUsers);
.
- Servlet request-i qəbul edir (
-
Controller View-a Yönləndirir (Forward): Servlet
RequestDispatcher
dən istifadə edərək request-i məlumatları göstərəcək olan JSP səhifəsinə forward edir:controller/UsersServlet.java -
View (JSP) Məlumatı Göstərir: JSP səhifəsi request scope-dakı məlumatları EL və JSTL istifadə edərək göstərir:
WEB-INF/jsp/userList.jsp
➡️ /WEB-INF/ Altında JSP-lər: Diqqət edin ki, JSP faylı (/WEB-INF/jsp/userList.jsp
) /WEB-INF
qovluğunun altında yerləşdirilib. Bu, təhlükəsizlik üçün vacib bir praktikadır. /WEB-INF
altındakı resources-lara client browser-dən birbaşa URL ilə çatmaq mümkün deyil. Yalnız server-side yönləndirmə (forward
) ilə çatıla bilər. Bu, istifadəçilərin Controller-i bypass edərək birbaşa View-a çatmağının qarşısını alır və MVC axınını qoruyur.
Daha Az Yayılmış Model: JSP İçərisində Servlet Daxil Etmək
<jsp:include page="/path/to/servlet" />
action-ı ilə bir JSP səhifəsi başqa bir Servlet-in output-unu öz məzmununa daxil edə bilər.
- Əsas JSP: Səhifənin əsas hissəsini render edir.
<jsp:include>
: Müəyyən bir nöqtədə<jsp:include page="/dynamicFragmentServlet" />
çağırılır.- Daxil Edilən Servlet: Request-i alır (əsas JSP-nin
request
vəresponse
obyektləri ilə), öz məntiqini icra edir və nəticəni özresponse.getWriter()
ına yazır. - Nəticə Birləşir: Daxil edilən Servlet-in output-u əsas JSP-nin həmin nöqtədəki output-una əlavə olunur.
İstifadə Sahələri: Bu yanaşma daha az yayılmışdır. Əsasən, səhifənin müəyyən dinamik hissələrini (məsələn, fərdi reklam bloku, dinamik naviqasiya menyusu) ayrı Servlet-lər tərəfindən idarə etmək və onları müxtəlif JSP-lərə daxil etmək üçün istifadə edilə bilər. Ancaq adətən Controller-in bütün məlumatları hazırlayıb tək bir JSP-yə ötürməsi daha təmiz bir həll hesab olunur. Bəzən JSP Fragments (.jspf
) və custom tags daha yaxşı alternativlərdir.
Forward vs Redirect (Servlet-dən JSP-yə)
forward
(RequestDispatcher.forward()
):- Tamamilə server-sideda baş verir.
- Browser URL-i dəyişmir.
- Orijinal
request
obyekti (və onun attributes-i) yeni resource-a ötürülür. - Daha sürətlidir (əlavə network roundtrip yoxdur).
- Adətən Controller-dən View-a məlumat ötürmək üçün istifadə olunur.
redirect
(response.sendRedirect()
):- Server, browser-a
302
status kodu və yeni URL göndərir. - Browser yeni URL-ə tamamilə yeni bir request göndərir.
- Orijinal
request
obyektləri və attributes-i itirilir. Məlumat ötürmək üçün session scope və ya URL parameters istifadə edilməlidir (daha az effektiv). - URL browser-da dəyişir.
- Post-Redirect-Get (PRG) Pattern: Əsas istifadə yeri, bir POST request-indən (məsələn, forma submission-ı) sonra browser refresh-i ilə eyni POST request-inin təkrar göndərilməsinin qarşısını almaqdır. Controller POST-u emal etdikdən sonra GET request-i ilə nəticə səhifəsinə redirect edir.
- Server, browser-a
Advanced Topics və Best Practices
Error Handling
<%@ page errorPage="error.jsp" %>
və<%@ page isErrorPage="true" %>
directives-lərindən istifadə edərək səhifə səviyyəsində xəta idarəçiliyi.exception
obyektini error page-də istifadə etmək.web.xml
də<error-page>
elementləri ilə HTTP status codes (404, 500) və ya exception types üçün global error pages təyin etmək. Bu, daha mərkəzləşdirilmiş bir yanaşmadır.
Security
- Scriptletlərdən Qaçınmaq: Əsas qayda! EL və JSTL istifadə edin.
- XSS Prevention: Həmişə
<c:out>
və ya ekvivalent escaping mexanizmləri ilə istifadəçi tərəfindən daxil edilmiş və ya dinamik məlumatları escape edin. - Input Validation: Həm client-side (JavaScript), həm də (daha vacibi) server-side (Servlet/Service layer) validation tətbiq edin. Heç vaxt yalnız client-side validation-a güvənməyin.
- /WEB-INF/: Bütün JSP view-larını
/WEB-INF
altına yerləşdirin. - CSRF (Cross-Site Request Forgery) Prevention: Formalara unique tokens əlavə edərək və onları server-side-da yoxlayaraq qorunma tətbiq edin.
Performance
- JSP Compilation: Anlayın ki, JSP-lər ilk request-də (və ya pre-compile edildikdə) Servlet-ə çevrilir. Bu ilk request bir az ləng ola bilər.
- Session Management: Əgər bir səhifə session-dan istifadə etmirsə,
<%@ page session="false" %>
ilə onu deaktiv edin. Bu, lazımsız session yaratma overhead-ini aradan qaldırır. include
Directive vs Action: Statik məzmun üçün (headers, footers)<%@ include file="..." %>
directive-i<jsp:include>
action-ından daha performanslıdır, çünki translation phase-də yalnız bir dəfə işləyir.
JSP Fragments (.jspf)
.jspf
uzantılı fayllar adətən tam JSP səhifələri deyil, başqa JSP-lərə <%@ include ... %>
directive-i ilə daxil edilmək üçün nəzərdə tutulmuş parçalardır. Bu, təkrar istifadə olunan statik markup və ya JSP kod blokları üçün faydalıdır.
JSP və Modern Web Development
Etiraf etmək lazımdır ki, müasir Single Page Applications (SPA) (React, Angular, Vue) və microservices arxitekturalarının yüksəlişi ilə birlikdə, ənənəvi server-rendered JSP-nin istifadəsi bir qədər azalmışdır. Çox vaxt backend (məsələn, Spring Boot, Jakarta EE REST) JSON API-ləri təqdim edir və frontend bu API-ləri istifadə edən ayrı bir JavaScript application olur.
Ancaq JSP hələ də bir çox mövcud Jakarta EE tətbiqlərində, bəzi yeni layihələrdə (xüsusilə server-side rendering-ə üstünlük verildikdə) və Thymeleaf kimi alternativ template engines ilə birlikdə istifadə olunur.
Nəticə
JSP, Java web development-ın vacib bir parçasıdır. Onun lifecycle-ını, müxtəlif elementlərini (scripting, directives, actions), implicit objects-i və xüsusilə də müasir yanaşmalar olan Expression Language (EL) və JSP Standard Tag Library-ni (JSTL) dərindən başa düşmək effektiv və maintainable veb tətbiqlər yaratmaq üçün kritikdir. Servlet-lərlə düzgün inteqrasiya (xüsusilə MVC pattern-i çərçivəsində) və /WEB-INF/
kimi təhlükəsizlik praktikaları da unudulmamalıdır.
Scriptlet-lərdən qaçınmaq və EL/JSTL-ə fokuslanmaq sizi daha təmiz, oxunaqlı və idarə edilə bilən presentation layer-ə aparacaq.