前 言
人总是要有梦想的,也许哪天就实现了呢!
如果有不正确之处,还望赐教,毕竟我只是初学者!
一、Servelt 其他实现方式
前面我们是通过实现Servlet接口来创建Servlet的,现在我们通过继承Servlet的实现类HttpPServlet来创建我们的Servlet。
@WebServlet(value = "/show")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("post" + username + "," + password);
}
}
二、HTTP 协议
1、概 述
HTTP协议(Hyper Text Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。HTTP是一个基于TCP/IP通信协议来传递数据的应用层协议。
2、HTTP 特点
- HTTP是无状态的:每次请求之间相互独立,不能进行数据交互
- HTTP协议默认端口号为80
- HTTP是无连接的:每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接
3、HTTP 版本介绍
- 1.0版本:在该版本中,每完成一次请求/响应就断开连接。其特点是简单、易于管理。
- 1.1版本:由于1.0版本每次连接只能完成一次请求/响应,这样会导致效率低下。在该版本中,允许一个连接可以进行多次请求/响应。
- 2.0版本:在该版本中,效率更快。
4、HTTP 请求消息结构
-
请求行:请求行中包括URL、请求协议、协议版本号、请求方式
-
请求头:请求头中包括浏览器告诉服务器的一些信息
请求头中通常包含User-Agent和Referer
User-Agent:告诉服务器,访问网页时浏览器的版本信息扫描二维码关注公众号,回复: 9975113 查看本文章Referer:告诉服务器,当前请求是从哪里发送来的
-
请求空行:用于分割POST请求的请求头和请求体的
-
请求体:封装POST请求信息的请求参数的
5、请求方式
请求方式有七种,常用的就只有GET和POST两种请求方式
- GET:GET方式发出的请求,请求参数在请求行中,在URL后面,GET方式请求的URL长度有限,并且数据不安全,通常用来获取数据。
- POST:POST方式发出的请求,请求参数在请求体中,请求的URL也没有长度限制,相对于GET来说,数据安全,一般用来提交表单数据。
三、Request 对象
1、概 述
Request对象是请求对象,通过该对象可以获取请求信息。Request对象是由Tomcat创建的,我们直接使用就行。
2、获取请求行数据
-
方法介绍:
1. String getMethod() - 获取请求方式 2. String getContextPath() - 获取虚拟目录(☆) 3. String getServletPath() - 获取Servlet路径 4. String getQueryString() - 获取get方式请求参数 5. String getRequestURI() - 获取请求URI(☆) 6. StringBuffer getRequestURL() - 获取请求URL 7. String getProtocol() - 获取协议及版本 8. String getRemoteAddr() - 获取客户机的IP地址
-
代码示例:
@WebServlet(value = "/method.test") public class ServletDemo5 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("请求方法:" + req.getMethod()); System.out.println("虚拟目录:" + req.getContextPath()); System.out.println("Servlet路径:" + req.getServletPath()); System.out.println("get方式请求参数:" + req.getQueryString()); System.out.println("URI:" + req.getRequestURI()); System.out.println("URL:" + req.getRequestURL()); System.out.println("协议版本:" + req.getProtocol()); System.out.println("IP地址:" + req.getRemoteAddr()); } }
2、获取请求头数据
-
方法介绍:
1. String getHeader(String name) - 通过请求头的名称获取请求头的值 2. Enumeration<String> getHeaderNames() - 获取所有的请求头名称
-
代码示例:
@WebServlet(value = "/head.test") public class ServletDemo6 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("User-Agent:" + req.getHeader("user-agent")); System.out.println("Referer:" + req.getHeader("referer")); System.out.println("Host:" + req.getHeader("host")); Enumeration<String> headerNames = req.getHeaderNames(); while (headerNames.hasMoreElements()) { System.out.println(headerNames.nextElement()); } } }
3、获取请求体数据
请求体只存在于通过POST请求方法,请求体中封装了POST请求的请求参数,获取其中的数据,需要先获取流对象,然后通过流对象去读取封装的数据。
-
方法介绍:
1. BufferedReader getReader() - 获取字符输入流,只能操作字符数据 2. ServletInputStream getInputStream() - 获取字节输入流,可以操作所有类型数据
-
代码示例及运行结果:
4、其他功能
-
获取请求参数的通用方式:不管是get请求还是post请求都适用
-
方法介绍:
1. String getParameter(String name) - 根据参数名称获取参数值 2. String[] getParameterValues(String name) - 根据参数名称获取参数值的数组,用于获取复选框的值 3. Map<String,String[]> getParameterMap() - 获取所有参数的map集合
-
代码示例:
@WebServlet(value = "/show.do") public class ServletDemo8 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String[] hobbies = req.getParameterValues("hobby"); Map<String, String[]> parms = req.getParameterMap(); System.out.println(username); for (String hobby : hobbies) { System.out.println(hobby); } Set<Map.Entry<String, String[]>> entries = parms.entrySet(); for(Map.Entry<String, String[]> entry : entries) { System.out.println(entry); } } } show.html <form action="/servlet/show.do" method="post"> <input type="text" name="username"><br> <input type="text" name="password"><br> <input type="checkbox" name="hobby">看书 <input type="checkbox" name="hobby">敲代码 <input type="submit" value="提交"> </form>
-
-
请求转发:请求转发是一种在服务器内部发生的资源跳转,但这仍是一次请求。举例:你现在去办事窗口盖章,你去了1号窗口,但是1号窗口不能给你办理,需要去3号窗口办理,此时1号业务员就去了3号窗口替你办好了,然后将文件给你,在这过程中,你只在1号窗口发起了请求,但是却转发到了3号窗口,但是你并不知道内部有什么操作,这就是请求转发。
-
特点:
- 请求转发是一次请求;
- 浏览器地址栏不发生改变;
- 只能转发到服务器内部资源中,不能指定网络资源;
-
方法:
1. RequestDispatcher getRequestDispatcher(String path) - 通过request对象获取请求转发器对象 2. forward(ServletRequest request, ServletResponse response) - 使用RequestDispatcher对象来进行转发
-
使用场景:用户注册完成后,完成自动登录。用户登录成功后跳转至主页面。
-
代码示例:
/* * 将请求转发给ServletDemo8 */ @WebServlet(value = "/forward.do") public class ServletDemo9 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getRequestDispatcher("/show.do").forward(req, resp); } }
-
-
共享数据:
-
概述:共享数据指的是在同一个作用范围内可以数据共享。即在一次请求的范围内,可以在请求转发的多个资源之间共享数据,我们称之为Request域。注意,数据共享只能存在于一次请求中,多个请求之间不能使用共享数据。
-
方法介绍:
1. void setAttribute(String name,Object obj) - 存储数据 2. Object getAttitude(String name) - 通过键获取值 3. void removeAttribute(String name) - 通过键移除键值对
-
代码示例:
@WebServlet(value = "/forward.do") public class ServletDemo9 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("name", "张三"); req.getRequestDispatcher("/request.do").forward(req, resp); } } @WebServlet(value = "/request.do") public class ServletDemo10 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = (String) req.getAttribute("name"); System.out.println("name:" + name); } }
-
5、乱码处理
-
为什么出现乱码问题:当浏览器和服务器的字符编码不同时,就会出现乱码问题。
-
注意:在Tomcat 8及以上,get方式的乱码问题已经被解决了,post方式的请求乱码需要我们自己解决。也就是说,我们解决的是post的请求乱码问题。
-
方法介绍:
setCharacterEncoding("字符编码集") - 在获取参数前设置request的编码
-
代码示例:
@WebServlet(value = "/request.do") public class ServletDemo10 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); // 在获取参数之前设置请求编码 String username = req.getParameter("username"); System.out.println(username); String name = (String) req.getAttribute("name"); System.out.println("name:" + name); } }