JSP 1.2 Spesifikasyonu'ndan, web uygulamanızda JSP Standart Etiket Kitaplığı'nın (JSTL) kullanılması , sayfalarınızdaki JSP komut dosyası ihtiyacını azaltmaya yardımcı olması önemle tavsiye edilir . JSTL kullanan sayfaların genel olarak okunması ve bakımı daha kolaydır.
...
Mümkünse, etiket kitaplıkları eşdeğer işlevsellik sağladığında JSP komut dosyalarından kaçının . Bu, sayfaların okunmasını ve bakımını kolaylaştırır, iş mantığını sunum mantığından ayırmaya yardımcı olur ve sayfalarınızın JSP 2.0 tarzı sayfalara dönüşmesini kolaylaştırır (JSP 2.0 Spesifikasyonu, scriptletlerin kullanımını destekler ancak vurguyu kaldırır).
...
İş mantığından sunum katmanı arasındaki bağlantıyı azaltmak için model-görünüm denetleyicisi (MVC) tasarım desenini benimsemek amacıyla, JSP komut dosyaları iş mantığı yazmak için kullanılmamalıdır . Bunun yerine, istemcinin isteklerinin işlenmesinden döndürülen verileri ("değer nesneleri" olarak da adlandırılır) dönüştürmek için gerekirse JSP komut dosyaları kullanılır. O zaman bile, bu bir ön denetleyici sunucu uygulaması veya özel bir etiketle daha iyi yapılabilir.
Her istekte aynı Java kodunu çağırmak istiyorsanız , istenen sayfadan bağımsız olarak daha az veya daha fazla, örneğin bir kullanıcının oturum açıp açmadığını kontrol etmek, ardından bir filtre uygulayın ve buna göre kod yazın.doFilter()
yönteme . Örneğin:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page.
} else {
chain.doFilter(request, response); // Logged in, just continue request.
}
}
İlgili <url-pattern>
JSP sayfalarını kapsayan uygun bir haritaya eşlendiğinde, aynı kod genel JSP sayfalarını kopyalamanız gerekmez.
Bazı Java kodlarını , örneğin bazı sorgu parametrelerine dayanarak gerekirse bir tabloda görüntülemek üzere veritabanından bazı listelerin önceden yüklenmesi gibi bir isteği önceden işlemek için çağırmak istiyorsanız , yönteme uygun olarak bir sunucu uygulaması ve yazma kodu uygulayın doGet()
. Örneğin:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<Product> products = productService.list(); // Obtain all products.
request.setAttribute("products", products); // Store products in request scope.
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table.
} catch (SQLException e) {
throw new ServletException("Retrieving products failed!", e);
}
}
Bu şekilde istisnalarla uğraşmak daha kolaydır. DB'ye JSP oluşturma işleminin ortasında değil, JSP'nin görüntülenmesinden çok önce erişilir. DB erişimi bir istisna attığında yanıtı yine de değiştirme olanağınız vardır. Yukarıdaki örnekte, bir <error-page>
giriş tarafından özelleştirebileceğiniz varsayılan hata 500 sayfası görüntülenecektir web.xml
.
Bir isteği göndermek için bazı Java kodlarını çağırmak istiyorsanız , örneğin bir form gönderimini işleme koymak için , yönteme uygun olarak bir sunucu uygulaması ve kod yazın doPost()
. Örneğin:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
response.sendRedirect("home"); // Redirect to home page.
} else {
request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope.
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error.
}
}
Farklı sonuç sayfası hedeflere uğraşan Bu şekilde daha kolay olur: Bu özel örnekte (bir hata durumunda doğrulama hataları ile formunu yeniden görüntüleme kullanarak tekrar görüntülemek için ${message}
de EL ), ya da sadece başarı durumunda istenen hedef sayfasına alarak.
İsteğin ve yanıtın yürütme planını ve / veya hedefini denetlemek için bazı Java kodlarını çağırmak istiyorsanız, MVC'nin Ön Denetleyici Modeline göre bir sunucu uygulaması uygulayın . Örneğin:
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Action action = ActionFactory.getAction(request);
String view = action.execute(request, response);
if (view.equals(request.getPathInfo().substring(1)) {
request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
} else {
response.sendRedirect(view);
}
} catch (Exception e) {
throw new ServletException("Executing action failed.", e);
}
}
Veya özel bir sunucu uygulamasına gerek kalmadan sadece JSP / Facelets sayfası ve JavaBean sınıfı ile sonuçlanacak şekilde JSF , Spring MVC , Wicket vb.Gibi bir MVC çerçevesini benimseyin .
Bir JSP sayfasındaki akışı kontrol etmek için bazı Java kodlarını çağırmak istiyorsanız, JSTL çekirdeği gibi (mevcut) bir akış denetimi taglib'i almanız gerekir . Örn.List<Product>
bir tabloda :
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td>${product.description}</td>
<td>${product.price}</td>
</tr>
</c:forEach>
</table>
Tüm bu HTML kodlarına çok iyi uyan XML tarzı etiketlerle, kod, çeşitli açılış ve kapanış parantezleri içeren bir grup betiğe göre daha iyi okunabilir (ve dolayısıyla daha iyi korunabilir) ( "Bu kapanış ayracı nereye aittir?" ). Kolay bir yardım, web uygulamanızı, komut dosyaları her kullanıldığında bir istisna oluşturacak şekilde aşağıdaki parçayı ekleyerek yapılandırmaktır web.xml
:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
In Facelets Java EE parçasıdır JSP'nin halefi MVC framework sağlanan JSF , zaten değil kullanmak mümkün scriptlets . Bu şekilde işleri otomatik olarak "doğru şekilde" yapmak zorunda kalırsınız.
Bir JSP sayfasındaki "arka uç" verilerine erişmek ve bunları görüntülemek için bazı Java kodlarını çağırmak istiyorsanız , EL (İfade Dili) kullanmanız gerekir ${}
. Örneğin, gönderilen girdi değerlerinin yeniden görüntülenmesi:
<input type="text" name="foo" value="${param.foo}" />
Sonuçlarını ${param.foo}
görüntülerrequest.getParameter("foo")
.
Bazı yardımcı program Java kodunu doğrudan JSP sayfasında çağırmak istiyorsanız (genellikle public static
yöntemler), bunları EL işlevleri olarak tanımlamanız gerekir. JSTL'de standart işlevler taglib vardır, ancak işlevleri kendiniz de kolayca oluşturabilirsiniz . İşte JSTL'nin XSS saldırılarınıfn:escapeXml
önlemek için ne kadar yararlı olduğunu gösteren bir örnek .
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
...
<input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
XSS duyarlılığının hiçbir şekilde özellikle Java / JSP / JSTL / EL / ile ilişkili olmadığını unutmayın, bu sorunun geliştirdiğiniz her web uygulamasında dikkate alınması gerekir . Komut dosyalarının sorunu , en azından standart Java API'sini kullanmadan yerleşik önleme yolu sağlamamasıdır. JSP'nin halefi Facelets zaten örtülü HTML çıkışına sahip, bu yüzden Facelets'teki XSS delikleri hakkında endişelenmenize gerek yok.