1. SpringMVC與Servlet的關系
SpringMVC框架是建立在Servlet之上的,提供各種功能,各種封裝,各種方便的同時,它一點兒也沒有限制Servlet,我們完全可以在SpringMVC的controller中,完全按照Servlet的方式來寫代碼,同時還享受SpringMVC提供的方便。所以我們完全沒有理由再使用Servlet了。
2. SpringMVC 返回 html 視圖頁面
SpringMVC的controller一般我們可以配置返回:jsp, json, Velocity, FreeMarker, XML, PDF, Excel等等視圖。那么如何返回到 html 視圖呢?當然一般我們沒有這種必要,但是有一些奇葩場景還是存在的。
上面我們知道SpringMVC沒有限制對Servlet有任何的限制,我們完全可以在controller中寫servlet形式的代碼,而我們知道,我們在Servlet中可以通過 轉發和重定向到 html 類型的頁面,所以我們也可以在SpringMVC的controller中利用request的轉發和response的重定向到html頁面,也可以利用PrintWriter直接輸出html字符流。這些Servlet中的用法,我們完全可以在SpringMVC中使用。
@RequestMapping(value="/htmlView") public void htmlView(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // ... // request.getRequestDispatcher("index.html").forward(request, response); response.sendRedirect("http://www.baidu.com"); }
@RequestMapping(value="/getPage") public void writeSubmitHtml(Reader reader, Writer writer, HttpSession session) throws IOException { User user = (User) session.getAttribute(ConstantConfig.LONGIN_USER); StringBuffer sbHtml = new StringBuffer(); sbHtml.append("<!doctype html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); sbHtml.append("<title>支付寶即時到賬交易接口</title></head><body>"+ user.getNo() +"</body></html>"); writer.write(sbHtml.toString()); }
上面分別使用 request的轉發和response的重定向,以及PrintWriter直接輸出html字符流,到達springMVC返回 html 類型視圖的目的。
3. Servlet重定向與轉發
下面的文字,轉自:http://blog.sina.com.cn/s/blog_7ffb8dd501013tbg.html
一、請求轉發與響應重定向的種類
有兩種方式獲得Servlet 轉發對象(RequestDispatcher):
一種是通過HttpServletRequest的getRequestDispatcher()方法獲得,
一種是通過ServletContext的getRequestDispatcher()方法獲得。
Servlet 重定向的方法只有一種:HttpServletResponse的sendRedirect()方法。
這三個方法的參數都是一個URL形式的字符串,但在使用相對路徑或絕對路徑上有所區別。
二、請求轉發與響應重定向中路徑參數區別
假設通過http://localhost/myApp/cool/bar.do 請求到達該方法所屬的Servlet。
1、響應重定向 ◆ HttpServletResponse.sendRedirect(String)
參數可以指定為相對路徑、絕對路徑或其它Web應用。
i:相對路徑:response.sendRedirect("foo/stuff.do"),容器相對於原來請求URL的目錄加參數來生成完整的URL——http://localhost/myApp/cool/foo/stuff.do。
ii:絕對路徑:response.sendRedirect("/foo/stuff.do"),容器相對於Web應用本身加參數建立完整的URL,這是因為重定向response.sendRedirect("")是服務器向客戶端發送一個請求頭信息,由客戶端再請求一次服務器,請求是在服務器外進行的,
所以完整的url是——http://localhost/foo/stuff.do。
iii:其它Web應用:response.sendRedirect("http://www.xxx.com ")容器直接定向到該URL。
2、請求轉發 ◆HttpServletRequest.getRequestDispatcher(String)
參數可以指定為相對路徑或絕對路徑。
i:相對路徑情況下生成的完整URL與重定向方法相同。
ii:絕對路徑與Servlet重定向不同,容器將相對於Web應用的根目錄加參數生成完整的URL(即“/”根路徑就是相對於虛擬路徑)這是因為轉發是在服務器內部進行的,寫絕對路徑/開頭指的是當前的Web應用程序。即:
request.getRequestDispatcher("/foo/stuff.do")生成的URL是http://localhost/myApp/foo/stuff.do 。
3、 ◆ ServletContext.getRequestDispatcher(String)
參數只能指定為絕對路徑,生成的完整URL與HttpServletRequest.getRequestDispatcher(String)相同。
##################################
同理:
JSP 提交表單給 Servlet 路徑問題
例如在web.xml中注冊如下的servlet:
<servlet>
<servlet-name>addStudent</servlet-name>
<servlet-class>org.mytest.addStudent</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>addStudent</servlet-name>
<url-pattern>/servlet/addStudent</url-pattern>
</servlet-mapping>
假如說,你工程名字為HibernateApp3,JSP頁面提交表單給servlet時有兩種寫法:
1.相對路徑: <form action=servlet/addStudent method=post>...</form>
2. 絕對路徑: <form action="/HibernateApp3/servlet/addStudent" method=post>...</form>
或者 <form action="<%=request.getContextPath() %>/servlet/addStudent" method=post>...</form>
注意:/代表根目錄,如果路徑是使用/開頭,Tomcat就是webApp那個目錄,如果你不是/開頭代表你從當前工程的目錄開始,例如:webApp/HibernateApp3/
這一點非常重要,很多提交表單時發生的錯誤都是因為提交路徑出錯造成的。
附、<a href>的路徑如果是"/"開頭,則表示相對於主機,如果不是則表示相對於當前請求
綜上所述:
這里最最關鍵的要能清楚發出請求目的資源的請求是在服務器內部還是服務器外部:內部時,“/”就是項目的虛擬目錄;外部時,“/”就是代表主機的根目錄
注意:response.sendRedirect 是先返回瀏覽器,再由瀏覽器重新定向到某個頁面,所以他可以重定向到任何頁面,包括其它站點的頁面,比如從我們自己的網站,重定向到http://www.baidu.com 都是可以的,這是有其原理決定的。