WEB-INF được sử dụng để làm gì trong ứng dụng web Java EE?


177

Tôi đang làm việc trên một ứng dụng web Java EE với cấu trúc mã nguồn sau:

src/main/java                 <-- multiple packages containing java classes
src/test/java                 <-- multiple packages containing JUnit tests
src/main/resources            <-- includes properties files for textual messages
src/main/webapp/resources     <-- includes CSS, images and all Javascript files
src/main/webapp/WEB-INF
src/main/webapp/WEB-INF/tags
src/main/webapp/WEB-INF/views

Điều tôi quan tâm là WEB-INF- nó chứa web.xml, các tệp XML để thiết lập các máy chủ, bối cảnh nối dây của Spring bean và các thẻ và khung nhìn của JSP.

Tôi đang cố gắng hiểu những gì ràng buộc / định nghĩa cấu trúc này. Ví dụ, các tệp tin JSP luôn phải ở trong WEB-INFhoặc chúng có thể ở một nơi nào khác? Và có điều gì khác có thể đi vào WEB-INF? Mục nhập tệp WAR của Wikipedia đề cập đến classescác lớp Java và libcho các tệp JAR - không chắc chắn tôi đã nắm bắt đầy đủ khi cần những thứ này ngoài các vị trí tệp nguồn khác.


1
Điều này có thể hữu ích: gordondickens.com/wordpress/2012/07/03/...
smwikipedia

1
FYI Để tìm hiểu về cách tải container của servletWEB-INF và các vị trí khác xem câu hỏi, Kiểm soát đường dẫn lớp trong một servlet , đặc biệt là Câu trả lời này .
Basil Bourque

Câu trả lời:


216

Đặc tả Servlet 2.4 cho biết điều này về WEB-INF (trang 70):

Một thư mục đặc biệt tồn tại trong hệ thống phân cấp ứng dụng có tên WEB-INF. Thư mục này chứa tất cả những thứ liên quan đến ứng dụng không có trong tài liệu gốc của ứng dụng. Các WEB-INFnút không phải là một phần của cây tài liệu công cộng của ứng dụng . Không có tập tin nào trong WEB-INFthư mục có thể được phục vụ trực tiếp cho khách hàng bởi container. Tuy nhiên, nội dung của WEB-INFthư mục được hiển thị với mã servlet bằng cách sử dụng các cuộc gọi getResourcegetResourceAsStreamphương thức trên ServletContextvà có thể được hiển thị bằng các RequestDispatchercuộc gọi.

Điều này có nghĩa là các WEB-INFtài nguyên có thể truy cập được vào trình tải tài nguyên của Ứng dụng web của bạn và không hiển thị trực tiếp cho công chúng.

Đây là lý do tại sao rất nhiều dự án đưa các tài nguyên của họ như các tệp tin JSP, JAR / thư viện và các tệp lớp hoặc tệp thuộc tính của riêng họ hoặc bất kỳ thông tin nhạy cảm nào khác vào WEB-INFthư mục. Nếu không, họ có thể truy cập bằng cách sử dụng một URL tĩnh đơn giản (chẳng hạn để tải CSS hoặc Javascript chẳng hạn).

Các tệp tin của bạn có thể ở bất cứ đâu mặc dù từ góc độ kỹ thuật. Chẳng hạn, trong Spring, bạn có thể định cấu hình chúng WEB-INFrõ ràng:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:prefix="/WEB-INF/jsp/" 
    p:suffix=".jsp" >
</bean>

Các WEB-INF/classesWEB-INF/libthư mục được đề cập trong bài viết tệp WAR của Wikipedia là ví dụ về các thư mục được yêu cầu bởi đặc tả Servlet khi chạy.

Điều quan trọng là tạo sự khác biệt giữa cấu trúc của dự án và cấu trúc của tệp WAR kết quả.

Cấu trúc của dự án trong một số trường hợp sẽ phản ánh một phần cấu trúc của tệp WAR (đối với các tài nguyên tĩnh như tệp JSP hoặc tệp HTML và JavaScript, nhưng điều này không phải lúc nào cũng đúng.

Việc chuyển đổi từ cấu trúc dự án sang tệp WAR kết quả được thực hiện bởi một quá trình xây dựng.

Mặc dù bạn thường được tự do thiết kế quy trình xây dựng của riêng mình, ngày nay hầu hết mọi người sẽ sử dụng một cách tiếp cận được tiêu chuẩn hóa như Apache Maven . Trong số những thứ khác, Maven định nghĩa mặc định các tài nguyên trong bản đồ cấu trúc dự án với tài nguyên nào trong tạo phẩm kết quả (tạo phẩm kết quả là tệp WAR trong trường hợp này). Trong một số trường hợp, ánh xạ bao gồm một quy trình sao chép đơn giản trong các trường hợp khác, quy trình ánh xạ bao gồm một phép biến đổi, chẳng hạn như lọc hoặc biên dịch và các thứ khác.

Một ví dụ : WEB-INF/classesThư mục sau này sẽ chứa tất cả các lớp và tài nguyên java đã biên dịch ( src/main/javasrc/main/resources) cần được tải bởi Classloader để khởi động ứng dụng.

Một ví dụ khác : WEB-INF/libThư mục này sau đó sẽ chứa tất cả các tệp jar cần thiết cho ứng dụng. Trong một dự án maven, các phụ thuộc được quản lý cho bạn và maven tự động sao chép các tệp jar cần thiết vào WEB-INF/libthư mục cho bạn. Điều đó giải thích tại sao bạn không có một libthư mục trong dự án maven.



2
Sự thay đổi trong Servlet 3.0 & 3.1 ( JSR 340 ) cho phép phục vụ các tài nguyên tĩnh và các tệp JSP từ bên trong một tệp JAR được lưu trữ trong WEB-INF / lib. Để trích dẫn phần speclet Servlet 3.1 10.5: Ngoại trừ tài nguyên tĩnh và các tệp JSP được đóng gói trong META-INF / tài nguyên của tệp JAR nằm trong thư mục WEB-INF / lib, không có tệp nào khác có trong thư mục WEB-INF phục vụ trực tiếp cho khách hàng bằng container. Vì vậy, ngoại trừ chỉ áp dụng cho: WAR> WEB-INF> lib> JARfile>resources
Basil Bourque

1
Rất tiếc, từ nhận xét của tôi ở trên, sự thay đổi đó câu cuối cùng để: file tĩnh có thể được phục vụ từ: WARfile> WEB-INF> lib> JARfile> META-INF> resources> yourStaticFilesGoHere .
Basil Bourque

@mwhs Tôi khuyên bạn nên sửa lại Câu trả lời của mình bằng phần Servlet 3 mới và gắn nhãn nội dung hiện tại của bạn là phần Servlet 2.
Basil Bourque

61

Khi bạn triển khai một ứng dụng web Java EE (có sử dụng các khung công tác hay không), cấu trúc của nó phải tuân theo một số yêu cầu / thông số kỹ thuật. Các thông số kỹ thuật đến từ:

  • Container servlet (ví dụ Tomcat)
  • API Servlet Java
  • Miền ứng dụng của bạn
  1. Yêu cầu bộ chứa Servlet
    Nếu bạn sử dụng Apache Tomcat, thư mục gốc của ứng dụng của bạn phải được đặt trong thư mục ứng dụng web. Điều đó có thể khác nếu bạn sử dụng một thùng chứa servlet hoặc máy chủ ứng dụng khác.

  2. Yêu cầu API của Servlet Java API API của Servlet
    Java nói rằng thư mục ứng dụng gốc của bạn phải có cấu trúc sau:

    ApplicationName
    |
    |--META-INF
    |--WEB-INF
          |_web.xml       <-- Here is the configuration file of your web app(where you define servlets, filters, listeners...)
          |_classes       <--Here goes all the classes of your webapp, following the package structure you defined. Only 
          |_lib           <--Here goes all the libraries (jars) your application need

Các yêu cầu này được xác định bởi API Java Servlet.

3. Miền ứng dụng của bạn
Bây giờ bạn đã tuân theo các yêu cầu của bộ chứa Servlet (hoặc máy chủ ứng dụng) và các yêu cầu API của Servlet Java, bạn có thể sắp xếp các phần khác của ứng dụng web dựa trên những gì bạn cần.
- Bạn có thể đặt tài nguyên của mình (tệp tin JSP, tệp văn bản thuần túy, tệp tập lệnh) vào thư mục gốc của ứng dụng. Nhưng sau đó, mọi người có thể truy cập chúng trực tiếp từ trình duyệt của họ, thay vì các yêu cầu của họ được xử lý bởi một số logic được cung cấp bởi ứng dụng của bạn. Vì vậy, để ngăn chặn tài nguyên của bạn được truy cập trực tiếp như vậy, bạn có thể đặt chúng vào thư mục WEB-INF, máy chủ chỉ có thể truy cập nội dung của chúng.
-Nếu bạn sử dụng một số khung, họ thường sử dụng các tệp cấu hình. Hầu hết các khung công tác này (struts, spring, hibernate) yêu cầu bạn đặt các tệp cấu hình của chúng trong đường dẫn lớp (thư mục "class").


12

Bạn nên đặt WEB-INF vào bất kỳ trang nào hoặc một phần trang nào mà bạn không muốn công khai. Thông thường, JSP hoặc facelets được tìm thấy bên ngoài WEB-INF, nhưng trong trường hợp này chúng có thể dễ dàng truy cập cho bất kỳ người dùng nào. Trong trường hợp bạn có một số hạn chế ủy quyền, WEB-INF có thể được sử dụng cho điều đó.

WEB-INF / lib có thể chứa các thư viện bên thứ 3 mà bạn không muốn đóng gói ở cấp hệ thống (JAR có thể có sẵn cho tất cả các ứng dụng đang chạy trên máy chủ của bạn), nhưng chỉ dành cho ứng dụng cụ thể này.

Nói chung, nhiều tệp cấu hình cũng đi vào WEB-INF.

Đối với WEB-INF / class - nó tồn tại trong bất kỳ ứng dụng web nào, bởi vì đó là thư mục chứa tất cả các nguồn được biên dịch (không phải JARS, mà là các tệp .java do bạn tự viết).


4

Công ước này được tuân theo vì lý do bảo mật. Ví dụ: nếu người không được ủy quyền được phép truy cập tệp gốc root trực tiếp từ URL thì họ có thể điều hướng qua toàn bộ ứng dụng mà không cần bất kỳ xác thực nào và họ có thể truy cập tất cả dữ liệu được bảo mật.


Không phải tệp jsp vẫn tìm phiên của yêu cầu? Và nếu không tìm thấy, nó sẽ không hiển thị một số phần của trang web.
phân tích cú pháp

3

Có một quy ước (không cần thiết) về việc đặt các trang jsp trong thư mục WEB-INF để chúng không thể được liên kết sâu hoặc đánh dấu vào. Bằng cách này, tất cả các yêu cầu đến trang jsp phải được chuyển qua ứng dụng của chúng tôi, để trải nghiệm người dùng được đảm bảo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.