回顾:
request: 请求信息对象
Http协议: 浏览器和服务器进行数据交互时,数据的一种规范
请求行: 请求方式 请求路径?get请求参数 协议/版本(http/1.1)
getMethod()
getContextPath()
getRemoteAddr()
getLocalPort()
请求头: key/values
getHeader("头名称");
重要头:
referer: 防盗链
user-agent: 用户代理
cookie:
请求体: post请求时携带的参数(get请求没有请求体)
获取请求参数: ★★★ 浏览器携带的参数,我们所获取的都是字符串
String getParameter("名称");
String[] getParameterValues("名称");
Map<String,String[]> getParameterMap("名称");
BeanUtils:
populate(实体对象,map集合);
Request作用域和请求转发:
请求转发: 一次请求的延续(可以经过多个servlet)
request.getRequestDispatcher("/请求转发的地址").forWard(req,resp);
作用域:
request.setAttribute(String,Object);
// 设置相同名称的属性就是 修改
request.getAttribute(String);
request.removeAttribute(String);
http协议-响应
响应: 服务器给浏览器的内容
组成:
响应行 响应头 响应体
响应行
格式:
协议/版本 响应的状态码 (状态码说明)
tomcat8.5中没有响应状态码说明了
eg: HTTP/1.1 200 OK tomcat7
状态码:
1xx :请求已发送
2xx :响应已完成
200:响应成功(请求成功)
3xx :需要浏览器进一步操作才可以完成
302:重定向(配合location头使用)
304:读缓存
4xx :用户访问错误
404:用户访问的资源不存在
5xx :服务器内部错误
500:服务器内部异常
响应头
格式:
key/values的格式 (values可以为多个值的)
常见的响应头
Location: http://www.it315.org/index.jsp --跳转方向
Server:apache tomcat --服务器型号
Content-Encoding: gzip --数据压缩
Content-Length: 80 --数据长度
Content-Language: zh-cn --语言环境
Content-Type: text/html; charset=utf-8 --数据类型(MIME类型) 大类型/小类型 text/javascript
index.html text/html
设置响应文件的mime类型
设置响应流的编码方式
通知浏览器使用指定的编码解析
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT --最后修改时间
Refresh: 1(秒);url=http://www.it315.org --定时刷新
Content-Disposition: attachment; filename=aaa.zip --下载 用于文件下载 附件
Set-Cookie:SS=Q0=5Lb_nQ; path=/search
重点的头:
Content-Type Refresh Content-Disposition Location Set-Cookie
响应体
浏览器解析的内容
response★
设置服务器发送给浏览器的内容
HttpServletResponse
操作响应行:
协议/版本 状态码(说明)
常用方法
(理解)setStatus(int code):针对1 2 3 开头的
(了解)sendError(int code):针对 4 5 开头的
操作响应头:
格式: key/values
常用方法
(重点)setHeader(String name,String value); // 设置一个字符串形式的响应头
sendRedirect("路径"); // 重定向
常见的响应头
location:重定向
方式1: 需要配合302状态码一起使用 (了解)
response.setStatus(302);
response.setHeader("location","绝对路径");
路径:绝对路径
方式2: (掌握)
response.sendRedirect("路径");
重定向发送的是多次请求
重定向不可以共享request对象(因为发送的是多次请求)
重定向时浏览器地址栏显示的是最后一次的地址
重定向可以跳转到任何路径
refresh:定时刷新
response.setHeader("refresh","秒数;url=跳转的路径"); 几秒之后跳转到指定的路径上
content-type:设置文件的mime类型
设置响应文件的mime类型
设置响应流的编码方式
通知浏览器使用指定的编码解析
方式1: 了解
response.setHeader("content-type","mime类型;charset=编码");
response.setHeader("content-type","text/html;charset=utf-8");
方式2: 掌握
response.setContentType("文件的mime类型;charset=utf-8");
content-disposition:文件下载专用头
response.setHeader("content-disposition","attachment;filename="+文件名称);
操作响应体:
常用方法:
PrintWriter getWriter():字符流
ServletOutputStream getOutputStream():字节流
注意事项:
自己编写的文件 一般都使用字符流输出 如:txt html等
音频,视频等文件使用字节流输出
==字节流和字符流互斥,不能同时使用==
服务器会帮我们释放资源,建议自己关闭;底层使用的缓存流
ServletContext:
上下文对象,全局管理者,知晓一个项目中所有Servlet的一切信息
作用:
获取文件的mime类型 *.html text/html
资源共享
获取资源的完整路径
生命周期:
创建:
当服务器启动的时候,服务器会为每一个项目创建servletcontext对象,一个项目只有一个servletcontext对象
销毁:
项目从服务器上移除或者服务器关闭的时候
servletContext对象与项目共存亡
获取方式:
方式1:通过ServletConfig对象获取
ServletConfig().getServletContext();
方式2:通过getServletContext方法获取 ★★★
getServletContext();
常用方法(API):
(掌握)获取一个文件的mime类型
String getMimeType(String 文件名)
(掌握)资源共享: 相当于一个map集合
setAttribute(String name,Object value): 设置
设置相同名称的属性就是修改
getAttribute(String name):获取指定的属性值
removeAttribute(String name):移除指定的属性
(掌握)获取资源在服务器上的路径
String getRealPath(String filepath)
注意:
filepath:直接从项目的根目录开始写
getRealPath("/") ---> d:/tomcat/webapps/day14
案例
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function isIE(){ // 判断用户使用的浏览器是否为IE浏览器
//获取当前浏览器相关信息
var explorer = window.navigator.userAgent.toLowerCase() ;
//判断是否是ie浏览器
if (explorer.indexOf("msie") >= 0 || explorer.indexOf("rv:11.0) like gecko") >=
0) {
return true;
}else {
return false;
}
}
window.onload = function () { // 页面加载成功事件
if(isIE()){
//在是IE浏览器的情况下,对中文请求参数编码
var str = document.getElementById("ww").href;
str = encodeURI(str);
document.getElementById("ww").href = str;
}
};
function changeImg(obj) {
//alert(1);
obj.src = "anli5?aa="+new Date().getTime();
}
</script>
</head>
<body>
<h3>response对象的相关操作</h3>
<a rel="nofollow" href="refresh">3秒钟之后跳转到黑马官网(定时刷新)</a> <br>
<a rel="nofollow" href="my?money=40">案例2-班长借钱(重定向)</a> <br>
<a rel="nofollow" href="anli3">案例3-返回中文无乱码</a> <br>
<a rel="nofollow" href="body">操作响应体</a> <br>
<hr>
<h3>上下文对象</h3>
<a rel="nofollow" href="getMime?filename=aa.js">通过上下文对象获取文件的mime类型</a> <br>
<a rel="nofollow" href="setAttr">向上下文对象中设置属性</a> <br>
<a rel="nofollow" href="getAttr">从上下文对象中获取属性</a> <br>
<a rel="nofollow" href="updateAttr">修改上下文对象中的属性</a> <br>
<a rel="nofollow" href="removeAttr">删除上下文对象中的属性</a> <br>
<a rel="nofollow" href="getRealPath">获取资源在服务器上的完整路径</a> <br>
<h3>文件下载</h3>
<a rel="nofollow" href="download?filename=meinv.png">美女的诱惑(下载)</a> <br>
<a rel="nofollow" href="download?filename=aa.txt">大数据简单理解(下载)</a> <br>
<a rel="nofollow" id="ww" href="download?filename=大数据简单理解.txt">大数据简单理解1(下载)</a> <br>
<h3>验证码</h3>
<img src="anli5" style="cursor: pointer;" alt="" onclick="changeImg(this)"> <br>
</body>
</html>
案例1 : 3秒钟之后跳转到黑马官网(定时刷新)
需求分析: 访问一个servlet,3秒钟之后跳转到黑马官网(定时刷新) 技术分析: 响应头: refresh="3;url=http://www.itheima.com" 设置响应头: response.setHeader("refresh","3;url=http://www.itheima.com"); package com.itheima.a_anli1;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "RefreshServlet", urlPatterns = "/refresh")
public class RefreshServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 实现定时刷新
// 设置响应头信息 refresh
response.setHeader("refresh","3;url=http://www.itheima.com");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
案例2:使用location响应头实现跳转(重定向)
MyServlert
package com.itheima.b_location;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "MyServlet", urlPatterns = "/my")
public class MyServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("班长曰: 借我钱!");
System.out.println("我曰: 借多少啊?");
System.out.println("班长曰: 自己获取....");
System.out.println(request.getParameter("money"));
System.out.println("我曰: 不好意思,没有零钱,你去找花花借吧...");
System.out.println("班长曰: 花花在哪? ");
//------------------- 重定向
// 方式1: 了解
//a.设置响应状态码
//response.setStatus(302);
//b.设置重定向的路径 /day04/hua
//response.setHeader("location",request.getContextPath()+"/hua?money=400");
//b.方式2:
response.sendRedirect(request.getContextPath()+"/hua?money=400");
//response.sendRedirect("http://www.itheima.com/");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
HuaServler
package com.itheima.b_location;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "HuaServlet", urlPatterns = "/hua")
public class HuaServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("班长曰: 花花,借我钱!");
System.out.println("花花曰: 借多少呀?");
System.out.println("班长曰: 自己获取?");
System.out.println(request.getParameter("money"));
response.getWriter().print("success....");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
案例3:向浏览器输出中文数据(无乱码)
package com.itheima.c_anli3;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "Anli3Servlet", urlPatterns = "/anli3")
public class Anli3Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 返回一段中文信息
// response.setHeader("content-type","text/html;charset=utf-8");
response.setContentType("text/html;charset=utf-8");
response.getWriter().print("你好美女....success");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
案例4:文件下载
需求分析:
当用户在浏览器上点击"下载"超链接时,向服务器发送一个文件下载的请求
将服务器上的文件保存到本地
技术分析: 浏览器: 提供文件下载的超链接 <a rel="nofollow" href="download?filename=meinv.png">美女的诱惑(下载)</a> <a rel="nofollow" href="download?filename=aa.txt">java资料(下载)</a> 服务器: 设置两个头,一个流 设置 文件的mime类型 response.setContentType(文件的mime类型); 设置 文件下载专用头 attachment(附件) filename: 文件下载时,保存文件的默认名称 response.setHeader("content-disposition","attachment;filename="+文件名称); 获取文件输出流 response.getOutputStream(); 步骤分析: 前端: <a rel="nofollow" href="download?filename=meinv.png">美女的诱惑(下载)</a> 后台: //1.获取被下载的文件的名称 String filename = request.getParameter("filename"); //2.设置两个头 //a.设置 文件的mime类型 // 获取上下文对象 context = getServletContext(); // 获取被下载文件的mime类型 String mimeType = context.getMimeType(filename); response.setContentType(mimeType); //b.设置 文件下载专用头 attachment(附件) filename: 文件下载时,保存文件的默认名称 response.setHeader("content-disposition","attachment;filename="+filename); //3.获取文件输出流 // 读取文件 // 找到文件在服务器上的完整路径 String realPath = context.getRealPath("/download/"+filename); // 获取文件的输入流 InputStream is = new FileInputStream(realPath); // 输出流 os = response.getOutputStream(); // 流的对拷 package com.itheima.f_download;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
@WebServlet(name = "DownloadServlet", urlPatterns = "/download")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置request对象的编解码方式
request.setCharacterEncoding("utf-8");
//1.获取被下载的文件的名称
String filename = request.getParameter("filename");
//2.设置两个头
//a.设置 文件的mime类型
// 获取上下文对象
ServletContext context = getServletContext();
// 获取被下载文件的mime类型
String mimeType = context.getMimeType(filename);
response.setContentType(mimeType);
//b.设置 文件下载专用头 attachment(附件) filename: 文件下载时,保存文件的默认名称
//response.setHeader("content-disposition","attachment;filename="+filename);
//-------------------- 处理文件下载时,默认名称(中文乱码)
// 文件下载注意事项: 文件下载的默认名称永远使用浏览器自己的编解码方式进行解码
//String name = "美女.png";
//name = URLEncoder.encode(name,"utf-8");
// 使用工具类实现
String agent = request.getHeader("user-agent");
String name = DownLoadUtils.getName(agent,filename);
//---------------------
response.setHeader("content-disposition","attachment;filename="+name);
//3.获取文件输出流
// 读取文件
// 找到文件在服务器上的完整路径
String realPath = context.getRealPath("/download/"+filename);
// 获取文件的输入流
FileInputStream is = new FileInputStream(realPath);
// 输出流
ServletOutputStream os = response.getOutputStream();
// 流的对拷
int len = 0;
byte b[] = new byte[1024];
while((len=is.read(b))!=-1){
os.write(b,0,len);
}
// 关流
os.close();
is.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
工具类
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import sun.misc.BASE64Encoder;
public class DownLoadUtils {
/**
@param agent : 用户代理
@param filename : 文件名称
@return
@throws UnsupportedEncodingException
/
public static String getName(String agent, String filename) throws UnsupportedEncodingException {
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;
}
}
### 案例5:点击切换验证码
package com.itheima.g_anli5;
import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random;
import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "CodeServlet",urlPatterns = "/anli5") public class CodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用java图形界面技术绘制一张图片
int charNum = 4; // 生成4位的验证码
int width = 20 * 4; // 图片宽
int height = 28; // 图片高
// 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.GRAY);
graphics.drawRect(0, 0, width - 1, height - 1);
// 5、输出验证码内容
graphics.setColor(Color.RED);
graphics.setFont(new Font("宋体", Font.BOLD, 22));
// 随机输出4个字符
String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
Random random = new Random();
// session中要用到
String msg = "";
int x = 5;
for (int i = 0; i < charNum; i++) {
int index = random.nextInt(32);
String content = String.valueOf(s.charAt(index));
msg += content;
graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
graphics.drawString(content, x, 22);
x += 20;
}
// 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 {
doGet(request,response);
}
}