您好,登錄后才能下訂單哦!
這篇“java重定向和轉發的區別是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“java重定向和轉發的區別是什么”文章吧。
定義
首先來看兩者的javadoc。
sendRedirect()
/**
* Sends a temporary redirect response to the client using the
specified redirect location URL. This method can accept relative URLs; the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading '/' the container interprets it as relative to the current request URI.
If the location is relative with a leading '/' the container interprets it as relative to the servlet container root.
*/
public void sendRedirect(String location) throws IOException;
重定向是向客戶端發送一個指定URL的臨時重定向的響應。
forward()
/**
* Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server. This method allows one servlet to do preliminary processing of a request and another resource to generate the response.
The request and response parameters must be either the same objects as were passed to the calling servlet's service method .
*/
public void forward(ServletRequest request, ServletResponse response);
轉發,則是將一個請求轉到服務器的另一個資源。在處理完初步請求另外的資源之后生成響應。
定義基本說明了轉發操作為何可以保持request內的parameter,attribute這些值都可以保留,而重定向操作卻會丟棄的原因:
轉發是在服務端完成的,并沒有經過客戶端
轉發整個操作完成后才生成響應
重定向是服務端向客戶端發送指定的URL
重定向是在客戶端完成的
我們再來看Tomcat內部,對于兩者是怎樣一種實現方式。
2. 容器實現
我們在servlet內部一般對于這兩者的使用形式也相當直觀,例如對于hello.jsp的請求:
sendRedirct方法
response.sendRedirect("/hello.jsp");
此時,內部的處理方式如下:
public void sendRedirect(String location, int status) throws IOException {
// Generate a temporary redirect to the specified location
try {
String absolute = toAbsolute(location);
setStatus(status); //這里,重定向是返回302狀態碼以及Location和對應的url
setHeader("Location", absolute);
} catch (IllegalArgumentException e) {
setStatus(SC_NOT_FOUND);
}}
即根據Location,瀏覽器最終再發起新的請求,最終展現在瀏覽器中的即為新請求的URL,也就是大家常說的重定向會顯示最終的URL。
有上這些并不能造成重定向操作將之前request中已經綁定的一系列parameter和attribute丟掉。最根本的原因是一個請求完整處理完成之后,整個請求會有一個release的過程,即CoyoteAdapter的service方法執行完的finally塊中執行release這一過程,基本如下:
finally {
if (!comet && !async || error.get()) {
request.recycle(); //注意這兩行代碼
response.recycle();
}
}
具體request的recycle部分代碼如下:
/**
* Release all object references, and initialize instance variables, in preparation for reuse of this object.
*/
public void recycle() {
attributes.clear();
requestedSessionId = null;
requestedSessionURL = false;
parameterMap.clear();
pathParameters.clear();
}
我們看到用于存儲setAttribute方法設置的和setParameter方法設置的數據在這里都clear掉了。這也是重定向不能夠保留數據的真正原因。
forward方法
forward方法一般使用如下:
request.getRequestDispatcher("/hello.jsp").forward(request, response);
forward方法內部最終會調用dispatcher的doForward方法
void doForward(ServletRequest request, ServletResponse response){
// Set up to handle the specified request and response
State state = new State(request, response, false);
wrapResponse(state);
ApplicationHttpRequest wrequest =
(ApplicationHttpRequest) wrapRequest(state);
String contextPath = context.getPath();
HttpServletRequest hrequest = state.hrequest;
if (hrequest.getAttribute(
RequestDispatcher.FORWARD_REQUEST_URI) == null) {
wrequest.setAttribute(RequestDispatcher.FORWARD_PATH_INFO,hrequest.getPathInfo());
wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING, hrequest.getQueryString());}
wrequest.setContextPath(contextPath);
wrequest.setRequestURI(requestURI);
wrequest.setServletPath(servletPath);
wrequest.setPathInfo(pathInfo);
if (queryString != null) {
wrequest.setQueryString(queryString);
wrequest.setQueryParams(queryString);
}
processRequest(request,response,state); //進行第二個資源的請求
}
}
第二個資源的請求處理與一般的請求處理類似,只是在第一個請求之上,并沒有返回響應時繼續發起第二個請求,此時第一個請求的各類參數會繼續向后傳遞,最終數據全部處理完成之后,整個響應發送回客戶端。此時上面的release流程也依然會走,但并沒有什么影響,畢竟第二個資源已經請求處理完成。
而由于瀏覽器發請求的時候是一個固定的URL,整個重定向是服務端內部進行的,瀏覽器并沒有感知到,因此也不會顯示出來。
以上就是關于“java重定向和轉發的區別是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。