• JavaWeb学习之HttpServletResponse


    HttpServletResponse

    在创建Servlet时会重写service()方法,或doGet()/doPost(),这些方法都需要传入两个参数,一个是代表请求的request,一个是代表响应的response。

    service方法中的response的类型是ServletResponse,而doGet/doPost方法中的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大。

    response的运行流程

    首先,客户端网页输入链接地址,发送请求,并被封装为Http请求。这个请求会被tomcat服务器接收传送到tomcat引擎,即tomcat内核。tomcat内核首先解析请求的资源,然后将请求的信息封装成request对象,与此同时创建一个response对象,然后创建servlet对象,最后调用service方法。服务器在web应用中去运行service方法。write()方法是将响应的内容写到response缓冲区中。服务器会自动监测到service方法中的内容是否写完,当service方法结束后,方法返回到tomcat内核去该response缓冲区去获取设置的内容。tomcat从response中获取设置的内容组装成一个Http响应,这里面包括响应行、响应头、响应体。最后将该Http响应返回到客户端解析Http响应显示页面。

    通过response设置响应行

    设置响应行的状态码

     setStatus(int  sc)

    例如:response.setStatus(404);   设置状态码

    通过response设置响应头

    addHead(String name,String value)

    addIntHead(String name,int value)

    addDateHead(String name,long date)

    setHead(String name,String value)

    setDateHead(String name,long date)

    setIntHead(String name,int value)

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoginServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		response.addHeader("name", "张三");
    		response.addIntHeader("age", 18);
    		response.addDateHeader("birthday", 2000000000L);
    		response.setIntHeader("age", 30);
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }
    

    重定向需要:

    1、状态码:302

    2、响应头:Location  代表重定向地址

    package com.oracle.demo02;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class servlet01 extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 原生代码
    		// 没有响应,告知客户端去重定向到servlet02
    		// 1、设置状态码302
    		// response.setStatus(302);
    		// 2、设置响应头Location
    		// response.setHeader("Location", "servlet02");
    		// 开发中常用的重定向方法
    		response.sendRedirect("servlet02");
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }
    

    通过response设置响应体

    (1)响应体设置文本

    PrintWriter 的getWriter()获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回到浏览器端。

     中文乱码的问题

    response缓冲区的默认编码时ISO8859-1,此码表中没有中文,可以通过response的setCharacterEncoding(String charset)设置response的编码格式,如UTF-8

    response.setCharacterEncoding("UTF-8");

    在将response缓冲区的编码设置为UTF-8,但是浏览器的默认编码是本地系统的编码,由于我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以手动修改浏览器的编码为UTF-8.

    在开发中,通常在代码中指定浏览器解析页面的编码方式,通过response的setContentType(String type)方法指定页面解析的编码为UTF-8

    response.setContentType("text/html;charset=UTF-8");

    这条代码中隐含有设置response缓冲区的编码为UTF-8的功能。

    package com.oracle.demo01;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Servlet01 extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 设置response缓冲区中的编码方式
    		// response.setCharacterEncoding("UTF-8");
    		//response.setHeader("Content-type", "text/html;charset=UTF-8");
    		//解决响应的中中文乱码问题
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().write("你好");
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }

    (2)响应头设置字节

    ServletOutputStream   getOutputStream()获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由tomcat服务器将字节内容组成Http响应返回给浏览器。

    package com.oracle.demo01;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Servlet02 extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 使用response获得字节输出流
    		ServletOutputStream out = response.getOutputStream();
    		// 获得服务器上的图片
    		String path = this.getServletContext().getRealPath("aaa.jpg");
    		FileInputStream in = new FileInputStream(path);
    		int len = 0;
    		byte[] bytes = new byte[1024];
    		while ((len = in.read()) != -1) {
    			out.write(bytes, 0, len);
    		}
    		in.close();
    		out.close();
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }
    

    文件的下载

    文件的下载就是将文件从服务器拷贝到浏览器端。运用IO技术将服务器端的文件通过InputStream读取到,然后通过ServletOutputStream写入到response缓冲区中。

    上述代码可以将图片从服务器端传输到浏览器,但浏览器直接解析图片显示在页面上, 而不是提供下载,我们需要设置两个响应头,告知浏览器文件的类型和文件的打开方 式。

    1)告知浏览器文件的类型:response.setContentType(文件的MIME类型);

    2)告示浏览器文件的打开方式是下载response.setHeader("Content-Disposition","attachment;filename=文件名称");

    package com.oracle.demo01;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import sun.misc.BASE64Encoder;
    
    public class DownloadServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		// 获取要下载的文件名称
    		String filename = request.getParameter("filename");
    		// 解决中文乱码的问题
    		filename = new String(filename.getBytes("ISO-8859-1"), "UTF-8");
    		// 获得请求头中的User—Agent
    		String agent = request.getHeader("User-Agent");
    		//根据不同的浏览器进行解码
    		String filenameEncoding="";
    		if (agent.contains("MSIE")) {
    			// IE浏览器
    			filenameEncoding = URLEncoder.encode(filename, "utf-8");
    			filenameEncoding = filename.replace("+", " ");
    		} else if (agent.contains("Firefox")) {
    			// 火狐浏览器
    			BASE64Encoder base64Encoder = new BASE64Encoder();
    			filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
    		} else {
    			// 其它浏览器
    			filenameEncoding = URLEncoder.encode(filename, "utf-8");
    		}
    		// 要下载的这个文件类型--客户端通过文件的MIME类型去区分类型
    		response.setContentType(this.getServletContext().getMimeType(filename));
    		// 告诉客户端该文件不是直接解析,而是以附件的形式打开(下载)
    		response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoding);
    		// 获取下载的文件在服务器上的绝对路径
    		String path = this.getServletContext().getRealPath("download/" + filename);
    		// 获取输出流,通过response获得输出流,用于向客户端写内容
    		ServletOutputStream out = response.getOutputStream();
    		// 获取该文件的输入流
    		FileInputStream in = new FileInputStream(path);
    		// 文件拷贝的模板
    		int len = 0;
    		byte[] bytes = new byte[1024];
    		while ((len = in.read()) != -1) {
    			out.write(bytes, 0, len);
    		}
    		in.close();
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    }
    

      

  • 相关阅读:
    软件项目的需求变更管理
    便利店规模经营的条件是什么?
    店长不得不知的七类非语言沟通方式
    软件项目管理的十大定律
    零售业精细化管理必须做好三大源头
    超市货架陈列暗藏玄机 最新鲜的藏在最后面
    超市陈列原则
    店铺中货架的装修设计要点
    《图解Java多线程设计模式》之五:Balking 模式
    《图解Java多线程设计模式》之三:Immutable 模式
  • 原文地址:https://www.cnblogs.com/Java-125/p/9000965.html
Copyright © 2020-2023  润新知