Danh sách câu hỏi của đề

Câu hỏi: PRJ301 Phát triển ứng dụng Java web – Bộ ôn tập thi lại số 3

50 câu trắc nghiệm kèm lời giải của môn PRJ301 - Phát triển ứng dụng Java web, xếp đúng thứ tự trong đề. Trang 2/3 — câu 21–40.

Danh sách câu hỏi

40/50 câuCòn 10
AUse the getConnection() method of the DriverManager class
BCall the createConnection() method of the ConnectionFactory class
CInstantiate a new Connection object directly
DExecute a SQL query to establish a connection dynamically
Lời giải
Đáp án đúng: "Use the getConnection() method of the DriverManager class". Trình tự thông thường là nạp driver rồi gọi phương thức tĩnh này với chuỗi địa chỉ dạng jdbc kèm tên người dùng và mật khẩu; lớp quản lý driver hỏi lần lượt các driver đã đăng ký xem ai hiểu chuỗi địa chỉ đó và trả về đối tượng kết nối do driver ấy tạo, rồi từ đối tượng kết nối ta mới tạo được câu lệnh để chạy SQL. "Call the createConnection() method of the ConnectionFactory class" sai vì trong JDBC chuẩn không có lớp nào mang tên đó, đây là tên nghe giống khuôn mẫu nhà máy nhưng không tồn tại. "Instantiate a new Connection object directly" sai vì kết nối là một giao diện, không thể dựng trực tiếp bằng toán tử tạo đối tượng; thực thể cụ thể luôn do driver cung cấp. "Execute a SQL query to establish a connection dynamically" sai ở thứ tự nhân quả: muốn gửi được một câu SQL thì phải có kết nối trước đã, nên không thể dùng chính SQL để mở kết nối.
Mở trang câu hỏi này →
AExplicit transaction management by invoke con.beginTrans()
BTurn off auto commit mode from DBSM for implicit transaction
CIt is automatically managed by DBMS
DInvoke con.commit() or con,rollback()
Lời giải
Đáp án đúng: "Invoke con.commit() or con,rollback()". Trong JDBC, giao dịch được điều khiển trên chính đối tượng Connection: đặt setAutoCommit(false) để nhiều câu lệnh gộp vào một giao dịch, rồi kết thúc bằng commit() khi mọi việc trôi chảy hoặc rollback() trong khối bắt lỗi để trả dữ liệu về trạng thái trước đó; chính cặp lệnh kết thúc này là chỗ lập trình viên quyết định giao dịch, nên nó là câu trả lời sát nhất. "Explicit transaction management by invoke con.beginTrans()" sai vì Connection không có phương thức nào tên như vậy, giao dịch tường minh bắt đầu bằng việc tắt chế độ tự commit chứ không bằng một lệnh mở. "Turn off auto commit mode from DBSM for implicit transaction" sai chỗ: chế độ tự commit được tắt từ phía mã JDBC trên Connection, và tắt nó là bước mở đầu cho giao dịch tường minh chứ không tự kết thúc giao dịch. "It is automatically managed by DBMS" sai vì khi để nguyên chế độ tự commit thì mỗi câu lệnh là một giao dịch riêng, không có cách nào gộp nhiều câu lệnh lại.
Mở trang câu hỏi này →
23In a servlet, what does the following line do?4 lựa chọncó code
Đề bài
session.setAttribute("user", null);
AIt causes a session invalidation
BIt sets the "user" attribute to null without removing it
CIt throws a NullPointerException
DIt deletes the "user" attribute from the session
Lời giải
Đáp án đúng: "It deletes the "user" attribute from the session". Đặc tả servlet quy định gọi đặt thuộc tính với giá trị null có cùng tác dụng như gọi xoá thuộc tính, nên khoá đó bị lấy khỏi phiên và không còn xuất hiện trong danh sách tên thuộc tính; listener về thuộc tính của phiên cũng nhận sự kiện xoá chứ không nhận sự kiện thay giá trị. Lựa chọn "It causes a session invalidation" sai vì phiên vẫn sống với cùng định danh, chỉ lời gọi huỷ phiên mới kết thúc phiên và dọn hết thuộc tính. Lựa chọn "It sets the "user" attribute to null without removing it" là cách hiểu theo trực giác nhưng trái với quy định trên, vì không có khoá nào được giữ lại với giá trị rỗng. Lựa chọn "It throws a NullPointerException" sai vì truyền null vào đây là lời gọi hợp lệ và có nghĩa rõ ràng; đọc lại bằng phương thức lấy thuộc tính sẽ ra null đúng như khi khoá không tồn tại.
Mở trang câu hỏi này →
AModel
BView
CController
DService
Lời giải
Đáp án đúng: "View". Trong MVC, thành phần hiển thị là nơi nhận dữ liệu đã được chuẩn bị sẵn rồi dựng nó thành giao diện trả cho người dùng; ở Java web vai trò này thường do trang JSP đảm nhiệm, nó chỉ đọc các thuộc tính mà tầng điều khiển đặt vào request hay session rồi sinh ra HTML, không tự truy vấn cơ sở dữ liệu. "Model" sai vì nó chỉ giữ dữ liệu và quy tắc nghiệp vụ, tức các lớp thực thể và lớp truy cập dữ liệu, hoàn toàn không biết gì về cách trình bày. "Controller" sai vì nó là servlet tiếp nhận yêu cầu, đọc tham số, gọi tầng nghiệp vụ rồi chọn trang để forward tới: nó điều phối chứ không vẽ giao diện. "Service" sai vì đây không phải một trong ba thành phần của MVC; lớp service chỉ là cách tổ chức nghiệp vụ nằm bên trong phần mô hình, và dù có hay không có nó thì việc trình bày dữ liệu vẫn thuộc tầng hiển thị.
Mở trang câu hỏi này →
AService Layer
BModel
CView
DController
Lời giải
Đáp án đúng: "Service Layer". Khuôn mẫu MVC chỉ định nghĩa ba vai: nơi giữ dữ liệu cùng quy tắc, nơi hiển thị và nơi tiếp nhận yêu cầu rồi điều phối. Tầng dịch vụ là quy ước tổ chức mã bổ sung, rất hay gặp trong các khung lớn và có ích khi tách nghiệp vụ, nhưng không thuộc định nghĩa của khuôn mẫu, nên nó chính là thứ cần chọn cho câu hỏi tìm thành phần không thuộc. "Model" là một trong ba vai, giữ dữ liệu và trạng thái nghiệp vụ. "View" cũng là một vai, sinh giao diện trả về cho người dùng, trong Java web thường là trang JSP. "Controller" là vai thứ ba, thường do servlet đảm nhiệm: nhận yêu cầu, gọi xử lý rồi chọn khung hiển thị. Ba thứ đó có tên ngay trong tên gọi của khuôn mẫu nên không thể là đáp án.
Mở trang câu hỏi này →
APresentation layer
BData access layer
CBusiness logic layer
DData storage layer
Lời giải
Đáp án đúng: "Business logic layer". Trong kiến trúc nhiều tầng, tầng nghiệp vụ là nơi đặt quy tắc và quy trình của bài toán: kiểm tra điều kiện, tính toán, quyết định luồng xử lý, rồi gọi xuống tầng truy xuất dữ liệu khi cần. Tầng "Presentation layer" chỉ lo nhận dữ liệu nhập và trình bày kết quả, tương ứng với servlet điều phối và trang JSP, nên không được chứa quy tắc nghiệp vụ. Tầng "Data access layer" đóng gói cách nói chuyện với cơ sở dữ liệu qua các lớp truy xuất và câu lệnh JDBC; nó biết lấy dữ liệu ở đâu chứ không quyết định dữ liệu đó có hợp lệ về nghiệp vụ hay không. Tầng "Data storage layer" là bản thân hệ quản trị cơ sở dữ liệu, chỉ lưu và trả dữ liệu; ràng buộc ở mức này là ràng buộc toàn vẹn của bảng, không phải quy tắc nghiệp vụ của ứng dụng.
Mở trang câu hỏi này →
AThis method is both secure and efficient, providing immediate retrieval of authorization details
BIt is often considered unsafe because there is a risk that someone could change the session information, which could lead to unauthorized access to higher privileges..
CAdvisable to reduce the frequency of database queries, hence optimizing performance.
DThere are no identified disadvantages; this technique is widely endorsed for managing access controls
Lời giải
Đáp án đúng: "Advisable to reduce the frequency of database queries, hence optimizing performance.". Dữ liệu đặt trong phiên nằm ở bộ nhớ phía máy chủ, client chỉ giữ mã phiên, nên sau khi đăng nhập một lần ta đọc vai trò và quyền từ phiên cho mọi yêu cầu sau mà không phải hỏi lại cơ sở dữ liệu; với ứng dụng mà trang nào cũng cần kiểm quyền thì số truy vấn tiết kiệm được rất đáng kể, và đó đúng là hệ quả câu hỏi nhắm tới. "This method is both secure and efficient, providing immediate retrieval of authorization details" khẳng định quá mạnh ở chữ an toàn: cách làm này vẫn phải chống việc chiếm mã phiên và vẫn phải làm mới khi quyền thay đổi, nên gọi nó vừa an toàn vừa hiệu quả là không chính xác. Lựa chọn cho rằng cách này "unsafe because there is a risk that someone could change the session information" lại mô tả sai cơ chế: nội dung phiên không nằm phía client nên người dùng không sửa trực tiếp được, khác hẳn dữ liệu đặt trong cookie hay trường ẩn. "There are no identified disadvantages; this technique is widely endorsed for managing access controls" sai vì nhược điểm có thật và dễ chỉ ra: quyền bị thu hồi trong cơ sở dữ liệu không tự phản ánh vào phiên đang mở, và dữ liệu phiên chiếm bộ nhớ nên phải nhân bản khi chạy nhiều máy.
Mở trang câu hỏi này →
AIncrease network performance
BTrack user activities
CLong-term data storage
DProtect data transmitted from client to server
Lời giải
Đáp án đúng: "Track user activities". HTTP không giữ trạng thái nên mỗi request về đến server là một lượt rời rạc; quản lý phiên gắn các lượt đó vào cùng một người dùng bằng một định danh phiên, nhờ vậy mới giữ được trạng thái đăng nhập, giỏ hàng hay bước đang làm dở khi người dùng đi qua nhiều trang. Lựa chọn "Increase network performance" không phải mục đích: giữ phiên còn tốn bộ nhớ trên server và thêm dữ liệu đi kèm mỗi lượt gọi. Lựa chọn "Long-term data storage" nhầm vai với cơ sở dữ liệu, vì phiên bị xoá khi quá thời gian chờ, khi mã gọi huỷ phiên hoặc khi server khởi động lại. Lựa chọn "Protect data transmitted from client to server" là việc của kênh truyền được mã hoá; bản thân phiên không che dữ liệu trên đường đi, và định danh phiên bị lấy còn là một rủi ro phải phòng.
Mở trang câu hỏi này →
Đề bài
public class CookieExampleServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO: Your code here
    }
}
ACookie newCookie = new Cookie("username", "john_doe"); response.addCookie(newCookie);
Bresponse.setCookie("username", "john_doe");
Crequest.createCookie("username", "john_doe"); response.sendCookie();
DCookie.create("username", "john_doe"); response.writeCookie();
Lời giải

Đáp án đúng: "Cookie newCookie =

Lời giải
new Cookie("username", "john_doe");
response.addCookie(newCookie);

". Cookie là một đối tượng được dựng bằng hàm khởi tạo hai tham số tên và giá trị, rồi phải nhờ phản hồi mang ra ngoài: addCookie thêm một dòng tiêu đề Set-Cookie vào phần đầu của phản hồi, vì vậy lệnh này phải chạy trước khi nội dung phản hồi được gửi đi. Lựa chọn dùng "response.setCookie("username", "john_doe"); " sai vì HttpServletResponse không có phương thức setCookie; nó chỉ nhận một đối tượng Cookie đã tạo qua addCookie. Lựa chọn dùng "request.createCookie("username", "john_doe"); " sai vì request là luồng dữ liệu đi vào, nó chỉ có getCookies để đọc cookie client gửi lên, và "response.sendCookie(); " cũng không tồn tại trong API. Lựa chọn dùng "Cookie.create("username", "john_doe"); " sai vì lớp Cookie không cung cấp phương thức tĩnh nào tên create, và "response.writeCookie(); " cũng là tên tự đặt: tên đúng duy nhất để đính cookie vào phản hồi là addCookie.

Mở trang câu hỏi này →
AAn object representing a single servlet instance
BAn interface for interacting with the client's web browser
CAn object representing the entire web application
DA mechanism for managing session data
Lời giải
Đáp án đúng: "An object representing the entire web application". Mỗi ứng dụng web khi được triển khai có đúng một ngữ cảnh servlet, dùng chung cho mọi servlet trong ứng dụng: đọc tham số khởi tạo của toàn ứng dụng, chia sẻ thuộc tính ở phạm vi ứng dụng, tra đường dẫn thật trên đĩa và ghi log. Mô tả "An object representing a single servlet instance" ứng với vật thể cấu hình gắn riêng một servlet, vốn chỉ thấy tham số khởi tạo khai cho servlet đó. Mô tả "An interface for interacting with the client's web browser" ứng với cặp yêu cầu và phản hồi của từng lượt gọi, vì ngữ cảnh ứng dụng không biết gì về một trình duyệt cụ thể. Mô tả "A mechanism for managing session data" ứng với phiên làm việc, thứ tồn tại một bản cho mỗi người dùng chứ không phải một bản cho cả ứng dụng.
Mở trang câu hỏi này →
A. (dot)
B+ (plus)
C* (asterisk)
D: (colon)
Lời giải
Đáp án đúng: ". (dot)". Trong EL, dấu chấm đọc một thuộc tính của đối tượng hoặc một khoá của bảng ánh xạ: viết ${user.name} thì EL gọi phương thức đọc thuộc tính theo quy ước JavaBean, còn nếu đối tượng là bảng ánh xạ thì phần sau dấu chấm được dùng làm khoá. Lựa chọn "+ (plus)" là phép cộng số học trong EL, nó còn cố ép chuỗi về số nên đem dùng để truy cập thuộc tính sẽ gây lỗi kiểu. Lựa chọn "* (asterisk)" là phép nhân, cũng chỉ làm việc trên giá trị số chứ không đi vào cấu trúc đối tượng. Lựa chọn ": (colon)" không phải toán tử của EL; dấu hai chấm chỉ xuất hiện khi ngăn tiền tố thư viện thẻ với tên thẻ. Ngoài dấu chấm, EL còn cho dùng cặp ngoặc vuông kèm khoá dạng chuỗi, cách này cần khi tên khoá có dấu cách hoặc được tính ra lúc chạy.
Mở trang câu hỏi này →
ApageScope → requestScope → sessionScope → applicationScope
BapplicationScope → sessionScope → requestScope → pageScope
CsessionScope → pageScope → requestScope → applicationScope
DrequestScope → pageScope → sessionScope → applicationScope
Lời giải
Đáp án đúng: "pageScope → requestScope → sessionScope → applicationScope". Khi một biểu thức EL chỉ nêu tên mà không nêu phạm vi, trình đánh giá tìm từ phạm vi hẹp nhất ra rộng nhất và lấy giá trị đầu tiên gặp được; thứ tự này cho phép biến đặt trong trang tạm che biến cùng tên ở phạm vi rộng hơn, còn muốn chỉ đích danh thì viết tên phạm vi rồi tới tên biến. Lựa chọn "applicationScope → sessionScope → requestScope → pageScope" đảo ngược hoàn toàn, khiến biến dùng chung cho cả ứng dụng luôn thắng biến cục bộ của trang. Lựa chọn "sessionScope → pageScope → requestScope → applicationScope" đặt phạm vi phiên lên đầu, trong khi phiên rộng hơn cả trang lẫn request nên không thể được tìm trước. Lựa chọn "requestScope → pageScope → sessionScope → applicationScope" chỉ đảo hai bậc đầu nhưng vẫn sai, vì biến do thẻ set tạo mà không nêu phạm vi nằm ở phạm vi trang và phải được thấy trước tiên.
Mở trang câu hỏi này →
A${bookList[12].title}
B${bookList.get(2).title}
C${bookList["2"].title}
D${bookList.title[2]}
E${bookList[2].title}
Lời giải

Đáp án đúng: "${bookList["2"].title}". Toán tử ngoặc vuông là cách truy cập dùng được cho cả danh sách và Map: EL lấy giá trị trong ngoặc làm khoá rồi ép về kiểu chỉ số khi đối tượng đích là List hoặc mảng, nên chuỗi hai được ép thành số hai; phần tử trả về là một Map, vì vậy dấu chấm đứng sau được hiểu là tra khoá title trong Map đó chứ không phải gọi getter. "${bookList[12].title}" sai vì nó trỏ tới phần tử thứ mười ba, lệch hẳn vị trí được hỏi và thường gây lỗi vượt biên. "${

Lời giải
bookList.get(2).title
}
" sai

vì đó là cách viết lời gọi phương thức kiểu Java, không phải cú pháp truy cập phần tử theo chỉ số mà câu hỏi đang nhắm tới. "${bookList.title[2]}" sai vì nó đi tìm thuộc tính title trên chính danh sách rồi mới lấy chỉ số, tức đảo ngược thứ tự hai chặng truy cập. "${bookList[2].title}" viết chỉ số bằng số nguyên trực tiếp nên chỉ là biến thể trùng nghĩa, không mang điểm kiến thức được kiểm tra là việc ngoặc vuông nhận một khoá rồi tự ép kiểu theo đối tượng đích.

Mở trang câu hỏi này →
ABy using the dot operator directly on the collection
BBy iterating over the collection using a loop in EL
CBy accessing elements using square brackets with the index
DBy converting the collection to a string and then accessing elements
Lời giải
Đáp án đúng: "By accessing elements using square brackets with the index". EL quy định toán tử ngoặc vuông là cách lấy phần tử của một tập có thứ tự hay của một map: viết tên biến rồi ngoặc vuông kèm chỉ số thì EL lấy phần tử ở vị trí đó của danh sách hoặc mảng, còn kèm một chuỗi khoá thì nó tra map; chỉ số có thể là biểu thức nên dùng được ngay trong biến đếm của thẻ lặp. "By using the dot operator directly on the collection" sai với tập có chỉ số vì dấu chấm được hiểu là đọc thuộc tính theo quy ước bean, nó đi tìm phương thức đọc mang tên đứng sau dấu chấm chứ không nhận một số làm vị trí. "By iterating over the collection using a loop in EL" sai vì EL là ngôn ngữ biểu thức, nó không có câu lệnh lặp; việc duyệt tập phải nhờ thẻ lặp của thư viện thẻ chuẩn hoặc vòng lặp trong mã Java. "By converting the collection to a string and then accessing elements" sai vì đổi tập thành chuỗi chỉ cho ra phần mô tả văn bản của đối tượng, mất luôn khả năng lấy đúng phần tử và sai cả kiểu dữ liệu trả về.
Mở trang câu hỏi này →
AA component responsible for managing database connections.
BA mechanism for intercepting and reacting to lifecycle events of a web application.
CA module for handling HTTP requests and generating responses.
DA tool for optimizing server performance and resource utilization.
Lời giải
Đáp án đúng: "A mechanism for intercepting and reacting to lifecycle events of a web application.". Server listener là lớp do ta viết, cài một giao diện listener của đặc tả servlet rồi khai báo bằng annotation listener hoặc bằng khối listener trong mô tả triển khai; container tự gọi các phương thức callback đúng lúc sự kiện vòng đời xảy ra, chẳng hạn ServletContextListener nhận contextInitialized khi ứng dụng vừa nạp xong và contextDestroyed khi ứng dụng bị tháo, HttpSessionListener nhận mốc tạo và huỷ phiên, ServletRequestListener nhận mốc request bắt đầu và kết thúc. Lựa chọn "A component responsible for managing database connections." mô tả một nguồn dữ liệu hay bể kết nối; listener chỉ là nơi thuận tiện để khởi tạo bể đó chứ bản thân nó không quản lý kết nối. Lựa chọn "A module for handling HTTP requests and generating responses." chính là định nghĩa của servlet, vì servlet mới nằm trên đường xử lý request và sinh nội dung trả về. Lựa chọn "A tool for optimizing server performance and resource utilization." nói về công cụ tinh chỉnh hiệu năng, không phải cơ chế bắt sự kiện vòng đời.
Mở trang câu hỏi này →
AServletContextAttributeListener
BServletRequestListener
CHttpSessionListener
DServletContextListener
Lời giải
Đáp án đúng: "ServletContextAttributeListener". Giao diện này có ba callback ứng với ba thao tác lên thuộc tính của ngữ cảnh ứng dụng là thêm, thay thế và xoá, nên việc đặt một thuộc tính ở phạm vi ứng dụng sẽ kích hoạt callback thêm thuộc tính. Lựa chọn "ServletRequestListener" chỉ bắt mốc một request bắt đầu và kết thúc, nó không theo dõi thuộc tính nào ở phạm vi ứng dụng. Lựa chọn "HttpSessionListener" bắt việc tạo và huỷ phiên; muốn bắt thuộc tính thì phải dùng giao diện về thuộc tính của phiên, mà phạm vi khi đó cũng là phiên chứ không phải ngữ cảnh ứng dụng. Lựa chọn "ServletContextListener" đúng phạm vi nhưng sai loại sự kiện: nó chỉ được gọi khi ngữ cảnh ứng dụng được khởi tạo và khi bị huỷ, hai mốc đó không liên quan đến việc đặt thuộc tính.
Mở trang câu hỏi này →
Đề bài
<context-param> tag in the web.xml file?
  <web-app>
    <context-param>
      <param-name>studentName</param-name>
      <param-value>abcJhn</param-value>
    </context-param>

</web-app>

Arequest.getParameter("studentName");
BServletContext sc = getServletContext(); String serverName = sc.getInitParameter("studentName");
CServletConfig sc = getServletConfig(). String serverName = sc.getInitParameter("studentName");
Dresponse.getParameter("studentName");
Lời giải

Đáp án đúng: "ServletContext sc = getServletContext(); String serverName = sc.getInitParameter("studentName"); ". Khai báo tham số nằm trực tiếp trong phần tử gốc của mô tả triển khai, không lồng trong khai báo của một servlet nào, nên nó là tham số khởi tạo của cả ứng dụng và chỉ vật thể ngữ cảnh ứng dụng đọc được, lấy bằng lời gọi trong servlet rồi hỏi theo tên. Dòng "request.getParameter("studentName"); " đọc tham số của lượt yêu cầu, tức dữ liệu từ chuỗi truy vấn hay biểu mẫu, nên luôn trả về giá trị rỗng với tham số khai trong tệp cấu hình. Đoạn "ServletConfig sc = getServletConfig()." sai hai lẽ: vật thể cấu hình chỉ thấy tham số khởi tạo khai riêng bên trong khai báo của chính servlet đó, và dòng lại kết thúc bằng dấu chấm nên mã không biên dịch được. Dòng "response.getParameter("studentName"); " sai vì đối tượng phản hồi chỉ dùng để ghi kết quả trả về, nó không có hàm đọc tham số nào.

Mở trang câu hỏi này →
ATo listen for changes in session attributes
BTo listen for changes in application context parameters
CTo listen for changes in request parameters
DTo listen for changes in session lifecycle events
Lời giải
Đáp án đúng: "To listen for changes in session lifecycle events". Listener của phiên gắn vào các mốc vòng đời do container quản lý: phiên vừa được tạo, phiên bị invalidate hoặc hết thời gian chờ; hai phương thức sessionCreated và sessionDestroyed được gọi đúng ở các mốc đó, nhờ vậy ứng dụng đếm được số phiên đang sống và giải phóng tài nguyên kịp lúc. "To listen for changes in session attributes" sai vì theo dõi việc thêm, thay và xoá thuộc tính là nhiệm vụ của một interface khác dành riêng cho thuộc tính phiên, không phải của listener vòng đời. "To listen for changes in application context parameters" sai vì phạm vi ứng dụng có bộ listener riêng của nó, còn tham số khởi tạo khai báo trong web.xml thì không đổi lúc đang chạy. "To listen for changes in request parameters" sai vì tham số của yêu cầu chỉ đọc được qua getParameter và không có sự kiện nào được phát ra khi chúng khác nhau giữa các yêu cầu.
Mở trang câu hỏi này →
Avar
Bitems
Cstep
Dcase
Lời giải
Đáp án đúng: "case". Thẻ lặp của JSTL nhận "items" để chỉ tập nguồn, "var" để đặt tên biến phần tử, varStatus để lấy thông tin lượt chạy, cùng begin, end và "step" khi lặp theo chỉ số, nên ba thuộc tính kia đều hợp lệ và hay dùng. Thư viện này không có thuộc tính nào tên case, mà cũng không có thẻ cùng tên: việc rẽ nhiều nhánh được viết bằng c:choose bọc các c:when và một c:otherwise, nên từ khoá quen thuộc trong câu lệnh switch của Java không chuyển sang thư viện thẻ. Đáng chú ý là đặt một thuộc tính lạ vào thẻ JSTL không bị bỏ qua im lặng: ở pha dịch trang, container đối chiếu thẻ với khai báo trong bản mô tả thư viện thẻ, thấy thuộc tính không được khai báo thì báo lỗi dịch và trang không chạy.
Mở trang câu hỏi này →
A<c:if>
B<c:choose>
C<c:when>
D<c:otherwise>
Lời giải
Đáp án đúng: "<c:if>". Thẻ này nhận một thuộc tính kiểm tra là biểu thức luận lý, EL tính ra đúng hoặc sai, rồi thân thẻ chỉ được dựng ra kết quả khi giá trị là đúng; đó là dạng rẽ nhánh một nhánh, không có phần ngược lại. Thẻ "<c:choose>" tự nó không mang biểu thức nào, chỉ làm vỏ chứa các nhánh con, nên không trực tiếp quyết định hiển thị. Thẻ "<c:when>" có mang biểu thức nhưng chỉ hợp lệ khi nằm trong thẻ vỏ rẽ nhiều nhánh, và cả nhóm chạy theo lối chọn nhánh đầu tiên khớp chứ không phải kiểm một điều kiện độc lập. Thẻ "<c:otherwise>" là nhánh dự phòng khi mọi nhánh trước đều không khớp, bản thân nó không nhận biểu thức luận lý nào.
Mở trang câu hỏi này →