הקובץ web.xml משמש רק כשפורסים אפליקציית Java בסביבת זמן ריצה שכוללת את שרת Eclipse Jetty 9/ servlet 3. פרטים נוספים זמינים במאמר בנושא Eclipse Jetty 9.3 Runtime.
אפליקציות אינטרנט ב-Java משתמשות בקובץ תיאור פריסה כדי לקבוע איך כתובות URL ממופות ל-servlets, אילו כתובות URL דורשות אימות ומידע נוסף. שם הקובץ הוא web.xml והוא נמצא ב-WAR של האפליקציה בספרייה WEB-INF/.
web.xml הוא חלק מתקן ה-servlet לאפליקציות אינטרנט.
מידע נוסף על תקן web.xml זמין במפרט Servlet.
מידע על קובצי תיאור פריסה
קובץ תיאור הפריסה של אפליקציית אינטרנט מתאר את המחלקות, המשאבים וההגדרות של האפליקציה, ואיך שרת האינטרנט משתמש בהם כדי לטפל בבקשות אינטרנט. כאשר שרת האינטרנט מקבל בקשה לאפליקציה, הוא משתמש בקובץ תיאור הפריסה כדי למפות את כתובת ה-URL של הבקשה לקוד שאמור לטפל בבקשה.
קובץ תיאור הפריסה הוא קובץ בשם web.xml. הוא נמצא בקובץ ה-WAR של האפליקציה בספרייה WEB-INF/. הקובץ הוא קובץ XML שרכיב הבסיס שלו הוא <web-app>.
הנה web.xml דוגמה למיפוי של כל נתיבי כתובות ה-URL (/*) למחלקה של ה-servlet =mysite.server.ComingSoonServlet:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>comingsoon</servlet-name>
<servlet-class>mysite.server.ComingSoonServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>comingsoon</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Servlets ונתיבים של כתובות URL
web.xml מגדיר מיפויים בין נתיבי כתובות URL לבין הסרוולטים שמטפלים בבקשות עם הנתיבים האלה. שרת האינטרנט משתמש בהגדרה הזו כדי לזהות את ה-servlet לטיפול בבקשה נתונה, וקורא לשיטת המחלקה שמתאימה לשיטת הבקשה (למשל, שיטת doGet() לבקשות HTTP GET).
כדי למפות כתובת URL לסרוולט, צריך להצהיר על הסרוולט באמצעות האלמנט <servlet>, ואז להגדיר מיפוי מנתיב כתובת ה-URL להצהרה על סרוולט באמצעות האלמנט <servlet-mapping>.
רכיב <servlet> מכריז על ה-servlet, כולל שם שמשמש להתייחסות ל-servlet על ידי רכיבים אחרים בקובץ, המחלקה שבה יש להשתמש עבור ה-servlet ופרמטרים של אתחול. אפשר להצהיר על כמה סרוולטים באמצעות אותה מחלקה עם פרמטרים שונים של אתחול. השם של כל servlet חייב להיות ייחודי בתוך קובץ תיאור הפריסה.
<servlet>
<servlet-name>redteam</servlet-name>
<servlet-class>mysite.server.TeamServlet</servlet-class>
<init-param>
<param-name>teamColor</param-name>
<param-value>red</param-value>
</init-param>
<init-param>
<param-name>bgColor</param-name>
<param-value>#CC0000</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>blueteam</servlet-name>
<servlet-class>mysite.server.TeamServlet</servlet-class>
<init-param>
<param-name>teamColor</param-name>
<param-value>blue</param-value>
</init-param>
<init-param>
<param-name>bgColor</param-name>
<param-value>#0000CC</param-value>
</init-param>
</servlet>
רכיב <servlet-mapping> מציין תבנית URL ואת השם של סרוולט מוצהר שייעשה בו שימוש לבקשות שכתובת ה-URL שלהן תואמת לתבנית. בתבנית של כתובת ה-URL אפשר להשתמש בכוכבית (*) בתחילת התבנית או בסופה כדי לציין אפס תווים או יותר מכל תו. התקן לא תומך בתווים כלליים באמצע מחרוזת, ולא מאפשר שימוש בכמה תווים כלליים בתבנית אחת. התבנית תואמת לנתיב המלא של כתובת ה-URL, החל מהלוכסן (/) שאחרי שם הדומיין, כולל הלוכסן.
<servlet-mapping>
<servlet-name>redteam</servlet-name>
<url-pattern>/red/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>blueteam</servlet-name>
<url-pattern>/blue/*</url-pattern>
</servlet-mapping>
בדוגמה הזו, בקשה לכתובת ה-URL http://www.example.com/blue/teamProfile מטופלת על ידי המחלקה TeamServlet, כשהפרמטר teamColor שווה ל-blue והפרמטר bgColor שווה ל-#0000CC. ה-servlet יכול לקבל את החלק של נתיב כתובת ה-URL שתואם לתו כל כללי באמצעות השיטה getPathInfo() של האובייקט ServletRequest.
הסרוולט יכול לגשת לפרמטרים של ההפעלה שלו באמצעות קבלת ההגדרה של הסרוולט באמצעות השיטה getServletConfig() שלו, ואז קריאה לשיטה getInitParameter() באובייקט ההגדרה באמצעות שם הפרמטר כארגומנט.
String teamColor = getServletConfig().getInitParameter("teamColor");
JSPs
אפליקציה יכולה להשתמש ב-JavaServer Pages (JSP) כדי להטמיע דפי אינטרנט. קובצי JSP הם סרוולטים שמוגדרים באמצעות תוכן סטטי (כמו HTML) בשילוב עם קוד Java.
App Engine תומך בהידור אוטומטי ובמיפוי כתובות URL ל-JSP. קובץ JSP ב-WAR של האפליקציה (מחוץ ל-WEB-INF/) ששם הקובץ שלו מסתיים ב-.jsp עובר קומפילציה אוטומטית למחלקת servlet, וממופה לנתיב כתובת ה-URL ששווה לנתיב לקובץ ה-JSP משורש ה-WAR. לדוגמה, אם לאפליקציה יש קובץ JSP בשם start.jsp בספריית משנה בשם register/ בקובץ ה-WAR שלה, מערכת App Engine תבצע קומפילציה של הקובץ ותמפה אותו לנתיב כתובת ה-URL /register/start.jsp.
אם רוצים לקבל יותר שליטה על המיפוי של ה-JSP לכתובת URL, אפשר לציין את המיפוי באופן מפורש על ידי הצהרה עליו באמצעות רכיב <servlet> בתיאור הפריסה. במקום אלמנט <servlet-class>, מציינים אלמנט <jsp-file> עם הנתיב לקובץ ה-JSP משורש ה-WAR. האלמנט <servlet> של JSP יכול להכיל פרמטרים של אתחול.
<servlet>
<servlet-name>register</servlet-name>
<jsp-file>/register/start.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>register</servlet-name>
<url-pattern>/register/*</url-pattern>
</servlet-mapping>
אפשר להתקין ספריות תגים של JSP באמצעות האלמנט <taglib>. לספריית תגים יש נתיב לקובץ JSP Tag Library Descriptor (TLD) (<taglib-location>) ו-URI שדפי JSP משתמשים בו כדי לבחור את הספרייה לטעינה (<taglib-uri>). שימו לב ש-App Engine מספק את JavaServer Pages Standard Tag Library (JSTL), ואין צורך להתקין אותה.
<taglib>
<taglib-uri>/escape</taglib-uri>
<taglib-location>/WEB-INF/escape-tags.tld</taglib-location>
</taglib>
רשימת קבצים עם הודעת פתיחה
אם כתובות ה-URL של האתר מייצגות נתיבים לקבצים סטטיים או ל-JSP ב-WAR, כדאי שגם נתיבים לספריות יבצעו פעולה שימושית.
משתמש שנכנס לנתיב כתובת ה-URL /help/accounts/password.jsp כדי לקבל מידע על סיסמאות לחשבון, עשוי לנסות להיכנס לכתובת /help/accounts/ כדי למצוא דף עם מבוא לתיעוד של מערכת החשבונות. קובץ תיאור הפריסה יכול לציין רשימה של שמות קבצים שהשרת צריך לנסות כשהמשתמש ניגש לנתיב שמייצג ספריית משנה של WAR (שלא ממופה כבר באופן מפורש ל-servlet). בתקן של סרוולט, הרשימה הזו נקראת "רשימת קובצי הפתיחה".
לדוגמה, אם המשתמש ניגש לנתיב כתובת ה-URL /help/accounts/, הרכיב <welcome-file-list> הבא בקובץ תיאור הפריסה מציין לשרת לבדוק את help/accounts/index.jsp ואת help/accounts/index.html לפני שהוא מדווח שכתובת ה-URL לא קיימת:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
מסננים
מסנן הוא מחלקה שפועלת על בקשה כמו סרוולט, אבל יכולה לאפשר לטיפול בבקשה להמשיך עם מסננים או סרוולטים אחרים. מסנן יכול לבצע משימה משנית כמו רישום ביומן, ביצוע בדיקות אימות מיוחדות או הוספת הערות לאובייקטים של הבקשה או התגובה לפני הקריאה ל-servlet. מסננים מאפשרים לכם ליצור משימות לעיבוד בקשות מתוך קובץ תיאור פריסה.
מחלקה של מסנן מטמיעה את הממשק javax.servlet.Filter, כולל השיטה doFilter(). הנה הטמעה פשוטה של מסנן שרושם הודעה ביומן ומעביר את השליטה בהמשך השרשרת, שעשויה לכלול מסננים אחרים או servlet, כפי שמתואר ב-קובץ תיאור פריסה:
package mysite.server;
import java.io.IOException;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class LogFilterImpl implements Filter {
private FilterConfig filterConfig;
private static final Logger log = Logger.getLogger(LogFilterImpl.class.getName());
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
log.warning("Log filter processed a " + getFilterConfig().getInitParameter("logType")
+ " request");
filterChain.doFilter(request, response);
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
public void init(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public void destroy() {}
}
בדומה ל-servlets, מגדירים מסנן בתיאור הפריסה על ידי הצהרה על המסנן באמצעות רכיב <filter>, ואז מיפוי שלו לתבנית של כתובת URL באמצעות רכיב <filter-mapping>. אפשר גם למפות מסננים ישירות לסרוולטים אחרים.
הרכיב <filter> מכיל רכיבים <filter-name>, <filter-class> ורכיבים אופציונליים <init-param>.
<filter>
<filter-name>logSpecial</filter-name>
<filter-class>mysite.server.LogFilterImpl</filter-class>
<init-param>
<param-name>logType</param-name>
<param-value>special</param-value>
</init-param>
</filter>
האלמנט <filter-mapping> מכיל את האלמנט <filter-name> שתואם לשם של מסנן מוצהר, ואת האלמנט <url-pattern> להחלת המסנן על כתובות URL, או את האלמנט <servlet-name> שתואם לשם של servlet מוצהר להחלת המסנן בכל פעם שה-servlet נקרא.
<!-- Log for all URLs ending in ".special" -->
<filter-mapping>
<filter-name>logSpecial</filter-name>
<url-pattern>*.special</url-pattern>
</filter-mapping>
<!-- Log for all URLs that use the "comingsoon" servlet -->
<filter-mapping>
<filter-name>logSpecial</filter-name>
<servlet-name>comingsoon</servlet-name>
</filter-mapping>
Error Handlers
אפשר להתאים אישית את מה שהשרת שולח למשתמש כשמתרחשת שגיאה, באמצעות קובץ תיאור הפריסה. השרת יכול להציג מיקום חלופי של דף כשהוא עומד לשלוח קוד סטטוס של HTTP מסוים, או כשסרוולט מעלה חריג מסוים של Java.
האלמנט <error-page> מכיל אלמנט <error-code> עם ערך של קוד שגיאת HTTP (למשל 500), או אלמנט <exception-type> עם שם המחלקה של החריגה הצפויה (למשל java.io.IOException). הוא מכיל גם אלמנט <location> עם נתיב כתובת ה-URL של המשאב שיוצג כשהשגיאה מתרחשת.
<error-page>
<error-code>500</error-code>
<location>/errors/servererror.jsp</location>
</error-page>
תכונות של web.xml שלא נתמכות
התכונות הבאות של web.xml לא נתמכות ב-App Engine:
- App Engine תומך ברכיב
<load-on-startup>להצהרות על סרוולטים. עם זאת, הטעינה מתרחשת בפועל במהלך הבקשה הראשונה שמטופלת על ידי מופע שרת האינטרנט, ולא לפני כן. - חלק מרכיבי קובץ תיאור הפריסה יכולים לקבל שם מוצג קריא, תיאור וסמל לשימוש בסביבות פיתוח משולבות (IDE). App Engine לא משתמש בהן ומתעלם מהן.
- App Engine לא תומך במשתני סביבה של JNDI (
<env-entry>). - App Engine לא תומך במשאבי EJB (
<resource-ref>). - אין תמיכה בהודעה על השמדה של סרוולטים, הקשר של סרוולט או מסננים.
- המערכת מתעלמת מהרכיב
<distributable>. - אין תמיכה בתזמון של Servlet באמצעות
<run-at>. - אין תמיכה במגבלות אבטחה: כדי לקבל פונקציונליות שוות ערך, אפשר לעיין במאמר בנושא אימות לשירותי Cloud באמצעות ספריות לקוח.
- אין תמיכה ב-CONFIDENTIAL ב-
web.xml.