博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javaWeb——Request和Response03
阅读量:3958 次
发布时间:2019-05-24

本文共 5213 字,大约阅读时间需要 17 分钟。

javaWeb——Request和Response03

到了这一节我们开始学习Response。

文章目录

一.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代码完全执行完后才发生

二.Tomcat项目中路径的写法及Response流的示例

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("

Hello World! 你好

");

在这里插入图片描述

不过上面这个方法不是很通用,比如我们的浏览器采用的字符集不是gbk我们可以使用下面的方式:

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/

你可能感兴趣的文章
C++实现http下载 && 24点计算编码风格
查看>>
memcached了解使用和常用命令详解
查看>>
GDB调试各功能总结
查看>>
"undefined reference to" 多种可能出现的问题解决方法
查看>>
类结构定义
查看>>
Windows下关于多线程类 CSemaphore,CMutex,CCriticalSection,CEvent,信号量CSemaphore的使用介绍
查看>>
图像处理基本算法(汇总)以及实现
查看>>
C++编程获取本机网卡信息 本机IP 包括Windows和Linux
查看>>
C++连接CTP接口实现简单量化交易
查看>>
服务端使用c++实现websocket协议解析及通信
查看>>
C# string.Format使用说明
查看>>
Linux下安装Mysql数据库开发环境
查看>>
Linux用户及用户组添加和删除操作
查看>>
通用 Makefile 的编写方法以及多目录 makefile 写法
查看>>
C++的4种智能指针剖析使用
查看>>
RPC框架实现之容灾策略
查看>>
Docker私库
查看>>
hdu——1106排序(重定向)
查看>>
hdu——1556Color the ball(树状数组)
查看>>
hdu——1541Stars(树状数组)
查看>>