1、response响应的对象
* HttpServletResposne对象,代表一个响应,父接口是ServletResponse
** 通过api文档查看这个对象里面的方法
* 响应包含三部分
** 响应行
*** 状态码
* setStatus(int sc) 设置状态码
* 比如 setStatus(302);
** 响应头
*** 结构:key value,一个key可以有一个或者多个value
* setHeader(java.lang.String name, java.lang.String value) :第一个参数头的名称 ,第二个值
** 针对一个key对应一个value的情况
** setHeader("aa","AA");
setHeader("aa","BB");
最终的结果:aa BB
** 针对特殊的类型有设置头的方法
* setIntHeader(java.lang.String name, int value):值是int类型
* setDateHeader(java.lang.String name, long date) :值是毫秒数
* addHeader(java.lang.String name, java.lang.String value) :第一个参数头的名称 ,第二个值
** 针对一个key对应多个value的情况
** addHeader("cc","CC");
addHeader("cc","QQ");
结果: cc CC,QQ
** 针对特殊类型的设置头的方法
* addIntHeader(java.lang.String name, int value) :值是int类型
* addDateHeader(java.lang.String name, long date) :值是毫秒数
** 响应体
*** 显示在浏览器里面的内容
** 使用字节流和字符流向页面输出内容
* getOutputStream()
* getWriter()
- getWriter().write();
- getWriter().printf();
** 把服务器上面的内容显示到浏览器,这个过程都可以使用response来实现
2、练习1:使用response实现登录的重定向操作
* 创建一个登录页面,表单,提交一个servlet里面
* 判断用户名和密码是否正确
* 如果用户名或者密码错误,重定向到登录页面
* 重定向 302
* 头信息 Location
* 步骤
* 1、得到输入的用户名和密码
* * request方法 getParameter("输入项里面的name属性的值")方法
* 2、判断用户名和密码是否正确,比如固定值 admin 1213
* 3、如果用户名和密码都正确,向页面输出 登陆成功
* 4、如果用户名或者密码错误,重定向到登录页面
* * 使用 302 设置状态码 setStatus方法
* * 使用头 Location 设置头方法 setHeader方法
* 代码
String username=request.getParameter("username");
String password=request.getParameter("password");
if("admin".equals(username)
&&"1213".equals(password))
{
//向页面输出内容
response.getWriter().writer("登陆成功");
}else
{
//重定向到登录页面
//设置302状态码
response.setStatus(302);
response.setHeader("Location","/webname/response/login.html");
}
//简写:实现重定向的操作
response.sendRedirect("/webname/response/login.html");
3、练习2:使用response实现页面的定时跳转
* 使用 Refresh头
** response.setHeader("Refresh","3;url=/webname/.....");
//设置中文可显,防止出现乱码
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("页面将在3秒后跳转");
//第一个是秒数,第二个是跳转到的页面
response.setHeader("Refresh", "3;url=/webname/response/login.html");
* 也可以在html页面中使用meta头标签实现
* <meta http-equiv="Refresh" content="3;url=/webname/response/login.html">
* 使用js实现倒计时
<span id="spanid"> </span>
<script type="text/javascript">
var m = 5;
function load1()
{
var span1 = document.getElementById("spanid");
span1.innerHTML = m;
m--;
}
setInterval("load1();",1000);
</script>
4、练习3:使用Response实现禁用浏览器缓存
* 使用到头信息
- Cache-Control : no-cache
- Pragma : no-cache
- Expires: -1 :使用的方法 setDateHeader("",毫秒数):毫秒数,1970-1-1至今的毫秒数
* 在一些版本低的浏览器里面,才会有这些头信息禁用浏览器缓存的效果 比如ie6
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", -1);
Date date=new Date();
String times=date.toLocaleString();
response.getWriter().write(times);
5、response向页面输出中文问题解决
* 向页面输出内容的两种方式
- 使用字节流和字符流输出
* 使用字节流向页面输出中文
* 解决乱码问题
//首先设置浏览器的编码
response.setHeader("Content-Type", "text/html;charset=utf-8");
//再设置字节数组的编码并输出
response.getOutputStream().write("字节流中文".getBytes("utf-8"));
# 使用字符流输出中文不一定会有乱码
# 浏览器的编码和字节数组的编码一致
* 使用字符流向页面输出中文
* 字符流会产生一个缓冲区,首先会输出的内容先放到缓冲区里面,通过缓冲区进行输出
* response缓冲区会有一个默认的编码 iso8859-1,但是这个编码不支持中文
* 解决方法
//首先设置response缓冲区的编码
response.setCharacterEncoding("utf-8");
//设置浏览器的编码
response.setHeader("Content-Type", "text/html;charset=utf-8");
//输出
response.getWriter().write("字符流中文");
# 使用字符流输出中文一定会有乱码
# 让response缓冲区的编码和浏览器编码一致
6、response在开发中的一些细节问题
* 第一个细节问题: 使用字符流向页面输出中文解决,有一种简写方式
response.setHeader("Content-Type", "text/html;charset=utf-8");
//简写方式
response.setContentType("text/html;charset=utf-8");
* 第二个细节问题:
* 字节流和字符流是互斥的,两个流不能在一起使用
* 第三个细节问题:
"text/html;charset=utf-8",使用分号进行隔开,而不能使用其他的符号
* 第四个细节问题:
* 不能使用字符流直接向页面输出数字
* 使用字符流向页面直接输出一个数字,
* 到utf-8码表查找数字对应的值,把数字对应的字符输出,而不会直接输出数字
* 第五个细节问题:
* 重定向操作时候,简写方式
response.sendRedirect("/webname/..");
7、练习4:使用response实现文件的下载
* 首先服务器上面有可以下载的文件
* 下载的步骤
* 第一步:得到文件流,输入流
* 得到文件的完全路径 使用servletContext对象里面getRealPath方法
InputStream in = new FileInputStream("文件完全路径");
* 第二步:使用输出流把文件输入流写到浏览器
OutputStream out = response.getOutputStream();
* 第三步:流对接
# 设置头信息:Content-Disposition,如果下载的文件是一个图片,如果不设置这个头信息,会把图片直接打开
# 作用:无论是什么格式的文件,都会提示下载这个文件
** 代码
//得到文件的完全路径
String path = getServletContext().getRealPath("/img/b.jpg");
// System.out.println(path); c:
\tomcat\img\a.jpg
//得到文件的名称 使用字符串截取
int lens = path.lastIndexOf("
\\"); //得到最后一个
\
String filename = path.substring(lens+1); //得到b.jpg
//设置头信息
response.setHeader("Content-Disposition", "attachment;filename="+filename);
//得到文件流
InputStream in = new FileInputStream(path);
//使用输出流写到浏览器
OutputStream out = response.getOutputStream();
//流对接
int len = 0;
byte
[] b = new byte
[1024
];
while((len=in.read(b))!=-1)
{
out.write(b, 0, len);
}
//关闭流
in.close();
* 如果下载的文件名称里面包含中文,这个下载时候就不能正常显示
* 首先在不同的浏览器里面有不同的编码,需要根据不同的浏览器进行相应的处理
* 使用头 User-Agent得到不同的浏览器类型
* ie里面采用的是url编码,火狐采用的编码是base64
- 在ie浏览器中
String filename1=URLEncoder.encode(filename,"utf-8");
8、案例五:使用response实现验证码
* 什么是验证码:防止恶意注册,灌水
* 步骤
第一步:生成图片
第二步:生成随机的数字和字母
第三步:把数字和字母画到图片上
第四步:把图片显示到页面上
* 代码
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//生成图片
int width = 200;
int height = 50;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
//生成的图片背景颜色 默认是黑色
//得到画笔
Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
//设置颜色
g2d.setColor(Color.gray);
g2d.fillRect(0, 0, width, height);
//生成四个随机的数字和字母、汉字
String words = "
\u7684
\u4e00
\u4e86
\u662f
\u6211
\u4e0d
\u5728
\u4eba
\u4eec
\u6709
\u6765
\u4ed6
\u8fd9
\u4e0a
\u7740
\u4e2a
\u5730
\u5230
\u5927
\u91cc
\u8bf4
\u5c31
\u53bb
\u5b50
\u5f97
\u4e5f
\u548c
\u90a3
\u8981
\u4e0b
\u770b
\u5929
\u65f6
\u8fc7
\u51fa
\u5c0f
\u4e48
\u8d77
\u4f60
\u90fd
\u628a
\u597d
\u8fd8
\u591a
\u6ca1
\u4e3a
\u53c8
\u53ef
\u5bb6
\u5b66
\u53ea
\u4ee5
\u4e3b
\u4f1a
\u6837
\u5e74
\u60f3
\u751f
\u540c
\u8001
\u4e2d
\u5341
\u4ece
\u81ea
\u9762
\u524d
\u5934
\u9053
\u5b83
\u540e
\u7136
\u8d70
\u5f88
\u50cf
\u89c1
\u4e24
\u7528
\u5979
\u56fd
\u52a8
\u8fdb
\u6210
\u56de
\u4ec0
\u8fb9
\u4f5c
\u5bf9
\u5f00
\u800c
\u5df1
\u4e9b
\u73b0
\u5c71
\u6c11
\u5019
\u7ecf
\u53d1
\u5de5
\u5411
\u4e8b
\u547d
\u7ed9
\u957f
\u6c34
\u51e0
\u4e49
\u4e09
\u58f0
\u4e8e
\u9ad8
\u624b
\u77e5
\u7406
\u773c
\u5fd7
\u70b9
\u5fc3
\u6218
\u4e8c
\u95ee
\u4f46
\u8eab
\u65b9
\u5b9e
\u5403
\u505a
\u53eb
\u5f53
\u4f4f
\u542c
\u9769
\u6253
\u5462
\u771f
\u5168
\u624d
\u56db
\u5df2
\u6240
\u654c
\u4e4b
\u6700
\u5149
\u4ea7
\u60c5
\u8def
\u5206
\u603b
\u6761
\u767d
\u8bdd
\u4e1c
\u5e2d
\u6b21
\u4eb2
\u5982
\u88ab
\u82b1
\u53e3
\u653e
\u513f
\u5e38
\u6c14
\u4e94
\u7b2c
\u4f7f
\u5199
\u519b
\u5427
\u6587
\u8fd0
\u518d
\u679c
\u600e
\u5b9a
\u8bb8
\u5feb
\u660e
\u884c
\u56e0
\u522b
\u98de
\u5916
\u6811
\u7269
\u6d3b
\u90e8
\u95e8
\u65e0
\u5f80
\u8239
\u671b
\u65b0
\u5e26
\u961f
\u5148
\u529b
\u5b8c
\u5374
\u7ad9
\u4ee3
\u5458
\u673a
\u66f4
\u4e5d
\u60a8
\u6bcf
\u98ce
\u7ea7
\u8ddf
\u7b11
\u554a
\u5b69
\u4e07
\u5c11
\u76f4
\u610f
\u591c
\u6bd4
\u9636
\u8fde
\u8f66
\u91cd
\u4fbf
\u6597
\u9a6c
\u54ea
\u5316
\u592a
\u6307
\u53d8
\u793e
\u4f3c
\u58eb
\u8005
\u5e72
\u77f3
\u6ee1
\u65e5
\u51b3
\u767e
\u539f
\u62ff
\u7fa4
\u7a76
\u5404
\u516d
\u672c
\u601d
\u89e3
\u7acb
\u6cb3
\u6751
\u516b
\u96be
\u65e9
\u8bba
\u5417
\u6839
\u5171
\u8ba9
\u76f8
\u7814
\u4eca
\u5176
\u4e66
\u5750
\u63a5
\u5e94
\u5173
\u4fe1
\u89c9
\u6b65
\u53cd
\u5904
\u8bb0
\u5c06
\u5343
\u627e
\u4e89
\u9886
\u6216
\u5e08
\u7ed3
\u5757
\u8dd1
\u8c01
\u8349
\u8d8a
\u5b57
\u52a0
\u811a
\u7d27
\u7231
\u7b49
\u4e60
\u9635
\u6015
\u6708
\u9752
\u534a
\u706b
\u6cd5
\u9898
\u5efa
\u8d76
\u4f4d
\u5531
\u6d77
\u4e03
\u5973
\u4efb
\u4ef6
\u611f
\u51c6
\u5f20
\u56e2
\u5c4b
\u79bb
\u8272
\u8138
\u7247
\u79d1
\u5012
\u775b
\u5229
\u4e16
\u521a
\u4e14
\u7531
\u9001
\u5207
\u661f
\u5bfc
\u665a
\u8868
\u591f
\u6574
\u8ba4
\u54cd
\u96ea
\u6d41
\u672a
\u573a
\u8be5
\u5e76
\u5e95
\u6df1
\u523b
\u5e73
\u4f1f
\u5fd9
\u63d0
\u786e
\u8fd1
\u4eae
\u8f7b
\u8bb2
\u519c
\u53e4
\u9ed1
\u544a
\u754c
\u62c9
\u540d
\u5440
\u571f
\u6e05
\u9633
\u7167
\u529e
\u53f2
\u6539
\u5386
\u8f6c
\u753b
\u9020
\u5634
\u6b64
\u6cbb
\u5317
\u5fc5
\u670d
\u96e8
\u7a7f
\u5185
\u8bc6
\u9a8c
\u4f20
\u4e1a
\u83dc
\u722c
\u7761
\u5174
\u5f62
\u91cf
\u54b1
\u89c2
\u82e6
\u4f53
\u4f17
\u901a
\u51b2
\u5408
\u7834
\u53cb
\u5ea6
\u672f
\u996d
\u516c
\u65c1
\u623f
\u6781
\u5357
\u67aa
\u8bfb
\u6c99
\u5c81
\u7ebf
\u91ce
\u575a
\u7a7a
\u6536
\u7b97
\u81f3
\u653f
\u57ce
\u52b3
\u843d
\u94b1
\u7279
\u56f4
\u5f1f
\u80dc
\u6559
\u70ed
\u5c55
\u5305
\u6b4c
\u7c7b
\u6e10
\u5f3a
\u6570
\u4e61
\u547c
\u6027
\u97f3
\u7b54
\u54e5
\u9645
\u65e7
\u795e
\u5ea7
\u7ae0
\u5e2e
\u5566
\u53d7
\u7cfb
\u4ee4
\u8df3
\u975e
\u4f55
\u725b
\u53d6
\u5165
\u5cb8
\u6562
\u6389
\u5ffd
\u79cd
\u88c5
\u9876
\u6025
\u6797
\u505c
\u606f
\u53e5
\u533a
\u8863
\u822c
\u62a5
\u53f6
\u538b
\u6162
\u53d4
\u80cc
\u7ec6";
Random r = new Random();
int x = 30;
int y = 30;
g2d.setColor(Color.red);
//设置字体的样式
g2d.setFont(new Font("宋体",Font.BOLD,25));
//旋转的效果
//弧度: 角度*3.14/180
for(int i=1;i< =4;i++)
{
//返回字符串里面字符的下标
int len = r.nextInt(words.length());
//旋转的角度 +-30度
int jiaodu = r.nextInt(60)-30;
double h = jiaodu*Math.PI/180;
//根据位置得到具体字符
char ch = words.charAt(len);
//实现旋转
g2d.rotate(h, x, y);
//把生成的字符画到图片
g2d.drawString(ch+"", x, y);
//再转回来
g2d.rotate(-h, x, y);
x += 25;
}
//增加三条干扰线 drawLine(int x1, int y1, int x2, int y2)
int x1,x2,y1,y2;
g2d.setColor(Color.green);
for(int j=1;j< =3;j++)
{
x1 = r.nextInt(width);
y1 = r.nextInt(height);
x2 = r.nextInt(width);
y2 = r.nextInt(height);
//把线画到图片
g2d.drawLine(x1, y1, x2, y2);
}
//把图片显示到页面上
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
* 实现中文的验证码
** 汉字:
\u4e00 ——
\u9fa5,但是这个范围后面的那些汉字不认识,使用常用汉字的范围
* 实现看不清换一张
** 首先在登陆页面里面增加验证码,使用img标签,src属性值加上验证码的servlet
** 创建一个超链接,写一个事件,通过js实现这样操作
** 首先得到img标签,重新请求servlet,使用src属性
# 产生一个问题:有缓存,在请求的地址后面增加一个随机数
** 代码
<body>
<h1>登录页面</h1>
<form action="/webname/login" method="post">
username:<input type="text" name="username"/>
<br/>
passwrod:<input type="password" name="password"/>
<br/>
code:<input type="text" name="code"/>
<img id="img1" src="/webname/code"/> <a href="javascript:void(0)" onclick="loadCode();">看不清,换一张</a>
<br/>
<input type="submit" value="登录"/>
</form>
</body>
<script type="text/javascript">
//实现看不清换一张
function loadCode()
{
//得到img标签
var img1 = document.getElementById("img1");
//向src重新设置地址,加随机数
img1.src = "/webname/code?"+new Date().getTime();
}
</script>
9、request对象
* HttpServletRequest,代表请求对象,父接口是 ServletRequest
10、request对象获取到客户机的信息
** 获取表单提交方式
getMethod()
** 获取到请求地址
getRequestURL()
** 获取到请求的项目名称
getContextPath()
** 获取请求的客户端的ip地址
getRemoteAddr()
11、request对象获取到请求的头信息
* 使用方法getHeader("头信息名称");
* 重要的头信息
* Referer User-Agent If-Modified-Since
** request.getHeader("Referer");
request.getHeader("User-Agent");
12、request对象获取通过表单提交的数据
* 方法
** getParameter(java.lang.String name)
- 获取表单提交的数据方法,参数输入项name的值
- String username = request.getParameter("username");
** getParameterValues(java.lang.String name),返回String
[]
- 针对复选框 ,获取多个提交的数据,参数输入项name的值
- //得到复选框里面的所有值
String
[] loves = request.getParameterValues("love");
//Arrays 里的方法tostring一次性获取数组中的多个值
System.out.println(Arrays.toString(loves));
** getParameterMap() :返回 Map<java.lang.String,java.lang.String
[]>
- 获取表单输入项的name的值,和输入的值
- //得到输入项name的值,和输入的值
Map<String,String
[]> map = request.getParameterMap();
//遍历map 有两种
//得到所有的key
Set<String> keys = map.keySet();
//遍历set,得到value ,set遍历有两种方式
for (String key : keys)
{
//根据key得到value
String
[] values = map.get(key);
System.out.println(key+" :: "+Arrays.toString(values));
}
** getParameterNames() : Enumeration<java.lang.String>
- 获取所有表单输入项的name的值
** 在表单输入项里面,输入中文,出现中文乱码
13、request对象获取表单提交中文数据乱码问题解决
* 表单提交方式,常用get 和 post
* 使用post提交中文数据时候乱码问题解决 (设置request缓冲区的编码)
** 使用post提交数据,放到请求体里面
//post提交中文数据有乱码问题
//request获取通过post提交的数据,也会把数据放到request缓冲区里面
//response缓冲区默认编码是 iso8859-1,而request缓冲区里面默认编码也是iso8859-1,不支持中文
//解决方式:设置request缓冲区的编码
request.setCharacterEncoding("utf-8");
//获取提交的数据有中文
String username = request.getParameter("username");
System.out.println("username:: "+username);
* 使用get提交中文数据时候乱码问题的解决
** get提交数据放到浏览器地址栏里面,对中文数据进行url编码。
** 三种解决方式:
- 在tomcat里面配置
** 找到tomcat目录conf下面server.xml,在配置端口地方,最后加 URIEncoding="utf-8"
- 首先先对中文编码,到servlet里面解码
- 使用string构造方法编码转换(重点掌握)
* username = new String(username.getBytes("ISO8859-1"),"utf-8");
** 代码:String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"),"utf-8");
===================================================
(1)向页面输出中文乱码
* 字节流
** 设置浏览器编码和字节数组的编码一致
* 字符流
** 设置response缓冲区的编码和浏览器的编码一致
(2)获取表单提交的中文数据乱码
* post: 设置request缓冲区的编码
* get:三种,使用string构造完成编码转换
14、request域
* 域:在一定的范围内,存值和取值
** servletContext域:整个web项目
存值:setAttribute
取值:getAttribute
* request也是一个域对象
** 范围: 一次请求
存值:setAttribute
取值:getAttribute
* request域对象经常和转发在一起使用
** request.getRequestDispatcher("转发的路径 不带项目名称").forward();
- 练习:向request域里面设置一个值 转发到demo2
Demo1写代码:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//设置值
request.setAttribute("msg", "itcast");
//转发到demo2
//request.getRequestDispatcher("/demo2").forward(request, response);
//重定向到demo2
response.sendRedirect("/webname/demo2");
}
Demo2写代码:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.getWriter().print(request.getAttribute("msg"));
}
15、转发和重定向区别
* 重定向:
** 请求两次,重定向的地址带项目名称
* 转发:
** 请求一次,转发地址不需要带项目名称
* 重定向:从一个网站到另外一个网站
* 转发:请求里面需要带数据
10、练习6:使用转发完成登录操作
* 如果用户名或者密码错误,回到登陆页面,但是携带错误提示在登录页面显示出来
* 引入知识点
** jsp :sun公司提供用于开发动态网站的技术 servlet
** el表达式:获取域对象里面的值
*** 语法:
${域对象名称}
* 创建jsp页面,写登录表单
** 转发的代码
//向request域里面设置一个值
request.setAttribute("msg1", "用户名或者密码错误");
//转发到登录页面
request.getRequestDispatcher("/request/login.jsp").forward(request, response);
** 在jsp里面获取域对象的值
<h2><font color="red">${msg1
}</font></h2>
11、debug调试web项目
* 设置断点,单步执行 F6
* 需要使用debug模式启动tomcat服务器
** 点击 debug server