Servlet之间的跳转
Servlet之間的跳轉(zhuǎn)
1. 轉(zhuǎn)向(Forward)
轉(zhuǎn)向(forward)是通過(guò)RequestDispatcher對(duì)象的forward(HttpServletRequest request, HttpServletResponse response)來(lái)實(shí)現(xiàn)的。示例如下:
?| RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet/LifeCycleServlet"); dispatcher.forward(request, response); |
getRequestDispatcher()方法的參數(shù)必須以“/”開(kāi)始,“/”表示本W(wǎng)eb應(yīng)用程序的根目錄。如上例中,
表示要跳轉(zhuǎn)的地址為http://localhost:8080/servlet/servlet/LifeCycleServlet。
forward是最常用的方式,在Structs等MVC框架中,都是用Servlet來(lái)處理用戶請(qǐng)求,把結(jié)果通過(guò)request.setAttribute()放到request中,
然后forward到JSP中顯示。
當(dāng)執(zhí)行forward方法時(shí),不能有任何輸出到達(dá)客戶端,否則會(huì)拋出異常,也就是說(shuō),在forward之前,不要使用out.println()語(yǔ)句向客戶端輸出。
?
| public void doGet(HttpServletRequest request, HttpServletResponse response) ????????throws ServletException, IOException { ????String destination = request.getParameter("destination"); ?????? ????if("file".equals(destination)){ ????????RequestDispatcher d = request.getRequestDispatcher("/WEB-INF/web.xml"); ????????d.forward(request, response); ????}else if("jsp".equals(destination)){ ????????request.setAttribute("date", new Date()); //attributes are reset between requests. ????????RequestDispatcher dispatcher = request.getRequestDispatcher("/forward.jsp"); ????????dispatcher.forward(request, response); ????}else if("servlet".equals(destination)){ ????????RequestDispatcher disp = request.getRequestDispatcher("/servlet/LifeCycleServlet"); ????????disp.forward(request, response); ????}else{ ????????response.setCharacterEncoding("UTF-8"); ????????response.getWriter().println("缺少參數(shù)。用法:"+request.getRequestURI()+"?destination=jsp或者file或者servlet"); ????} } |
2. 重定向(Redirect)
重定向是通過(guò)服務(wù)器端返回狀態(tài)碼來(lái)實(shí)現(xiàn)的。301,302都表示重定向,區(qū)別是301表示永久性重定向,302表示臨時(shí)性重定向。通過(guò)sendRedirect(String location)就可以實(shí)現(xiàn)重定向,下面是例子。本例子主要實(shí)現(xiàn)了Servlet來(lái)實(shí)現(xiàn)文件下載并統(tǒng)計(jì)下載次數(shù)。要下載的文件以及下載次數(shù)都保存在一個(gè)Map中。主要思路是:首先加載頁(yè)面表單,當(dāng)用戶點(diǎn)擊下載鏈接時(shí),客戶端發(fā)起請(qǐng)求,運(yùn)行doGet里的if判斷,實(shí)現(xiàn)重定向。
重定向和跳轉(zhuǎn)的區(qū)別:跳轉(zhuǎn)是在服務(wù)器端實(shí)現(xiàn)的,客戶端瀏覽器并不知道該瀏覽動(dòng)作,而使用Redict跳轉(zhuǎn)時(shí),跳轉(zhuǎn)是在客戶端實(shí)現(xiàn)的,也就是說(shuō)客戶端瀏覽器實(shí)際上請(qǐng)求了2次服務(wù)器。
?| public class RedictServlet extends HttpServlet { ?? ????Map<String,Integer> map = new HashMap<String,Integer>(); //new一個(gè)Map ?? ????public void init() throws ServletException { //放在init中,加載servlet時(shí)運(yùn)行此方法,把文件內(nèi)容放到map中去 ????????map.put("/download/setup.exe", 0); ????????map.put("/download/application.zip", 0); ????????map.put("/download/01.mp3", 0); ????} ?? ????public void doGet(HttpServletRequest request, HttpServletResponse response) ????????????throws ServletException, IOException { ????????String filename = request.getParameter("filename"); ?????????? ????????if(filename!=null){ ????????????int hit = map.get(filename); //取下載次數(shù) ????????????map.put(filename, ++hit); //下載次數(shù)加1后保存 ????????????response.sendRedirect(request.getContextPath()+filename); //重定向到文件 ?????????????? ????????}else{ ????????????response.setCharacterEncoding("UTF-8"); ????????????PrintWriter out = response.getWriter(); ????????????response.setContentType("text/html"); ????????????out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); ????????????out.println("<HTML>"); ????????????out.println("? <HEAD><TITLE>文件下載</TITLE></HEAD>"); ????????????out.println("?? <link rel='stylesheet' type='text/css' href='../css/style.css'>"); ????????????out.println("? <BODY><br/>"); ?? ????????????out.println("<fieldset align=center style=width:90%><legend>文件下載</legend>"); //繪制頁(yè)面表單 ????????????out.println("<table width=100%>"); ????????????out.println("?? <tr>"); ????????????out.println("?????? <td><b>文件名"+"</b></td>"); ????????????out.println("?????? <td><b>下載次數(shù)</b></td>"); ????????????out.println("?????? <td><b>下載</b></td>"); ????????????out.println("?? </tr>"); ?????????????? ????????????for(Entry<String,Integer> entry: map.entrySet()){ //遍歷map的方法 ????????????????out.println("<tr>"); ????????????????out.println("?? <td>"+entry.getKey()+"</td>"); ????????????????out.println("?? <td>"+entry.getValue()+"</td>"); ????????????????out.println("?? <td><a href = '"+request.getRequestURI()+"?filename="+entry.getKey()+"'target = '_blank' onclick ='location = location;'>下載</a></td>"); //target='_blank'目標(biāo)地址在無(wú)標(biāo)題的新頁(yè)面中打開(kāi)。onclick ='location = location;'頁(yè)面刷新 ????????????????out.println("</tr>"); ????????????} ????????????out.println("</table>"); ????????????out.println("?? </legend>"); ????????????out.println("? </BODY>"); ????????????out.println("</HTML>"); ????????????out.flush(); ????????????out.close(); ????????} ?????????? ????} ?? ????public void destroy() { ????????super.destroy(); // Just puts "destroy" string in log ????????// Put your code here ????????map = null; ????} } |
結(jié)果圖:
總結(jié)
以上是生活随笔為你收集整理的Servlet之间的跳转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POI入门教程
- 下一篇: 服务器端使用sendRedirect跳转