request
服务器会把客户端的请求数据封装到request对象中,request就是请求数据的载体
一.获取常用信息:
- 获取客户端IP:案例:封IP。request.getRemoteAddr()
- 获取请求方式:request.getMethod()
二.获取HTTP请求头
- String getHeader(String name),适用于单值头
- Enumeration<String> getHeaders(String name),适用于多值头
- int getIntHeader(String name),适用于单值int类型的请求头
- long getDateHeader(String name),适用于单值毫秒类型的请求头
1.通过User-Agent识别用户浏览器版本
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userAgent = req.getHeader("User-Agent");
System.out.println(userAgent);
if(userAgent.toLowerCase().contains("chrome")){
System.out.println("你使用的是谷歌!");
}else if(userAgent.toLowerCase().contains("firefox")){
System.out.println("你使用的是火狐!");
}
}
}
2.防盗链,如果请求不是通过本站的超链接发出来的,则发送错误码404
使用referer头判断:
如果来源为自己网站发出的超链接,则跳转到相应的地址,否则发出相应错误,这个实例中添加了一个a.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/temp/AServlet">请求头案例</a>
</body>
</html>
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String referer = req.getHeader("Referer");
System.out.println(referer);
if(referer == null || !referer.contains("localhost")){
resp.sendError(404,"不让你看!");
}else{
System.out.println("hello");
}
}
}
三.获取请求URL
例子:http://localhost:8080/temp/AServlet?username=xxx&password=123
- String getSchema(),获取协议 HTTP
- String getServerName(),获取服务器名 localhost
- String getServerPort(),获取服务器端口 8080
- String getContextPath(),获取项目名 /temp
- String getServletPath(),获取Servlet路径 /AServlet
- String getQueryString(),获取参数部分,即问号后面的部分 username=xxx&passwrod=123
- String getRequestURI(),获取请求URI,等于项目名+Servlet路径 /temp/AServlet
- String getRequestURL(),获取请求URL,等于不包含参数的整个请求路径 http://localhost:8080/temp/AServlet
四.获取请求参数
-
String getParameter(String name),获取指定名称的请求参数值,适用于单值请求参数
-
Map<String ,String[]> getParameterMap();获取所有请求参数,适用于多值请求参数
-
String[] getParameterValues(String name),获取指定名称的请求参数值,适用于多值请求参数
获取请求参数实例,表单POST(基本注册)+ a标签GET
html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/temp/AServlet?username1=xxx&password1=yyy">提交</a>
<form action="/temp/AServlet" method = "post">
用户名:<input type="text" name="username" /><br>
密 码:<input type="password" name="password"/><br>
爱 好:<input type="checkbox" value="sj" name="hobby"/>睡觉
<input type="checkbox" value="cf" name="hobby"/>吃饭
<input type="submit" value="提交"/>
</form>
</body>
</html>
JAVA代码
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(req.getParameter("username1"));
System.out.println(req.getParameter("password1"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO 自动生成的方法存根
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
}
}
五.请求转发和请求包含
有时一个请求需要多个Servlet协作才能完成,所以需要在一个Servlet中跳到另一个Servlet
一个请求跨多个Servlet,需要使用转发和包含。
- 请求转发:由下一个Servlet完成响应体,当前Servlet可以保留响应头,当前Servlet不能完成响应体
- 请求包含:有两个或多个Servlet共同完成响应体
- 无论是请求包含还是请求转发,都在一个请求范围内,使用同一个request和response,如图所示
- RequestDispatcher rd = req.getRequestDispatcher("/BServlet");
- 请求转发:rd.forward(req,resp);
- 请求包含:rd.include(req,resp);
实例:
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet");
resp.getWriter().print("Hello AServlet");
RequestDispatcher rd = req.getRequestDispatcher("/BServlet");
rd.forward(req, resp);//请求转发
//rd.include(req, resp);//请求包含
}
}
public class BServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet");
resp.getWriter().print("Hello BServlet");
}
}
六.request域
- void setAttribute(String name,Object value)
- Object getAttribute(String name)
- void removeAttribute(String name)
- 同一请求范围内使用request.setAttribute()、request.getAttribute()来传值
七.请求转发和重定向的区别
- 请求转发是一个请求一个响应,重定向是两个转发两个响应
- 请求转发地址栏不变,而重定向会显示后一个请求的地址
- 请求转发只能转发到本项目其他Servlet,而重定向不止能重定向到本项目的其他Servlet,还能定向到其他项目
- 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名
- 请求转发比重定向效率高,因为转发只有一个请求
- 需要地址栏发生变化,那么必须使用重定向
- 需要在下一个Servlet中获取request域中的数据,必须要使用转发
八.请求编码
客户端首先要打开一个页面,然后在页面中提交表单或点击超链接,在请求这个页面时,服务器响应的编码是什么,那么客户端发送请求时的编码就是什么
服务器默认使用ISO-8859-1来解码,所以一定出现乱码,ISO不支持中文
解决办法:
- POST请求:
只需要在获取参数之前调用request.setCharacterEncoding("utf-8")
- GET请求:
适用于tomcat8以下的服务器,tomcat8不需要反编
String name = request.getParameter("name");
反编:
byte[] bytes = name.getBytes("ISO-8859-1");
name = new String(bytes,"utf-8");
实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/temp/AServlet?username1=张三">提交</a>
<form action="/temp/AServlet" method = "post">
用户名:<input type="text" name="username" /><br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
public class AServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("username1");
byte[] bytes = name.getBytes("iso-8859-1");
name = new String(bytes,"utf-8");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String name = req.getParameter("username");
System.out.println(name);
}
}