2008-09-23 24 views
39

Tôi muốn biết nếu có một số cách để chia sẻ một biến hoặc một đối tượng giữa hai hoặc nhiều Servlets, tôi có nghĩa là một số "tiêu chuẩn" cách. Tôi cho rằng đây không phải là một thực hành tốt nhưng là một cách dễ dàng hơn để xây dựng một nguyên mẫu.Làm thế nào tôi có thể chia sẻ một biến hoặc đối tượng giữa hai hoặc nhiều Servlets?

Tôi không biết nếu nó phụ thuộc vào các công nghệ được sử dụng, nhưng tôi sẽ sử dụng Tomcat 5,5


tôi muốn chia sẻ một Vector của các đối tượng của một lớp đơn giản (chỉ cần thuộc tính công cộng, chuỗi, ints, v.v.) Ý định của tôi là có một dữ liệu tĩnh như trong một DB, rõ ràng là nó sẽ bị mất khi Tomcat bị dừng lại. (nó chỉ để thử nghiệm)

+0

Phần lớn phụ thuộc vào loại đối tượng/biến đó là gì. Biến có thuộc về một lớp không và bạn chỉ muốn truy cập? Nó là một hằng số? Một ví dụ sẽ được tốt đẹp. – Swati

+0

Tôi muốn điều này sẽ giúp :) –

Trả lời

74

Tôi nghĩ rằng những gì bạn đang tìm kiếm ở đây là yêu cầu, dữ liệu phiên hoặc ứng dụng.

Trong một servlet bạn có thể thêm một đối tượng như một thuộc tính để yêu cầu đối tượng, đối tượng session hoặc bối cảnh servlet đối tượng:

protected void doGet(HttpServletRequest request, HttpServletResponse response) { 
    String shared = "shared"; 
    request.setAttribute("sharedId", shared); // add to request 
    request.getSession().setAttribute("sharedId", shared); // add to session 
    this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context 
    request.getRequestDispatcher("/URLofOtherServlet").forward(request, response); 
} 

Nếu bạn đặt nó trong đối tượng yêu cầu nó sẽ có sẵn cho các servlet mà được chuyển tiếp đến cho đến khi yêu cầu được hoàn thành:

request.getAttribute("sharedId"); 

Nếu bạn đặt nó trong phiên nó sẽ có sẵn cho tất cả các servlets đi về phía trước nhưng giá trị sẽ được gắn với người sử dụng:

request.getSession().getAttribute("sharedId"); 

Cho đến khi phiên hết hạn dựa trên sự không hoạt động của người dùng.

là thiết lập lại bằng bạn:

request.getSession().invalidate(); 

Hoặc một servlet loại bỏ nó khỏi phạm vi:

request.getSession().removeAttribute("sharedId"); 

Nếu bạn đặt nó trong bối cảnh servlet nó sẽ có sẵn khi các ứng dụng đang chạy:

this.getServletConfig().getServletContext().getAttribute("sharedId"); 

Cho đến khi bạn xóa:

this.getServletConfig().getServletContext().removeAttribute("sharedId"); 
+0

Bạn có thể mở rộng câu trả lời cho ServletContext không? –

+1

Hoặc 'getServletContext()' thay vì 'this.getServletConfig(). GetServletContext()' ... –

+0

@William Làm thế nào tôi có thể truyền cái gì khác ngoài String f.e. một đối tượng từ một lớp tôi tự tạo ra? – Stanko

1

Bạn không thể chỉ đặt đối tượng trong HttpSession và sau đó tham chiếu đến nó bằng tên thuộc tính của nó trong mỗi servlet?

ví dụ:

getSession().setAttribute("thing", object); 

... sau đó trong servlet khác:

Object obj = getSession.getAttribute("thing"); 
+0

không đối tượng phải được serializable cho điều này để làm việc? – Jus12

7

Phụ thuộc vào phạm vi của mục đích sử dụng của dữ liệu.

Nếu dữ liệu chỉ được sử dụng trên cơ sở mỗi người dùng, như thông tin đăng nhập của người dùng, số lần truy cập trang, v.v. sử dụng đối tượng phiên (httpServletRequest.getSession(). Get/setAttribute (String [, Object]))

Nếu đó là cùng một dữ liệu trên nhiều người dùng (tổng số lần truy cập trang web, chuỗi công việc, v.v.) sử dụng thuộc tính ServletContext. servlet.getServletCongfig(). getServletContext(). get/setAttribute (String [, Object])). Điều này sẽ chỉ hoạt động trong cùng một tập tin chiến tranh/ứng dụng web. Lưu ý rằng dữ liệu này không được duy trì trong quá trình khởi động lại.

+0

Sử dụng ServletContext có thể dễ dàng khiến bạn gặp rắc rối nếu bạn không cẩn thận. Ví dụ, bạn không thể sử dụng nó để thực hiện đếm số lần truy cập trang theo cách ngây thơ: nhận số lần truy cập trang hiện tại từ ngữ cảnh, tăng nó và đặt giá trị cho ngữ cảnh. Đa luồng giết chết giải pháp đó. – JavadocMD

+0

Meta critque - câu hỏi đặt ra là yêu cầu chức năng lưu trữ dữ liệu sao lưu phải được xử lý thông qua giao dịch. Khiếu nại về ACID sẽ dẫn đến việc sử dụng dịch vụ dữ liệu ACID. ServletContext và Session vi phạm tất cả ACID theo một cách nào đó. – shemnon

8

Đặt nó ở một trong 3 phạm vi khác nhau.

yêu cầu - kéo dài tuổi thọ của yêu cầu

phiên - kéo dài tuổi thọ của session của user

ứng dụng - kéo dài cho đến Nhờ có chương trình tắt

Bạn có thể truy cập vào tất cả các phạm vi thông qua biến HttpServletRequest đó là được chuyển đến các phương pháp mở rộng từ HttpServlet class

2

Tùy chọn khác, chia sẻ dữ liệu theo ngữ cảnh ...

share-data-between-servlets-on-tomcat

<Context path="/myApp1" docBase="myApp1" crossContext="true"/> 
    <Context path="/myApp2" docBase="myApp2" crossContext="true"/> 

On myApp1:

ServletContext sc = getServletContext(); 
    sc.setAttribute("attribute", "value"); 

On myApp2:

ServletContext sc = getServletContext("/myApp1"); 
    String anwser = (String)sc.getAttribute("attribute"); 
0

Đây là cách tôi làm điều này với Jetty.

https://stackoverflow.com/a/46968645/1287091

Sử dụng bối cảnh máy chủ, nơi một singleton được ghi vào quá trình khởi động của một máy chủ Jetty nhúng và chia sẻ giữa tất cả các ứng dụng web cho tuổi thọ của máy chủ. Cũng có thể được sử dụng để chia sẻ các đối tượng/dữ liệu giữa các ứng dụng web giả sử chỉ có một người viết trong ngữ cảnh - nếu không bạn cần phải chú ý đến sự đồng thời.

Các vấn đề liên quan