本文共 5213 字,大约阅读时间需要 17 分钟。
到了这一节我们开始学习Response。
Response的作用是设置响应消息。
1. 设置响应行 1. 格式:HTTP/1.1 200 ok 2. 设置状态码:setStatus(int sc):如果不设置会自动根据情况返回2. 设置响应头:setHeader(String name, String value):可以自定义响应头,客户端可以收到3. 设置响应体: 1. 获取输出流 * 字符输出流:PrintWriter getWriter() * 字节输出流:ServletOutputStream getOutputStream() 2. 使用输出流,将数据输出到客户端浏览器
我们要学习一个新的概念:
重定向,即一种资源跳转的方式,前面我们讲过了转发,现在我们来比较一下二者:
- 重定向的特点:redirect 1. 地址栏发生变化 2. 重定向可以访问其他站点(服务器)的资源 3. 重定向是两次请求。不能使用request对象来共享数据
- 转发的特点:forward 4. 转发地址栏路径不变 5. 转发只能访问当前服务器下的资源 6. 转发是一次请求,可以使用request对象来共享数据
现在我们来实现一个重定向的例子来演示上面的特点:
@WebServlet("/demo")public class ServletDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { System.out.println("访问了demo"); req.setAttribute("aa","bb"); resp.sendRedirect("/demo2"); System.out.println(123); }}
@WebServlet("/demo2")public class ServletDemo2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("访问了demo2"); System.out.println(req.getAttribute("aa")); }}从结果来分析:
重定向地址栏发生了变化,且request共享的数据无法获取到,重定向两次请求可以通过F12抓包来看。上面这个例子没有体现可以访问外部资源的特点,可以将resp.sendRedirect("/demo2")改为resp.sendRedirect(“www.baidu.com”);来验证这里不做演示了,同时我们发现重定向发生在ServletDemo代码完全执行完后才发生
1. 相对路径:通过相对路径不可以确定唯一资源* 如:./index.html* 不以/开头,以.开头路径* 规则:找到当前资源和目标资源之间的相对位置关系 * ./:当前目录 * ../:后退一级目录2. 绝对路径:通过绝对路径可以确定唯一资源* 如:http://localhost:8080/jack/responseDemo2或者/jack/responseDemo2* 以/开头的路径* 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出 * 给客户端浏览器使用:需要加虚拟目录(项目的访问路径) * 建议虚拟目录动态获取:request.getContextPath() * ,
演示:
相对路径这里不展示。 绝对路径展示:Title 超链接
点击超链接:
下面我们来看一个Response流的示例: SevletDemo的doGet方法代码如下:PrintWriter writer = resp.getWriter();writer.write("Hello World! 你好
");
出现了乱码的现象:
将代码改为如下即可:resp.setCharacterEncoding("gbk");\\(将流的字符集改为gbk与浏览器一致,浏览器一般都是gbk编码格式)PrintWriter writer = resp.getWriter();writer.write("不过上面这个方法不是很通用,比如我们的浏览器采用的字符集不是gbk我们可以使用下面的方式:Hello World! 你好
");
resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); PrintWriter writer = resp.getWriter(); writer.write("Hello World! 你好
");
前面我们已经讲过了ServletContext对象了,这里再拓展一下:
1. 获取MIME类型: * MIME类型:在互联网通信过程中定义的一种文件数据类型 * 格式: 大类型/小类型 text/html image/jpeg * 获取:String getMimeType(String file) 2. 域对象:共享数据 1. setAttribute(String name,Object value) 2. getAttribute(String name) 3. removeAttribute(String name)3. 获取文件的真实(服务器)路径 1. 方法:String getRealPath(String path) 三个例子: String b = context.getRealPath("/b.txt");//web目录下资源访问 System.out.println(b); String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问 System.out.println(c); String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问 System.out.println(a);
对1,3做个演示:
ServletContext servletContext = req.getServletContext();String mimeType = servletContext.getMimeType("login.html");System.out.println(mimeType);System.out.println(servletContext.getRealPath("/login.html"));System.out.println(servletContext.getRealPath("/WEB-INF/web.xml"));System.out.println(servletContext.getRealPath("/WEB-INF/classes/ServletDemo"));接下来我们要实现下载这个图片: 代码如下:
resp.setCharacterEncoding("utf-8"); ServletContext servletContext = req.getServletContext(); String mimeType = servletContext.getMimeType("a.png"); mimeType+=mimeType+";charset=utf-8"; resp.setContentType(mimeType); resp.setHeader("content-disposition", "attachment;filename=目标.png"); ServletOutputStream outputStream = resp.getOutputStream(); InputStream inputStream = new FileInputStream(servletContext.getRealPath("/WEB-INF/classes/Image/目标.png")); byte[] bytes = new byte[1024*200]; while(inputStream.read(bytes)!=-1){ outputStream.write(bytes); outputStream.flush(); } inputStream.close(); outputStream.close();
下载后图片打开后正常,但是文件名乱码了
解决办法如下,编写如下文件:package web.servlet;import sun.misc.BASE64Encoder;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; }}
然后将resp.setHeader("content-disposition", "attachment;filename=目标.png");
改为:
String header = req.getHeader("user-agent"); String filename = DownLoadUtils.getFileName(header,"目标.png"); resp.setHeader("content-disposition", "attachment;filename="+filename);
成功解决:
转载地址:http://jtlzi.baihongyu.com/