一、Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。
二、HttpServletResponse
1、响应行 HTTP/1.1 200 OK
- setStatus(int sc) 设置响应状态码
2、响应头
- setRedirect(String location)请求重定向
- setHeader(String name,String value)设置响应头信息
- //告知浏览器使用什么码表
response.setHeader("content-type", "text/html;charset=UTF-8");
//告知客户端不缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setDateHeader("expires", 0)
- Refresh 刷新
3、响应正文(主体)
-
*** getWrite(); 字符输出流
-
getOutputStream(); 字节输出流
-
setCharacterEncoding(String charset) 告知服务器使用什么编码
*****setContentType(String type)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//服务器中默认的编码为ISO-8859-1,它不支持中文,tomcat规定的
// //告诉服务器应用使用UTF-8解析文本
// resp.setCharacterEncoding("UTF-8");
// //告诉客户端要使用什么编码
// resp.setHeader("content-type", "text/html;charset=UTF-8");
//告诉服务器应用使用UTF-8解析文本,告诉客户端要使用什么编码
resp.setContentType("text/html; charset=UTF-8");
//得到一个字符输出流
PrintWriter out = resp.getWriter();
//向客户端响应文本内容
out.write("中国");
resp
.setContentType(
"text/html; charset=UTF-8"
);
ServletOutputStream
sos
=
resp
.getOutputStream();
sos
.write(
"你好"
.getBytes(
"UTF-8"
));
}
4、下载文件
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
//通过路径得到一个输入流
String
path
=
this
.getServletContext().getRealPath(
"/WEB-INF/classes/1.png"
);
FileInputStream
fis
=
new
FileInputStream(
path
);
//创建字节输出流
ServletOutputStream
sos
=
resp
.getOutputStream();
//得到要下载的文件名
String
filename
=
path
.substring(
path
.lastIndexOf(
"\\"
)+1);
//设置文件名的编码
filename
= URLEncoder.encode(
filename
,
"UTF-8"
);
//将不安全的文件名改为UTF-8格式
//告知客户端要下载文件
resp
.setHeader(
"content-disposition"
,
"attachment;filename="
+
filename
);
resp
.setHeader(
"content-type"
,
"image/jpeg"
);
//执行输出操作
int
len
= 1;
byte
[]
b
=
new
byte
[1024];
while
(-1 != (
len
=
fis
.read(
b
))){
sos
.write(
b
, 0,
len
);
}
sos
.close();
fis
.close();
}
5、验证码
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
int
width
= 110;
int
height
= 25;
//在内存中创建一个图片对象
BufferedImage
img
=
new
BufferedImage(
width
,
height
, BufferedImage.
TYPE_INT_RGB
);
//创建一个画笔
Graphics
g
=
img
.getGraphics();
//给图片添加背景色
g
.setColor(Color.
PINK
);
//设置一个颜色
g
.fillRect(1, 1,
width
-2,
height
-2);
//填充颜色
//给边框一个色
g
.setColor(Color.
RED
);
g
.drawRect(0, 0,
width
-1,
height
-1);
//设置边框的显示坐标
//设置文本样式
g
.setColor(Color.
BLUE
);
g
.setFont(
new
Font(
"宋体"
, Font.
BOLD
|Font.
ITALIC
, 15));
//给图片添加文字
Random
rand
=
new
Random();
int
position
= 20;
for
(
int
i
= 0;
i
<4;
i
++){
g
.drawString(
rand
.nextInt(10)+
""
,
position
, 20);
//给图片填充文字
position
+= 20;
}
//添加9条干扰线
for
(
int
i
= 0;
i
<9;
i
++){
g
.drawLine(
rand
.nextInt(
width
),
rand
.nextInt(
height
),
rand
.nextInt(
width
),
rand
.nextInt(
height
));
}
//将图片对象以流的方式输出到客户端
ImageIO.write(
img
,
"jpg"
,
resp
.getOutputStream());
}
使用
ValidateCode
包
ValidateCode
vc
=
new
ValidateCode(110, 25, 4, 9);
vc
.write(
resp
.getOutputStream());
6、客户端不设置缓存
//告诉客户端不适用缓存
resp
.setHeader(
"pragma"
,
"no-cache"
);
resp
.setHeader(
"cache-control"
,
"no-cache"
);
resp
.setHeader(
"expires"
,
"0"
);
7、3秒刷新
resp
.setContentType(
"text/html; charset=UTF-8"
);
// resp.setIntHeader("refresh", 1);
// Random rand = new Random();
// resp.getWriter().write(rand.nextInt()+"");
resp
.getWriter().write(
"注册成功!3秒钟跳到主页"
);
resp
.setHeader(
"refresh"
,
"3;url=/Servlet/demo01"
);
8、请求重定向
// //告诉客户端要重新定向新的资源
// resp.setStatus(302);
// //高速浏览器要去访问哪个URL
// resp.setHeader("location", "/Servlet/demo01");
//请求重定向
resp
.sendRedirect(
"/Servlet/demo01"
);
9、Response细节
- getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOutputStream、Printwriter对象
- getOutputStream和getWriter这两个方法相互排斥,调用了其中的任何一个方法后,就不能再调用另一方法,会抛异常
- Servlet程序向ServletOutputStream或Printwriter对象中写入的数据将被Servlet引擎从Response里面获取,Servlet引擎将这些数据当做响应消息的正文,然后与响应状态行和各响应头组合后输出到客户端
- Servlet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象
三、HttpServletRequest
1、请求行
Get http://localhost:8080/day09/servlet/req1?username=zs http/1.1
getMethod(); 获得请求方式
***getRequestURL();返回客户端发出请求时的完整URL。
***getRequestURI(); 返回请求行中的资源名部分。
*****getContextPath(); 当前应用的虚拟目录 /day09_01_request
getQueryString() ; 返回请求行中的参数部分
2、请求消息头
* String getHeader(String name) 根据头名称得到头信息值
Enumeration getHeaderNames() 得到所有头信息name
Enumeration getHeaders(String name) 根据头名称得到相同名称头信息值
3、请求正文
与获取表单数据相关的方法
<input type="text" name="username" />
*** getParameter(name) 根据表单中name属性的名,获取value属性的值方法
*** getParameterValues(String name)专业为复选框取取提供的方法
getParameterNames() 得到表单提交的所有name的方法
*** getParameterMap 到表单提交的所有值的方法 //做框架用,非常实用
getInputStream 以字节流的方式得到所有表单数据
与操作非表单数据相关的方法(request也是一个域对象)
*** void setAttribute(String name, Object value);
*** Object getAttribute(String name);
Void removeAttribute(String name);
与请求转发相关的方法
//得到请求转发或请求包含的协助对象
RequestDispatcher getRequestDispatcher(String path)
*** forward(ServletRequest request, ServletResponse response) //转发的方法
include(ServletRequest request, ServletResponse response) //请求包含 两个request对象变成同一个
与请求编码相关的方法:
//解决post方式编码
*****request.setCharacterEncoding("UTF-8"); //告诉服务器客户端什么编码,只能处理post请求方式
//解决get方式编码
String name = new String(name.getBytes("iso-8859-1"),"UTF-8");
4、
@Override
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
req
.setCharacterEncoding(
"UTF-8"
);
try
{
User
user
=
new
User();
System.
out
.println(
"封装前:"
+
user
);
Map<String,String[]>
map
=
req
.getParameterMap();
for
(Map.Entry<String,String[]>
e
:
map
.entrySet()) {
String
name
=
e
.getKey();
String[]
value
=
e
.getValue();
//创建一属性描述器
PropertyDescriptor
pd
=
new
PropertyDescriptor(
name
, User.
class
);
//得到setter属性
Method
setter
=
pd
.getWriteMethod();
if
(
value
.
length
==1){
setter
.invoke(
user
,
value
[0]);
//给一个值的变量赋值
}
else
{
setter
.invoke(
user
, (Object)
value
);
//相关于给复选框赋值
}
}
System.
out
.println(
"封装后:"
+
user
);
}
catch
(Exception
e
) {
e
.printStackTrace();
}
}
5、框架
@Override
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
try
{
User
user
=
new
User();
System.
out
.println(
"封装前:"
+
user
);
BeanUtils.populate(
user
,
req
.getParameterMap());
System.
out
.println(
"封装数据后:"
+
user
);
}
catch
(Exception
e
) {
e
.printStackTrace();
}
}
6、请求与转发 转发永远在该应用内,不返送回浏览器,由服务器完成
@Override
protected
void
doGet(HttpServletRequest
req
, HttpServletResponse
resp
)
throws
ServletException, IOException {
System.
out
.println(
"1111"
);
String
s
=
"aaaa"
;
req
.setAttribute(
"a"
,
s
);
req
.getRequestDispatcher(
"/demo2"
).forward(
req
,
resp
);
System.
out
.println(
"3333"
);
}
7、转发与重定向的区别:
转发:
- request 由服务器执行
- 客户端只发送一次请求
- 地址栏不变
- 转发能够传递数据
- 转发也是一个域对象 servletContext
- 立马跳转至其他网页再执行剩下的语句
重定向
- response 由客户端执行
- 客户端会发送两次请求
- 地址栏会发生改变
- 不能传递数据
- 可以跳转到其他应用
- 全部执行完本servlet再执行另外一个servlet