您好,登錄后才能下訂單哦!
這篇“java重定向和轉(zhuǎn)發(fā)的區(qū)別是什么”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“java重定向和轉(zhuǎn)發(fā)的區(qū)別是什么”文章吧。
定義
首先來看兩者的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;
重定向是向客戶端發(fā)送一個(gè)指定URL的臨時(shí)重定向的響應(yīng)。
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);
轉(zhuǎn)發(fā),則是將一個(gè)請(qǐng)求轉(zhuǎn)到服務(wù)器的另一個(gè)資源。在處理完初步請(qǐng)求另外的資源之后生成響應(yīng)。
定義基本說明了轉(zhuǎn)發(fā)操作為何可以保持request內(nèi)的parameter,attribute這些值都可以保留,而重定向操作卻會(huì)丟棄的原因:
轉(zhuǎn)發(fā)是在服務(wù)端完成的,并沒有經(jīng)過客戶端
轉(zhuǎn)發(fā)整個(gè)操作完成后才生成響應(yīng)
重定向是服務(wù)端向客戶端發(fā)送指定的URL
重定向是在客戶端完成的
我們?cè)賮砜碩omcat內(nèi)部,對(duì)于兩者是怎樣一種實(shí)現(xiàn)方式。
2. 容器實(shí)現(xiàn)
我們?cè)趕ervlet內(nèi)部一般對(duì)于這兩者的使用形式也相當(dāng)直觀,例如對(duì)于hello.jsp的請(qǐng)求:
sendRedirct方法
response.sendRedirect("/hello.jsp");
此時(shí),內(nèi)部的處理方式如下:
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狀態(tài)碼以及Location和對(duì)應(yīng)的url
setHeader("Location", absolute);
} catch (IllegalArgumentException e) {
setStatus(SC_NOT_FOUND);
}}
即根據(jù)Location,瀏覽器最終再發(fā)起新的請(qǐng)求,最終展現(xiàn)在瀏覽器中的即為新請(qǐng)求的URL,也就是大家常說的重定向會(huì)顯示最終的URL。
有上這些并不能造成重定向操作將之前request中已經(jīng)綁定的一系列parameter和attribute丟掉。最根本的原因是一個(gè)請(qǐng)求完整處理完成之后,整個(gè)請(qǐng)求會(huì)有一個(gè)release的過程,即CoyoteAdapter的service方法執(zhí)行完的finally塊中執(zhí)行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();
}
我們看到用于存儲(chǔ)setAttribute方法設(shè)置的和setParameter方法設(shè)置的數(shù)據(jù)在這里都clear掉了。這也是重定向不能夠保留數(shù)據(jù)的真正原因。
forward方法
forward方法一般使用如下:
request.getRequestDispatcher("/hello.jsp").forward(request, response);
forward方法內(nèi)部最終會(huì)調(diào)用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); //進(jìn)行第二個(gè)資源的請(qǐng)求
}
}
第二個(gè)資源的請(qǐng)求處理與一般的請(qǐng)求處理類似,只是在第一個(gè)請(qǐng)求之上,并沒有返回響應(yīng)時(shí)繼續(xù)發(fā)起第二個(gè)請(qǐng)求,此時(shí)第一個(gè)請(qǐng)求的各類參數(shù)會(huì)繼續(xù)向后傳遞,最終數(shù)據(jù)全部處理完成之后,整個(gè)響應(yīng)發(fā)送回客戶端。此時(shí)上面的release流程也依然會(huì)走,但并沒有什么影響,畢竟第二個(gè)資源已經(jīng)請(qǐng)求處理完成。
而由于瀏覽器發(fā)請(qǐng)求的時(shí)候是一個(gè)固定的URL,整個(gè)重定向是服務(wù)端內(nèi)部進(jìn)行的,瀏覽器并沒有感知到,因此也不會(huì)顯示出來。
以上就是關(guān)于“java重定向和轉(zhuǎn)發(fā)的區(qū)別是什么”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。