2009-11-13 38 views
11

我一直在我正在構建的web應用程序中混用JSP和Servlet,我開始發現我的更復雜的JSP最終包含了大量的代碼,它們面對所有的MVC課程被打入了我。我知道我可以通過轉發到JSP來做到這一點,但這似乎是一個愚蠢的黑客攻擊。是否可以使用JSP作爲servlet的模板?

我想要做的是使用一個servlet來處理,然後發送一組值到JSP來呈現HTML並返回響應。沿着線的東西:

public class MyServlet extends HttpServlet { 
public void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws IOException { 

     // ... Do some processing 

     resp.getWriter.print(renderJSP("mypage.jsp", values)); 

    } 

} 

我一直關注着Sun的文檔,發現這個:http://java.sun.com/developer/technicalArticles/javaserverpages/servlets_jsp/ 這似乎是JSP Model 2架構是我想要實現什麼,但我不能找到一個例子人們如何設置它。出於技術原因,我不能使用Struts等更高級的模板框架之一。

這是可能的還是一個失敗的原因?

+2

「出於技術原因,我不能使用更高級的模板框架之一,比如Struts。」 - 所以你將基本上重新實現它只是爲了你的應用程序... – Nate 2009-11-13 20:31:39

+0

我知道這是一個天真的聲明,但這真的不覺得我正在重塑一個完整的框架。我只是在尋找一種將兩種現有技術結合在一起的方式,在我看來,這是一個非常明顯的用例。 – 2009-11-13 22:34:52

回答

9

將對象放入請求中,將請求轉發給jsp頁面,然後使用jsp中的對象來呈現響應。

在你的servlet,

MyObject obj = ... //build somehow 
request.setAttribute("myObject", obj); 
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/my.jsp"); 
rd.forward(request, response); 

如果你的JSP的結果不應直接從你應該把它藏在它只能通過向前指令訪問的WEB-INF目錄中的URL訪問。

然後在你的JSP可以有,

<% MyObject obj = (MyObject) request.getAttribute("myObject"); %> 

檢索對象,並用它作爲必要的。

正如其他人所建議的,最終學習使用JSTL以及可能是一個像Spring MVC這樣的MVC框架將是一個不錯的主意。該教程可以找到here

+0

rd.forward是否將302發送回客戶端,還是在服務器端處理?我可能會讓我的術語感到困惑。 – 2009-11-13 22:36:36

+0

@Sean Lynch - 轉發目錄是服務器端。這就是爲什麼您可以使用它訪問WEB-INF目錄內的JSP頁面的原因。 – 2009-11-17 19:01:51

4

您描述了轉發到JSP作爲黑客,但實際上,這正是MVC框架(Spring MVC和Struts,至少)所做的。

「模型」是servlet填充的請求屬性;那麼JSP只是檢索它們來顯示。你可以像Spring MVC那樣將它包裝在「ModelAndView」中,但它確實是關於它的。

您可以在JSP上獲得更復雜的內容,當然也可以解析請求參數,會話屬性或servlet上下文(「全局」)屬性。我發現,一般來說,讓前端控制器/ servlet將所有這些請求屬性編組並將其從頁面中提取出來會更簡潔。如果您使用的是JSTL,請求和會話之間的區別可能更加模糊。在Request/Response/Session

+0

絕對如此。我已經使用Spring完成了大約4個體面大小的Web應用程序,這絕對不是黑客,servlet(或者在春天,控制器)爲視圖設置所有數據,並且JSP僅包含用於顯示提供給它由控制器。它工作的很好,而且很容易維護,你一定要走這條路,它不是黑客。 – Zoidberg 2009-11-13 20:29:41

5

把Java對象和在servlet使用javax.servlet.RequestDispatcher,類似的東西:

RequestDispatcher dispatcher = request.getRequestDispatcher("/test.jsp"); 
dispatcher.forward(request,response); 

遠期是服務器端和目標的servlet/JSP接收相同請求/響應對象作爲原始servlet/JSP。因此,您可以使用request.setAttribute()在它們之間傳遞數據。

另一種選擇是使用response.sendRedirect(String location)其是客戶端(此方法發送一個臨時重定向響應於客戶端),以使位置URL接收來自客戶端的新請求,並傳遞數據是唯一的方法通過會話或使用網絡參數(url?name = value)。

這基本上是MVC框架所做的(不,它不是黑客)。

+0

Dispatcher.forward()是否實際發送一個302到客戶端,或者它處理所有服務器端?我想我可能會讓我的HTML術語超載。 – 2009-11-13 23:36:34

+0

@Sean,所有服務器端。 – 2009-11-14 00:54:33

+0

我已經更新了我的答案,涵蓋了兩種情況(服務器端和客戶端) – 2009-11-14 07:45:24

相關問題