web_day35_HttpServletResponse对象&&文件下载

一、HttpServletResponse对象

1、概念

  • HttpServletResponse专门负责响应的,它是一个接口,是ServletResponse接口的子接口
  • 实现类是服务器做的实现
  • 它带有http协议,那么我们就可以按照之前学习Http响应协议的方法来学习它

2、http响应协议

2.1 组成部分

响应行、响应头、响应体

2.2 操作响应行

格式:协议/版本 状态码 状态码说明

常见的响应状态码

状态码说明
200正常响应
302重定向
304读缓存
404找不到资源
405访问的方法不存在
500服务器内部错误

设置响应状态码

  • setStatus(int 状态码);-----针对于1XX,2XX,3XX
  • sendError(int 状态码);-----针对于4XX,5XX

2.3 操作响应头

格式:key/value(value可以是多个值)

设置响应头的方法
方法说明
public void setHeader(String name,String value);设置HTTP协议的响应头字段,一头一值,会覆盖
public void addHeader(String name,String value);设置HTTP协议的响应头字段,一头多值,不会覆盖,设置cookie
public void setCharacterEncoding(String encoding);设置服务器向客户端响应数据的编码
public void setContentType(String type);

设置的mime类型;

解决响应乱码问题的方法

除了设置服务器向客户端响应数据的编码外,还告诉浏览器使用什么编码来解析

public void setContentLength(int len);设置响应消息的实体内容的大小

常用的响应头:

  • location:重定向
  • refresh:定时刷新
  • content-type:设置文件的mime类型,设置响应流的编码及告诉浏览器用什么编码打开
  • content-disposition:文件下载

操作响应体

  • getWriter();        //字符流
  • getOutputStream();    //字节流 (只要是文件下载或者文件上传,都必须使用这个)
  • 注意:不要同时使用这2个流
package com.itheima.web.servlet;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itheima.domain.User;
import com.itheima.service.UserService;

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public LoginServlet() {
		super();
	}

	@Override
	public void init() throws ServletException {
		// 1.定义一个变量进行初始化
		int count = 0;
		// 2.获取ServletContext域对象
		ServletContext servletContext = this.getServletContext();
		// 3.将变量保存到域对象中
		servletContext.setAttribute("count", count);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 处理中文乱码
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		// 1.获取请求参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		// 2.封装数据
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);

		// 3.调用service层方法
		UserService service = new UserService();
		User existUser = null;
		try {
			existUser = service.login(user);
			// 4.对查询结果进行判断
			if (existUser != null) {
				// 5.获取ServletContext对象
				ServletContext servletContext = this.getServletContext();
				// 6.从ServletContext域对象中获取值
				int count = (int) servletContext.getAttribute("count");
				// 7.自增
				count++;
				// 8.放入域对象中
				servletContext.setAttribute("count", count);
				// 9.给出提示信息
				response.getWriter().write("<h3 style='color:blue'>"+"亲,您是第" + count + "次登录..."+"</h3>");
			} else {
				response.getWriter().write("<h3 style='color:red'>"+"登录失败"+"</h3>");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

二、文件下载

1、下载方式

1.1 超链接下载(不靠谱)

直接将服务器上的文件的路径写到href属性中

  1. 如果浏览器不支持该格式文件,那么就会提示进行下载
  2. 如果浏览器支持这个格式的文件,那么直接打开

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>文件下载</title>
</head>
	<body>
		<h3>超链接方式:不靠谱</h3>
			<a href="http://localhost:8080/web_day35/download/feiji03.gif">feiji03.gif</a><br>
			<a href="http://localhost:8080/web_day35/download/DownloadServlet.java">DownloadServlet.java</a><br>
			<a href="http://localhost:8080/web_day35/download/document.zip">document.zip</a><br>
			
	</body>
</html>

1.2 编码下载(重点)

无论浏览器是否识别该格式的文件,都会提示下载

需要的信息说明
Content-Type要下载文件类型的MIME的类型
Content-Disposition:"attachment;filename="+filename浏览器识别该格式文件,提示下载
文件的输入流需要文件的真实路径

2、文件下载案例

download.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta http-equiv="Refresh" content="3; url=http://www.itcast.cn">
		<title>文件下载</title>
	</head>
	<body>
		
		<h3>手动编码方式:靠谱</h3>
			<a href="http://localhost:8080/web_day35/DownloadServlet?filename=feiji.gif">feiji.gif</a><br>
			<a href="http://localhost:8080/web_day35/DownloadServlet?filename=DownloadServlet.java">DownloadServlet.java</a><br>
			<a href="http://localhost:8080/web_day35/DownloadServlet?filename=document.zip">document.zip</a><br>
			<a href="http://localhost:8080/web_day35/DownloadServlet?filename=飞机.gif">飞机.gif</a><br>
			
	</body>
</html>
</html>

DownloadServlet.java


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.IOUtils;

import sun.misc.BASE64Encoder;

/**
 * 文件下载 文件下载:(1一个流2个头) 
 * 文件输入流:直接创建即可(需要知道这个文件的真实路径)
 * Content-Type:执行文件的MIME类型(ServletContext.getMimeType(文件名称))
 * Content-Disposition:"attachment;filename="+filename(从页面获得)
 */
public class DownloadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		
		// 1.获取请求参数(文件名)
		String filename = request.getParameter("filename");
		// 2.解决请求乱码问题
		filename = new String(filename.getBytes("iso8859-1"), "utf-8");

		ServletContext context = this.getServletContext();
		// 3.获取文件的真实路径
		String realPath = context.getRealPath("download/" + filename);

		// 4.获取文件的MIME类型
		String mimeType = context.getMimeType(filename);

		// 5.解决下载框的乱码(根据不同的浏览器来处理:只有火狐不一样,其它 的处理一样)
		// 获得User-Agent
		String header = request.getHeader("User-Agent");
		if (header.contains("Firefox")) {
			// 说明是火狐浏览器
			filename = base64EncodeFileName(filename);
		} else {
			// 其它浏览器
			filename = URLEncoder.encode(filename, "utf-8");
		}

		// 6.设置Content-Type头
		response.setHeader("Content-Type", mimeType);

		// 7.设置Content-Disposition头(告诉浏览器无论如何都要给我弹出下载框)
		response.addHeader("Content-Disposition", "attachment;filename=" + filename);

		// 8.创建一个文件输入流
		InputStream is = new FileInputStream(realPath);

		// 9.获得输出流
		ServletOutputStream os = response.getOutputStream();

		// 10.流对拷
		IOUtils.copy(is, os);

		// 11.关闭流
		os.close();
		is.close();

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	/**
	 * @MethodName:base64EncodeFileName
	 * @Description:火狐浏览器编码问题
	 * @param fileName
	 * @return
	 */
	public static String base64EncodeFileName(String fileName) {
		BASE64Encoder base64Encoder = new BASE64Encoder();
		try {
			return "=?UTF-8?B?" + new String(base64Encoder.encode(fileName.getBytes("UTF-8"))) + "?=";
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

}

案例--点击获取验证码

页面

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<img alt="验证码" src="/day10/code" title="看不清除,换一张" onclick="changeImg(this)">
</body>
<script type="text/javascript">
	function changeImg(obj){
		//操作src属性
		obj.src="/day10/code?i="+Math.random();
		//obj.src="/day10/code";
		//alert(1)
	}
</script>
</html>

CodeServlet.java

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		// 使用java图形界面技术绘制一张图片

		int charNum = 4;
		int width = 30 * 4;
		int height = 30;

		// 1. 创建一张内存图片
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		// 2.获得绘图对象
		Graphics graphics = bufferedImage.getGraphics();

		// 3、绘制背景颜色
		graphics.setColor(Color.YELLOW);
		graphics.fillRect(0, 0, width, height);

		// 4、绘制图片边框
		graphics.setColor(Color.BLUE);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 5、输出验证码内容
		graphics.setColor(Color.RED);
		graphics.setFont(new Font("宋体", Font.BOLD, 20));

		// 随机输出4个字符
		Graphics2D graphics2d = (Graphics2D) graphics;
		String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
		Random random = new Random();
		// session中要用到
		String msg = "";
		int x = 5;
		for (int i = 0; i < 4; i++) {
			int index = random.nextInt(32);
			String content = String.valueOf(s.charAt(index));
			msg += content;
			double theta = random.nextInt(45) * Math.PI / 180;
			// 让字体扭曲
			graphics2d.rotate(theta, x, 18);
			graphics2d.drawString(content, x, 18);
			graphics2d.rotate(-theta, x, 18);
			x += 30;
		}

		// 6、绘制干扰线
		graphics.setColor(Color.GRAY);
		for (int i = 0; i < 5; i++) {
			int x1 = random.nextInt(width);
			int x2 = random.nextInt(width);

			int y1 = random.nextInt(height);
			int y2 = random.nextInt(height);
			graphics.drawLine(x1, y1, x2, y2);
		}

		// 释放资源
		graphics.dispose();

		// 图片输出 ImageIO
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值