文章目录
1.HttpServletRequest 类
1.1.HttpServletRequest 类有什么作用
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的 信息。
1.2.HttpServletRequest 类的常用方法
- getRequestURI() 获取请求的资源路径
- getRequestURL() 获取请求的统一资源定位符(绝对路径)
- getRemoteHost() 获取客户端的 ip 地址
- getHeader() 获取请求头
- getParameter() 获取请求的参数
- getParameterValues() 获取请求的参数(多个值的时候使用)
- getMethod() 获取请求的方式 GET 或 POST
- setAttribute(key, value); 设置域数据
- getAttribute(key); 获取域数据
- getRequestDispatcher() 获取请求转发对象
API举例一:
@WebServlet("/request")
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. getRequestURI() 获取请求的资源路径
System.out.println("URI:"+req.getRequestURI());
//2. getRequestURL() 获取请求的统一资源定位符(绝对路径)
System.out.println("URL:"+req.getRequestURL());
//3. getRemoteHost() 获取客户端的 ip 地址
//在idea中使用localhost访问时,得到的客户端ip地址是:0:0:0:0:0:0:0:1
//在idea中使用真实ip 访问时,得到的客户端ip地址是:真实的客户端ip地址(10.6.114.221)
System.out.println("客户端ip地址:"+req.getRemoteHost());
//4. getHeader() 获取请求头
System.out.println("请求头User-Agent:"+req.getHeader("User-Agent"));
//7. getMethod() 获取请求的方式 GET 或 POST
System.out.println("请求方式:"+req.getMethod());
}
}
1.3.获取请求的参数
API举例二:
前端代码:
<body>
<form action="http://localhost:8080/02_servlet/parameter" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">c++
<input type="checkbox" name="hobby" value="java">java
<input type="checkbox" name="hobby" value="js">javascript<br>
<input type="submit">
</form>
</body>
@WebServlet("/parameter")
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. getParameter() 获取请求的参数
// 2. getParameterValues() 获取请求的参数(多个值的时候使用)
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
System.out.println("兴趣爱好:"+ Arrays.asList(hobby));
}
}
1.4.解决post请求中文乱码问题
req.setCharacterEncoding("UTF-8");
注意:这个API要在获取请求参数之前调用在有效。
1.5.请求的转发
什么是请求的转发?
请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。
servlet1代码:
@WebServlet("/servlet1")
public class servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的参数查看
String username = req.getParameter("username");
System.out.println("在servlet1中查看参数:"+username);
//2.给参数盖一个章并传递到servlet2 去查看
req.setAttribute("key","servlet1的章");
//3.问路:servlet2怎么走
/*
请求转发必须要以斜杠(/)打头,斜杠表示地址为:http://ip:port/工程名/
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
//4.走向servlet2
requestDispatcher.forward(req,resp);
}
}
servlet2代码:
@WebServlet("/servlet2")
public class servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的参数查看
String username = req.getParameter("username");
System.out.println("在servlet2中查看参数:"+username);
//2.查看servlet1是否盖章
Object key1 = req.getAttribute("key");
System.out.println("servlet1是否有章:"+key1);
//3.处理自己的业务
System.out.println("servlet2处理自己的业务");
}
}
在浏览器地址栏中问号后面传入参数
注意点:
可以转发到WEB-INF目录下
WEB-INF下的html页面不能通过地址栏直接访问,但是可以使用请求转发访问。
1.6.base标签的作用
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
这是web下的index.html页面<br>
<a href="a/b/c.html">c.html</a>
<a href="http://localhost:8080/02_servlet/forward">请求转发:c.html</a>
</body>
</html>
c.html(这是a目录下的b目录下的c.html页面)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
这是a目录下的b目录下的c.html页面<br>
<a href="../../index.html">跳回首页</a>
</body>
</html>
ForwardC类
@WebServlet("/forward")
public class ForwardC extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("经过了ForwardC程序");
req.getRequestDispatcher("/a/b/c.html").forward(req,resp);
}
}
执行代码收发现:
点击“c.html”和“跳回首页”可以正常跳转
点击“请求转发:c.html”和“跳回首页”无法正常跳转
分析原因1:
当我们点击a标签进行跳转的时候,浏览器地址栏中的地址是:
http 😕/localhost:8080/02_servlet/a/b/c.html
跳转回去的a标签路径是:…/…/index.html
所有相对路径在工作时侯都会参照当前浏览器地址栏中的地址来进行跳转。
参照后得到的地址是:htt p://localhost:8080/02_servlet/index.html(正确的跳转路径)
分析原因2:
当我们使用请求转发进行跳转的时候,浏览器地址栏中的地址是:
http 😕/localhost:8080/02_servlet/forward
跳转回去的a标签路径是:…/…/index.html
所有相对路径在工作时侯都会参照当前浏览器地址栏中的地址来进行跳转。
参照后得到的地址是:htt p://localhost:8080/index.html(错误的跳转路径)
解决办法:
base标签可以设置当前界面中所有相对路径工作时,参照哪个路径来进行跳转。
在c.html中设置:
1.7.Web 中的相对路径和绝对路
在 javaWeb 中,路径分为相对路径和绝对路径两种:
- 相对路径:
- . 表示当前目录
- … 表示上一级目录
- 资源名 表示当前目录/资源名
- 绝对路径:
- http 😕/ip:port/工程路径/资源路径
- http 😕/ip:port/工程路径/资源路径
在实际开发中,路径都使用绝对路径,而不简单的使用相对路径。
- 绝对路径
- base+相对
1.8.web 中 / 斜杠的不同意义
在 web 中 / 斜杠 是一种绝对路径。
-
/ 斜杠 如果被浏览器解析,得到的地址是:http: //ip:port/
-
举例
<a href="/">斜杠</a>
地址栏得到结果为:http: //localhost:8080/
-
-
/ 斜杠 如果被服务器解析,得到的地址是:http: //ip:port/工程路径
-
举例
1.< url-pattern>/servlet1< /url-pattern>
2.servletContext.getRealPath(“/”);
3.request.getRequestDispatcher(“/”);
-
特殊情况:
response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到 http: //ip:port
2.HttpServletResponse 类
2.1.HttpServletResponse 类的作用
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息。
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletResponse 对象来进行设置
2.2.两个输出流的说明
字节流 | getOutputStream(); | 常用于下载(传递二进制数据) |
---|---|---|
字符流 | getWriter(); | 常用于回传字符串(常用) |
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
报错信息:
2.3.如何往客户端回传数据
要求:往客户端回传 字符串 数据。
@WebServlet("/response")
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 要求:往客户端回传 字符串 数据。
PrintWriter writer = resp.getWriter();
writer.write("response's content!!");
}
}
2.4.响应的乱码解决
@WebServlet("/response")
public class ResponseIOServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println(resp.getCharacterEncoding());//服务器默认字符集ISO-8859-1,不支持中文字符
//方法一:不推荐
//设置服务器字符集为utf-8
//resp.setCharacterEncoding("UTF-8");
//设置浏览器也使用utf-8
//resp.setHeader("Content-Typ","text/html;charset=UTF-8");
//方法二:爽
// 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8");
// 要求:往客户端回传 字符串 数据。
PrintWriter writer = resp.getWriter();
// writer.write("response's content!!");
writer.write("永远嘀神");
}
}
2.5.请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向(因为之前的地址可能已经被废弃)。
请求重定向的第一种方案:(不推荐)
// 设置响应状态码 302 ,表示重定向,(已搬迁)
resp.setStatus(302);
// 设置响应头,说明 新的地址在哪里
resp.setHeader("Location", "http://localhost:8080");
Response1类:
@WebServlet("/response1")
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("response1");
resp.setStatus(302);
resp.setHeader("Location","http://localhost:8080/02_servlet/response2");
}
}
Response2类:
@WebServlet("/response2")
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("response2");
resp.getWriter().write("response's result!");
}
}
请求重定向的第二种方案(推荐使用):
resp.sendRedirect("http://localhost:8080");