Servlet之间的跳转

Servlet之间的跳转

1. 转向(Forward)

  转向(forward)是通过RequestDispatcher对象的forward(HttpServletRequest request, HttpServletResponse response)来实现的。示例如下:

?
RequestDispatcher dispatcher = request.getRequestDispatcher( "/servlet/LifeCycleServlet" );
dispatcher.forward(request, response);    

getRequestDispatcher()方法的参数必须以“/”开始,“/”表示本Web应用程序的根目录。如上例中,

表示要跳转的地址为http://localhost:8080/servlet/servlet/LifeCycleServlet。

forward是最常用的方式,在Structs等MVC框架中,都是用Servlet来处理用户请求,把结果通过request.setAttribute()放到request中,

然后forward到JSP中显示。

当执行forward方法时,不能有任何输出到达客户端,否则会抛出异常,也就是说,在forward之前,不要使用out.println()语句向客户端输出。

?
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( "缺少参数。用法:" +request.getRequestURI()+ "?destination=jsp或者file或者servlet" );
     }
}


2. 重定向(Redirect)

  重定向是通过服务器端返回状态码来实现的。301,302都表示重定向,区别是301表示永久性重定向,302表示临时性重定向。通过sendRedirect(String location)就可以实现重定向,下面是例子。本例子主要实现了Servlet来实现文件下载并统计下载次数。要下载的文件以及下载次数都保存在一个Map中。主要思路是:首先加载页面表单,当用户点击下载链接时,客户端发起请求,运行doGet里的if判断,实现重定向。

  重定向和跳转的区别:跳转是在服务器端实现的,客户端浏览器并不知道该浏览动作,而使用Redict跳转时,跳转是在客户端实现的,也就是说客户端浏览器实际上请求了2次服务器。

?
public class RedictServlet extends HttpServlet {
  
     Map<String,Integer> map = new HashMap<String,Integer>(); //new一个Map
  
     public void init() throws ServletException {   //放在init中,加载servlet时运行此方法,把文件内容放到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);   //取下载次数
             map.put(filename, ++hit);   //下载次数加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>" );   //绘制页面表单
             out.println( "<table width=100%>" );
             out.println( "   <tr>" );
             out.println( "       <td><b>文件名" + "</b></td>" );
             out.println( "       <td><b>下载次数</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'目标地址在无标题的新页面中打开。onclick ='location = location;'页面刷新
                 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 ;
     }
}

 结果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值