• 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=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;
    	}
    }

     结果图:

    点击下载chrome浏览器就会自动下载

  • 相关阅读:
    Oracle时间日期操作
    c# 语音卡控制语音卡实现电话录音
    ORACLE日期时间函数大全
    oracle的表分区
    如何应付表数据过大的查询问题?(如何尽量避免大表关联)[转]
    优化SQL Server数据库
    oracle知识回顾
    增强现实 artoolkit
    高负载系统架构设计
    三套.net支持库
  • 原文地址:https://www.cnblogs.com/clara/p/2112732.html
Copyright © 2020-2023  润新知