Request
1.获取请求的基本信息
1>获取请求的url和uri
2>获取url后面的请求参数部分的字符串
3>获取请求方式
4>获取主机名,IP地址
5>获取 Contexpath
String
url
=
request
.getRequestURL().toString();
System.
out
.println(
url
);
String
uri
=
request
.getRequestURI().toString();
System.
out
.println(
uri
);
String
params
=
request
.getQueryString();
System.
out
.println(
params
);
String
method
=
request
.getMethod();
System.
out
.println(
method
);
String
addr
=
request
.getRemoteHost() +
request
.getRemotePort() +
request
.getRemoteAddr() +
"==user="
+
request
.getRemoteUser();
System.
out
.println(
"addr: "
+
addr
);
String
contextPath
=
request
.getContextPath();
response
.sendRedirect(
contextPath
+
"/index.jsp"
);
2.通过 Referer 请求头实现防盗链
Referer请求头的值表示从哪个网页上的链接访问到当前链接
盗链: 其他站点通过超链接链接到自己的站点,从而实现资源的盗窃称为盗链.
@WebServlet
(
"/NewsServlet"
)
public
class
NewsServlet
extends
HttpServlet {
private
static
final
long
serialVersionUID
= 1L;
protected
void
doGet(HttpServletRequest
request
, HttpServletResponse
response
)
throws
ServletException, IOException {
response
.setContentType(
"text/html;charset=utf-8"
);
String
referer
=
request
.getHeader(
"Referer"
);
if
(
referer
==
null
||
""
.equals(
referer
) || !
referer
.contains(
"localhost/"
)) {
response
.sendRedirect(
request
.getContextPath() +
"/index.jsp"
);
}
response
.getWriter().write(
"习大大吃包子...."
);
}
protected
void
doPost(HttpServletRequest
request
, HttpServletResponse
response
)
throws
ServletException, IOException {
doGet(
request
,
response
);
}
}
如果Referer为空或者不是从自己的站点访问过来就重定向到自己站点的主页.
2.获取请求参数
Map
params
=
request
.getParameterMap();
for
(String
name
:
params
.keySet()) {
String
value
=
request
.getParameter(
name
);
System.
out
.println(
"name="
+
name
+
", value="
+
value
);
}
解决请求乱码问题:
request.setCharacterEncoding("
Utf
-8");
如果上面的代码只能解决POST的乱码问题, 则可以自行进行解码操作
String
userName
=
request
.getParameter(
"username"
);
userName
=
new
String(
userName
.getBytes(
"ISO8859-1"
),
"UTF-8"
);
前段使用 UTF-8 进行编码, 传输到服务器, 服务器可以使用 ISO8859-1 解码得到UTF-8编码后的码值, 然后通过new String(bytes, charset)的方式进行解码.
3.设置和获取域属性
Object
attr
=
request
.getAttribute(
"attr"
);
request
.setAttribute(
"key"
,
"value"
);
request
.removeAttribute(
"attr"
);
Enumeration
attributeNames
=
request
.getAttributeNames();
一般我们的应用是servlet处理数据, 将处理好的数据放到request域中,然后带到jsp页面上进行展示操作.
- 请求转发与请求包含
请求转发:
request
.getRequestDispatcher(
"/DispatcherTest2"
).forward(
request
,
response
);
或
this
.getServletContext().getRequestDispatcher(
"/DispatcherTest2"
).forward(
request
,
response
);
Note:
1)一次请求只能转发一次, 否则会发生下面的异常: -- 可以得到第一次转发获取的数据
java.lang.IllegalStateException
: Cannot forward after response has been committed
2)当有数据已经写到客户端时再请求转发也会抛出异常.
3)若转发前有数据写入到response缓冲区,则请求转发会清空response缓冲区的实体内容, 但不会清空请求头信息.
请求包含:
当需要将多个servlet的输出合并到一块打给浏览器时可以使用请求包含
request
.getRequestDispatcher(
"/DispatcherTest2"
).include(
request
,
response
);
或
this.getServletContext().getRequestDispatcher("/DispatcherTest2").include(request, response);
Notice:
1)被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略.
2)常被用来进行页面布局
请求重定向:
response
.sendRedirect(
request
.getContextPath() +
"/DispatcherTest2"
);
Notice:
1) 不能在数据已经发送到浏览器之后再进行请求重定向:
java.lang.IllegalStateException
: Cannot call sendRedirect() after the response has been committed
2) 在请求重定向之前写入到response缓冲区的数据会被清空
3) 一次请求只能重定向一次
Summary:
请求重定向地址栏会发生变化.请求转发地址栏不发生变化.
请求重定向两次请求两次响应.请求转发一次请求一次响应.
如果需要在资源跳转时利用request域传递域属性则必须使用请求转发
如果希望资源跳转后修改用户的地址栏则使用请求重定向
如果使用请求转发也可以重定向也可以,则优先使用请求转发,减少浏览器对服务器的访问次数减轻服务器的压力.
Response
1.response
ServletResponse -- 通用的response提供了一个响应应该具有最基本的属性和方法
|
|-HttpServletResponse -- 在ServletResponse的基础上针对于HTTP协议增加了很多强化的属性和方法
2.输出数据
1)getOutputStream字节输出流
response.getOutputStream().write("中国".getBytes("
utf
-8"));
string.getBytes()如果没有指定编码方式,会使用平台默认的编码方式
2)getWriter字符输出流
response
.getWriter().write(
"北京"
);
Notice: getWriter和getOutputStream在一次请求中只能使用一个
使用字符输出流输出中文时, 由于网线上只能输出高低电平,如果没有指定编码方式,那么服务器在发送数据时会使用默认的ISO-8859-1对数据编码(该码表中没有汉字, 因此汉字会被编码为?, 传送到浏览器上的数据实际就是?).
3)解决乱码
1> 通知服务器发送数据时使用utf-8编码
response.setCharacterEncoding("
utf
-8");
2> 通知浏览器接受数据时使用utf-8解码
response.setHeader("Content-Type", "text/
html
;
charset
=
utf
-8");
3> Notice:
a. response对象中对Content-Type响应头进行了封装,可以使用一下代码代替 2>
response
.setContentType(
"text/html;charset=utf-8"
);
b. 如果设置了Content-Type,服务器会自动的设置 characterEncoding,因此解决乱码只需要设置Content-Type响应头一行代码就可以了,但是为了代码的可读性更高,一般还是建议同时设置 characterEncoding 和 Content-Type.
3)实现下载
protected
void
doGet(HttpServletRequest
request
, HttpServletResponse
response
)
throws
ServletException, IOException {
response
.setHeader(
"Content-Disposition"
,
"attachment;filename="
+ URLEncoder.
encode
(
"美女.jpg"
)
);
InputStream
in
=
new
FileInputStream(
this
.getServletContext().getRealPath(
"美女.jpg"
));
OutputStream
out
=
response
.getOutputStream();
byte
[]
bytes
=
new
byte
[1024];
int
len
= -1;
while
(-1 != (
len
=
in
.read(
bytes
))) {
out
.write(
bytes
, 0,
len
);
}
in
.close();
}
4) 实现定时刷新
1.Servlet实现
response
.setContentType(
"text/html;charset=utf-8"
);
response
.getWriter().write(
"恭喜您注册成功, 3秒后回到主页"
);
response
.setHeader(
"Refresh"
,
"3;url=OutServlet"
);
2.html实现
<
meta
charset
=
"UTF-8"
>
<
meta
http-equiv
=
"Refresh"
content
=
"3; url=index.jsp"
>
<
title
>
Insert title here
title
>
head
>
<
body
>
恭喜您注册成功, 3秒后回到主页....
body
>
5)控制浏览器是否缓存
response
.setIntHeader(
"Expires"
, -1);
response
.setHeader(
"Cache-Control"
,
"no-cache"
);
response
.setHeader(
"Pragma"
,
"no-cache"
);
response
.getWriter().write(
new
Date().
toLocaleString
()
);
6)实现请求重定向
response
.sendRedirect(
this
.getServletContext().getContextPath());
7)输出验证码图片
package
com.inetsoft.response;
import
java.awt.Color;
import
java.awt.Font;
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.annotation.WebServlet;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
/**
*
@Description
: 用于输出验证码图片的
Servlet
*
@Warning
:
*
@Author
DreamLi
*
@Package
Day04
-
Response
-
Request
--
com.inetsoft.response.ValidServlet
*
@Date
: 2017年12月17日 下午4:51:22
*
@Version
: 1.0.0
*/
@WebServlet
(
"/ValidServlet"
)
public
class
ValidServlet
extends
HttpServlet {
private
static
final
long
serialVersionUID
= -70985881600765636L;
private
Random
rand
=
new
Random();
public
void
doGet(HttpServletRequest
request
, HttpServletResponse
response
)
throws
ServletException, IOException {
//设置响应头让浏览器不再缓存验证码图片
response
.setDateHeader(
"Expires"
, -1);
response
.setHeader(
"Cache-Control"
,
"no-cache"
);
response
.setHeader(
"Pragma"
,
"no-cache"
);
//创建验证码图片
//1.创建一张图片到内存中
int
width
= 120;
int
height
= 30;
BufferedImage
img
=
new
BufferedImage(
width
,
height
, BufferedImage.
TYPE_INT_RGB
);
//2.获取该图片上的画笔
Graphics2D
g
= (Graphics2D)
img
.getGraphics();
//3.设置背景色以及图片边框
g
.setColor(
new
Color(199,237,204));
g
.fillRect(0, 0,
width
,
height
);
g
.setColor(Color.
black
);
g
.drawRect(0, 0,
width
-1,
height
-1);
//4.设置干扰线
int
lineNum
= randNumber(3,7);
//干扰线的条数
for
(
int
i
= 0;
i
<
lineNum
;
i
++){
g
.setColor(
new
Color(randNumber(0,255),randNumber(0,255),randNumber(0,255)));
g
.drawLine(randNumber(0,
width
), randNumber(0,
height
),randNumber(0,
width
), randNumber(0,
height
) );
}
//5.设置验证码内容
int
row
= 10;
int
col
= 22;
g
.setFont(
new
Font(
"黑体"
, Font.
BOLD
, 20));
StringBuffer
buffer
=
new
StringBuffer();
for
(
int
i
= 0;
i
< 4;
i
++){
g
.setColor(
new
Color(randNumber(0,255),randNumber(0,255),randNumber(0,255)));
double
theta
= Math.
toRadians
(randNumber(-50, 50));
g
.rotate(
theta
,
row
,
col
);
int
num
= randNumber(0, 9);
buffer
.append(
num
);
g
.drawString(
num
+
""
,
row
,
col
);
g
.rotate(0-
theta
,
row
,
col
);
row
+= 30;
}
//将验证码加入到session
request
.getSession().setAttribute(
"valid"
,
buffer
.toString());
System.
out
.println(
buffer
);
//6.写入到输出流中
ImageIO.
write
(
img
,
"jpg"
,
response
.getOutputStream());
}
/**
* 产生一个区间里面的随机数
*
@param
left 区间左值
*
@param
right 区间右值
*
@return
区间里面的一个随机数
*/
private
int
randNumber(
int
left
,
int
right
){
return
rand
.nextInt(
right
-
left
) +
left
;
}
public
void
doPost(HttpServletRequest
request
, HttpServletResponse
response
)
throws
ServletException, IOException {
doGet(
request
,
response
);
}
}
最后, 附上demo地址: https://github.com/DreamLi1314/Day04-Response-Request.git