HTTP协议:

网络模型:7种

1.物理层
2.数据链路层
3.网络层
4.传输层
5.会话层
6.表示层
7.应用层

什么是hhtp:

http协议简介:B/S系统,需要用户远程链接服务器站点,必须要遵循一定的网络协议,这里规定在远程访问站点的时候,需要遵循HTTP协议,这个协议是TCP/IP协议的应用协议。
HTTP超文本传输协议
HTTP有两个版本:
1.HTTP/1.0版本
2.HTTP/1.1版本
两个协议的区别:
1.0版本的协议,当链接后,数据传输结束会断开连接,如果需要再次传输,需要再次链接。
1.1.版本的协议。当链接后。数据传输结束,会保持连接,除非主动关闭连接。

HTTP协议的请求和响应

通过客户端(包括浏览器)发送请求,称之为HTTP的请求,当发生请求之后,服务器需要给客户端响应数据,这个过程称为HTTP的响应。
注意:以后只要提到请求,一定是客户端发送给服务器;如果是提到响应,一定是服务器对客户端发送了数据。
请求到 示例图:
对请求里面参数进行说明
在请求行里面有请求方式的区别:1.post与get方式
1.两个方式的传参不一样。get传参方式是将数据直接明文写在请求URL地址里面
2.两个方式的传输数据的大小不一样,get请求方式传输数据大小最大为1k,post请求方式理论上数据的大小是没有限制的。如果数据量过大,建议分片传输。
请求头中的细节:

  • Accept:浏览器告诉服务器,我所支持的数据格式。
  • Accept-Encoding:浏览器告诉服务器,我所支持的压缩格式
  • Accept-Language:浏览器告诉服务器,我所支持的语言环境
  • Cache-Control:浏览器告诉服务器,缓存最长时效。
  • Connection:浏览器告诉服务器,是保持连接还是断开连接,Keep-Alive:保持连接
  • Host:浏览器告诉服务器,我所请求的主机及端口
  • User-Agent:浏览器告诉服务器,当前使用的浏览器的版本
  • Date:浏览器告诉服务器,当次请求发生的时间。
  • Referer:浏览器告诉服务器,我是从哪个页面跳转过来的
  • Cookie:后续会有专门的专题讲解。

    HTTP协议的响应

    响应行
    在响应行里面,HTTP/1.1表示协议的版本,200表示状态码,ok表示原因或者描述
    状态码:表示该次请求后,服务器给浏览器或者客户端响应的状态,由状态码来表示,100-599之间。

  • 100-199:说明该次请求成功,但是服务器要等待客户端进一步的请求,很少见。

  • 200-299:该次请求成功,并且响应也成功,可以说明这次请求响应已经完成。
  • 300-399:说明该次请求成功,但是,需要客户端进一步有的处理。很少见
  • 400-499:说明该次请求成功,但是服务器找不到请求的资源,常见的404
  • 500-599:说明请求失败,服务器炸了,一般错误是500

响应头:

  • Accept-Ranges:服务器告诉浏览器,发送的数据类型
  • Connection:服务器告诉浏览器,是否保持连接。
  • Content-Length:服务器告诉浏览器,本次响应的数据长度。
  • Content-Type:服务器告诉浏览器,本次响应内容的数据格式以及编码集,(后面用于设置编码集要使用的响应头字段)。
  • Date:当次响应的时间
  • Keep-Alive: 保持连接的时间限制
  • Last-Modified:最后缓存的时间

    Servlet接口

    概念:javaweb程序开发,项目就是一个java应用程序,用sun公司提供的接口Servlet,只要实现里面的一些接口,并按照规则把接口中的代码写完,就是一个javaweb项目。如果要完成一个javaweb项目的开发

    编写一个Servlet实现类

    Servlet接口,根据Servlet的API知道,Servlet存在3个生命周期的方法
    init():用于初始化的方法,没有特殊代码处理的时候,发送请求的时候执行该方法
    service():用于处理请求和响应的方法,程序员编写代码的部分。
    destroy():销毁的方法,如果没有特殊代码处理,关闭服务器的时候销毁。
    Servlet接口中,也提供了获取Servlet初始化信息的方法
    getServletConfig();重点,该方法主要能够得到一个ServletConfig对象。后续会专门学习
    getServletInfo():只能获取Servlet版本号等信息。一般不用。
    Servlet的API中,提到了在程序员编写Servlet的时候,实际上不需要实现Servlet接口,可以选择继承genericServlet或者HttpServlet
    说明:虽然这两个类都是可以实现一个Servlet程序开发的,但是从API上可以看到,实际HttpServlet是GenericServlet的子类,因此,推荐使用HttpServlet

    用实现GenericServlet来实现javaweb程序开发

  • 说明:下面的程序是用继承GenericServlet类的方式进行实现javaweb程序的开发,直接提示了要重写service方法,里面的两个参数:ServletRequest和ServletResponse,分别为请求对象和响应对象。 ```java /**

    • Title: ServletDemo1

    • Description: 用继承GenerciServlet的方式进行开发javaweb项目

    • @author Alon
    • @date 2020年10月21日 上午10:11:57
    • @version 1.0 / public class ServletDemo1 extends GenericServlet{ /
      • Title: service

      • Description:

      • @param request 请求对象,获取浏览器发送给服务器的数据
      • @param response 响应对象,由服务器发送给浏览器数据
      • @throws ServletException
      • @throws IOException
      • @see javax.servlet.GenericServlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { System.out.println(“成功请求到了服务器里面的Servlet代码”); //服务器向浏览器发送一些数据 OutputStream out = response.getOutputStream(); out.write(“123123”.getBytes()); //关闭流 out.close(); }

}

  1. 需要在WebContent下面的WEB-INF里面新建一个web.xml配置文件,用于配置映射信息
  2. ```xml
  3. <?xml version="1.0" encoding="UTF-8"?>
  4. <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
  5. <!-- 在该配置文件中配置Servlet的映射信息,简单理解就是配置Servlet和Servlet-mapping -->
  6. <servlet>
  7. <!-- 配置一个Servlet的名称,建议和类名一致 -->
  8. <servlet-name>ServletDemo1</servlet-name>
  9. <!-- 配置对应Servlet的全路径 -->
  10. <servlet-class>com.woniuxy.demo.ServletDemo1</servlet-class>
  11. </servlet>
  12. <!--配置Servlet映射信息 -->
  13. <servlet-mapping>
  14. <!-- 配置映射名称,要求和Servlet里面的servlet-name一致 -->
  15. <servlet-name>ServletDemo1</servlet-name>
  16. <!-- 映射名称 -->
  17. <url-pattern>/demo1</url-pattern>
  18. </servlet-mapping>
  19. </web-app>
  • 用浏览器请求到Servlet并执行

image.png

用实现HttpServlet来实现javaweb程序开发

先编写Servlet代码。

2.2 用实现HttpServlet来实现javaweb程序开发

  • 先编写Servlet代码。 ```java /**

    • Title: ServletDemo2

    • Description: 使用HttpServlet实现javaweb代码的开发

    • @author Alon
    • @date 2020年10月21日 上午11:48:41
    • @version 1.0 */ public class ServletDemo2 extends HttpServlet{

      @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      1. doPost(request,response);

      }

      /*

      • Title: doPost

      • Description:

      • @param request 请求对象 获取浏览器向服务器发送的数据
      • @param response 响应对象 将服务器的数据发送给浏览器
      • @throws ServletException
      • @throws IOException
      • @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println(“请求成功”);

        //由服务器给浏览器写出数据 OutputStream out = response.getOutputStream(); out.write(“abc”.getBytes()); //关闭资源 out.close(); } }

  1. - web.xml配置文件中配置Servlet对应的类代码
  2. ```xml
  3. <!-- 配置ServletDemo2的映射 -->
  4. <servlet>
  5. <servlet-name>ServletDemo2</servlet-name>
  6. <servlet-class>com.woniuxy.demo.ServletDemo2</servlet-class>
  7. </servlet>
  8. <!-- 映射配置 -->
  9. <servlet-mapping>
  10. <servlet-name>ServletDemo2</servlet-name>
  11. <url-pattern>/demo2</url-pattern>
  12. </servlet-mapping>

2.3 实现请求的步骤

说明:实际上HttpServlet是GenericServlet的子类,在GenericServlet里面处理请求使用的是service方法,在service方法中会自动的判断是什么请求,并处理请求,但是到了HttpServlet将service方法进行了拆分,拆分成指定请求执行指定的doXXX()方法。

2.4 初始化方法和销毁方法

  • 初始化方法:init()

初始化的方法,在启动服务器的时候是不会执行的,是在发送第一条请求的时候才会执行,只执行一次。

  1. @Override
  2. public void init() throws ServletException {
  3. System.out.println("初始化的方法");
  4. }
  • 销毁的方法,在服务器关闭的时候执行

    1. @Override
    2. public void destroy() {
    3. System.out.println("服务器被销毁了");
    4. }

    三、Servlet流程及原理

    3.1 浏览器请求之后解析的步骤

  • 浏览器发出请求,链接服务器

  • 发送http请求:http://localhost:8080/WebDemo2/demo2;
  • 解析出来IP地址解析出来端口号解析出来web应用程序解析出来请求访问的资源文件创建Servlet对象,并用init初始化
  • Servlet对象调用Service方法或者别拆分出来的doxxx()方法。
  • 关闭服务器的时候,销毁Servlet对象,调用destroy方法

    3.2 Servlet对象的生命周期

  • 实现Servlet接口或者继承HttpServlet,该类所在的工程为一个web应用程序,该程序需要放到服务器里面,当服务器一旦开启,那么服务器会自动的在容器中创建一个Servlet对象。

  • 当发送第一条请求的时候,会调用init方法进行初始化Servlet对象。后续请求将不再初始化
  • 每一次调用service方法或者doGet方法或者doPost方法之前,都需要使用Servlet对象创建独立的HttpServletRequest对象和HttpServletResponse对象。
  • 调用service方法或者对应的doXXX()方法处理请求响应。
  • 当服务器关闭的时候,销毁Servlet对象。

    3.3 全局配置文件web.xml

  • 在web.xml配置文件里面,需要配置映射关系,配置servlet的标签和配置映射的标签servlet-mapping

    1. <!-- 配置Servlet的名称和类名全路径 -->
    2. <servlet>
    3. <servlet-name></servlet-name>
    4. <servlet-class></servlet-class>
    5. <!-- 设置init执行顺序,要求服务器一旦启动就执行 -->
    6. <load-on-startup>1</load-on-startup>
    7. </servlet>
    8. <!-- 配置映射关系 -->
    9. <servlet-mapping>
    10. <servlet-name></servlet-name>
    11. <url-pattern></url-pattern>
    12. </servlet-mapping>
  • 特别说明:Servlet中只有在第一次请求的时候,才会调用init方法,但是有的时候需要在服务器启动的时候,就执行init方法进行初始化容器。

  • 如何让服务器启动的时候就执行init方法?


    1

四、web服务器中其他对象

4.1 ServletConfig对象

  • 作用:获取配置文件(web.xml)中的参数,一些数据可以先配置在web.xml文件中,由ServletConfig对象进行获取,在servlet接口中提供了有参的init方法,参数为ServletConfig对象,在初始化Servlet对象的时候,会调用init方法,在这个时候,web服务器会自动将web.xml里面的参数加载到ServletConfig对象。在web.xml配置文件中配置数据

    1. <servlet>
    2. <servlet-name>ServletDemo3</servlet-name>
    3. <servlet-class>com.woniuxy.demo.ServletDemo3</servlet-class>
    4. <!-- 配置初始化参数 -->
    5. <init-param>
    6. <param-name>age</param-name>
    7. <param-value>18</param-value>
    8. </init-param>
    9. </servlet>
  • 在Servlet中获取ServletConfig对象的两种方式

方式1:通过init方法获取ServletConfig对象

  1. public class ServletDemo extends HttpServlet{
  2. //声明一个全局的ServletConfig对象
  3. private ServletConfig config;
  4. public void init(ServletConfig config){
  5. this.config = config;
  6. }
  7. public void doPost(HttpServletRequest request,HttpServletResponse response) throws Exception{
  8. String age = config.getInitParameter("age");
  9. System.out.println(age);
  10. }
  11. }

方式2:由Servlet对象直接获取

  1. public class ServletDemo extends HttpServlet{
  2. //推荐使用
  3. public void doPost(HttpServletRequest request,HttpServletResponse response) throws Exception{
  4. //通过Servlet对象获取ServletConfig对象
  5. ServletConfig config = this.getServletConfig();
  6. String age = config.getInitParameter("age");
  7. System.out.println(age);
  8. }
  9. }

练习:在web.xml配置文件中配置上数据库链接信息,当发送请求的时候,直接获取四个参数
配置参数

  1. <!-- 配置ServletDemo4 -->
  2. <servlet>
  3. <servlet-name>ServletDemo4</servlet-name>
  4. <servlet-class>com.woniuxy.demo.ServletDemo4</servlet-class>
  5. <!-- 配置参数 -->
  6. <init-param>
  7. <param-name>driver</param-name>
  8. <param-value>com.mysql.jdbc.Driver</param-value>
  9. </init-param>
  10. <init-param>
  11. <param-name>url</param-name>
  12. <param-value>jdbc:mysql://localhost:3306/shop?useUnicode=true&amp;characterEncoding=utf-8</param-value>
  13. </init-param>
  14. <init-param>
  15. <param-name>username</param-name>
  16. <param-value>root</param-value>
  17. </init-param>
  18. <init-param>
  19. <param-name>password</param-name>
  20. <param-value>root</param-value>
  21. </init-param>
  22. </servlet>
  23. <servlet-mapping>
  24. <servlet-name>ServletDemo4</servlet-name>
  25. <url-pattern>/demo4</url-pattern>
  26. </servlet-mapping>

java代码

  1. @Override
  2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //获取ServletConfig
  4. ServletConfig config = this.getServletConfig();
  5. String driver = config.getInitParameter("driver");
  6. String url = config.getInitParameter("url");
  7. String username = config.getInitParameter("username");
  8. String password = config.getInitParameter("password");
  9. }

问题:当参数过多的时候,再去一个一个的根据名称获取值比较麻烦,可以一次性获取所有的参数。

  1. @Override
  2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //获取ServletConfig
  4. ServletConfig config = this.getServletConfig();
  5. //获取所有的参数名集合
  6. Enumeration<String> e = config.getInitParameterNames();
  7. //迭代集合
  8. while(e.hasMoreElements()) {
  9. String name = e.nextElement();
  10. //根据名称获取所有的值
  11. config.getInitParameter(name);
  12. }
  13. }

4.2 ServletContext对象(非常重要)

  • 一个web容器里面,只有一个ServletContext对象,获取ServletContext对象有两种方式

方式1:通过ServletConfig对象中的getServeltContext()方法来获取ServletContext对象
ServletContext context = this.getServletConfig().getServletContext();
方式2:可以直接通过Servlet对象中的getServletContext()方法来获取ServletConext对象,推荐方式。
ServletContext context = this.getServletContext();
ServletContext的第一个作用:实现各个Servlet类中的数据共享。

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. System.out.println("请求到了Demo5");
  4. //获取ServletContext对象
  5. ServletContext context = this.getServletContext();
  6. //向context对象中获取值
  7. context.setAttribute("msg", "哈哈哈哈,我是从demo5过来的,惊喜吧");
  8. }
  1. @Override
  2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //获取ServletConext对象
  4. ServletContext context = this.getServletContext();
  5. //获取值
  6. String msg = (String)context.getAttribute("msg");
  7. System.out.println("msg = "+msg);
  8. }
  • 获取全局的配置文件值

    1. <context-param>
    2. <param-name>age</param-name>
    3. <param-value>18</param-value>
    4. </context-param>
    1. @Override
    2. public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
    3. //获取ServletContext对象
    4. ServletContext context = this.getServletContext();
    5. //获取全局的配置文件参数值
    6. String age = context.getInitParameter("age");
    7. System.out.println("demo1的age = "+age);
    8. }
    1. @Override
    2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. //获取ServletContext对象
    4. ServletContext context = this.getServletContext();
    5. //获取参数值
    6. String age = context.getInitParameter("age");
    7. System.out.println("demo2的age = "+age);
    8. }
  • 读取配置文件

使用Servlet读取工程配置文件(properties文件和XML文件),因为项目最终是在tomcat服务器里面执行的,工程运行只识别webapps里面的工程目录,而在这个目录里面根本没有src目录,原先的获取文件的路径不能使用。
方式1:直接使用ServletContext里面的getReasourceAsStream()方法获取到输入流对象

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. //读取到db.properties配置文件
  4. //获取ServletContext对象
  5. ServletContext context = this.getServletContext();
  6. //根据context对象获取输入流
  7. InputStream in = context.getResourceAsStream("/WEB-INF/classes/db.properties");
  8. //创建Properties对象
  9. Properties prop = new Properties();
  10. prop.load(in);
  11. String driver = prop.getProperty("driver");
  12. String url = prop.getProperty("url");
  13. String username = prop.getProperty("username");
  14. String password = prop.getProperty("password");
  15. System.out.println("驱动:"+driver+",请求路径:"+url+",用户名:"+username+",密码:"+password);
  16. }
  17. }

方式2:通过ServletContext中的getRealPath()方法获得绝对路径,有了绝对路径可以再使用FileInputStream类

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. //获取ServletContext对象
  4. ServletContext context = this.getServletContext();
  5. //根据虚拟路径获取绝对路径
  6. String realPath = context.getRealPath("/WEB-INF/classes/db.properties");
  7. //创建输入流对象
  8. FileInputStream in = new FileInputStream(new File(realPath));
  9. Properties prop = new Properties();
  10. prop.load(in);
  11. String driver = prop.getProperty("driver");
  12. String url = prop.getProperty("url");
  13. String username = prop.getProperty("username");
  14. String password = prop.getProperty("password");
  15. System.out.println("驱动:"+driver+",请求路径:"+url+",用户名:"+username+",密码:"+password);
  16. }

方式3:将配置文件的位置放在webContent的目录下,要读取webContent目录下的配置文件

  1. @Override
  2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  3. //获取ServletContext对象
  4. ServletContext context = this.getServletContext();
  5. InputStream in = context.getResourceAsStream("db.properties");
  6. Properties prop = new Properties();
  7. prop.load(in);
  8. String driver = prop.getProperty("driver");
  9. String url = prop.getProperty("url");
  10. String username = prop.getProperty("username");
  11. String password = prop.getProperty("password");
  12. System.out.println("驱动:"+driver+",请求路径:"+url+",用户名:"+username+",密码:"+password);
  13. }

4.3 Response对象

  • 当服务器接收到了请求之后,会执行doPost或者doGet方法,执行完之后会给浏览器反馈数据,完成反馈数据的对象就是response,该对象不需要程序员自己创建。常用的方法

    1. addCookie(Cookie cook) 添加一个cookie对象,后续会话管理的地方讲解
    2. addHeader(String headerName,String value) 添加一个响应头以及对应的数据
    3. sendRedirect(String location) response对象实现重定向
    4. setHeader(String headName,String value) 设置一个响应头及对应的数据
    5. setStatus(int sc) 设置状态码,一般不需要程序员设置,服务器会根据响应的状态返回状态码
    6. getWriter() 通过response对象获取字符输出流
    7. getOutputStream() 通过response对象获取字节输出流
  • 示例代码1:getOutputStream(),并解决乱码的问题

    1. @Override
    2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. //设置response对象里面的编码集
    4. resp.setCharacterEncoding("utf-8");
    5. resp.setHeader("Content-type", "text/html;charset=utf-8");
    6. //获取字节输出流对象
    7. OutputStream out = resp.getOutputStream();
    8. out.write("你追我,嘿嘿嘿,我不同意".getBytes("UTF-8"));
    9. }
  • 示例代码2:getWriter()方法

    1. @Override
    2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. //设置编码集
    4. resp.setCharacterEncoding("UTF-8");
    5. resp.setHeader("Content-type", "text/html;charset=utf-8");
    6. //获取字符输出流
    7. Writer out = resp.getWriter();
    8. out.write("你好,哈哈哈哈哈,中午了,肚子饿");
    9. }
  • 使用response对象实现重定向,当浏览器向服务器发送一个请求之后,通过doGet或者doPost方法,实现页面之间的跳转

    1. //前端代码,要求,当点击超链接之后,能够正常的执行到Servlet的代码
    2. <div id="reg">
    3. <a href = "/WebDemo3">注册></a>
    4. </div>
    1. @Override
    2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. System.out.println("执行到了demo3");
    4. //经过服务器之后,再实现页面的跳转
    5. resp.sendRedirect("/WebDemo3/page/register.html");
    6. }
  • 注意:response对象可以调用sendRedirect方法实现页面之间的跳转,而且是经过服务器之后实现跳转,但是不推荐使用,对于服务器底层来说,重定向会给服务器实际发送两次请求,重定向只能单纯的实现页面跳转,不能携带数据

4.4 request对象(重点)

  • 当浏览器向服务器发送请求之后,服务器会接受到来自浏览器的数据(用户填写的数据、请求头数据和请求的数据),request是完成前端数据交给服务器的对象。request常用的方法

    1. *1getCookies(); 获取Cookie对象的数组,后续会有专门的课程讲解会话管理
    2. 2getHeader(String name); 获取请求头的相关数据
    3. 3getMethod(); 获取请求方式(一般包括get请求或者post请求)
    4. 4getReuqestURI(); 获取请求的资源路径
    5. 5getRequestURL(); 获取请求路径(包含详细的ip地址和端口号)
    6. *6getSession(); 获取一个Session对象,后续专门用会话管理的地方讲解
    7. *7getAttribute(String name); 获取request里面存储的数据
    8. *8setAttribute(String name,Object obj);向request域中添加一个键值对。
    9. 9removeAttribute(String name);移除一个元素值
    10. *10setCharacterEncoding(String name); 设置编码集
    11. 11getLocalAddr() ;获取ip地址
    12. 12getLocalName();获取主机名
    13. 13getLocalPort() ;获取端口
    14. *14getParameter(String name);获取前端传送过来的数据
    15. *15getParameterNames();获取前端传送过来的数据名称
    16. *16getRequestDispatcher();实现请求转发
  • 作为了解的方法 ```java @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    1. //根据指定头名称获取响应的数据
    2. String headValue = request.getHeader("Accept");
    3. System.out.println("请求头:"+headValue);
    4. //获取请求方法
    5. String method = request.getMethod();
    6. System.out.println("请求方式:"+method);
    7. //获取当次请求的资源路径
    8. String uri = request.getRequestURI();
    9. System.out.println("uri = "+uri);
    10. //获取当次的请求路径
    11. StringBuffer url = request.getRequestURL();
    12. System.out.println("url = "+url);
    13. //获取请求ip地址
    14. String ip = request.getLocalAddr();
    15. System.out.println("ip = "+ip);
    16. //获取当次请求的主机名
    17. String hostName = request.getLocalName();
    18. System.out.println("主机名:"+hostName);
    19. //获取该次请求的端口
    20. int port = request.getLocalPort();
    21. System.out.println("端口:"+port);

    }

}

  1. - request里面的请求转发
  2. ```java
  3. //实现Servlet类之间的请求转发
  4. /*
  5. 前端请求到RquestDemo2里面的doPost()方法,在这个方法里面不做处理,想要调用RequestDemo3里面的doPost()方法做处理
  6. */
  7. @Override
  8. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9. System.out.println("已经成功请求到了demo2");
  10. //向request域里面存入键值对
  11. request.setAttribute("name", "张三");
  12. //将方法切换到Demo3里面去执行
  13. //实现请求转发
  14. RequestDispatcher rd = request.getRequestDispatcher("/demo6");
  15. //需要转发
  16. rd.forward(request, response);
  17. }
  18. @Override
  19. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  20. System.out.println("已经成功请求到了demo3");
  21. //获取值
  22. String name = (String)request.getAttribute("name");
  23. System.out.println("来自于demo2的name:"+name);
  24. }
  25. //setAttribute()和getAttribute();
  26. setAttribute()方法是向request域里面存入一个键值对
  27. getAttribute()方法是根据名称获取到request域里面对应的值。
  • request对象实现页面的请求转发

    1. @Override
    2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    3. System.out.println("请求成功");
    4. //实现页面的转发
    5. RequestDispatcher rd = request.getRequestDispatcher("/page/login.html");
    6. rd.forward(request, response);
    7. }
  • 后端获取前端发送过来的数据 ```html @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    1. //设置编码集
    2. req.setCharacterEncoding("UTF-8");
    3. resp.setCharacterEncoding("UTF-8");
    4. resp.setHeader("Content-type", "text/html;charset=utf-8");
    5. //获取前端的参数,使用方法:getParameter(String name);

// String userName = req.getParameter(“userName”); // String password = req.getParameter(“password”); // System.out.println(“用户名:”+userName+”,密码:”+password);

  1. String comment = req.getParameter("comment");
  2. System.out.println("他说:"+comment);
  3. }
  1. - jsp页面(简单版本)
  2. ```java
  3. public class LoginServlet extends HttpServlet{
  4. @Override
  5. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  6. doPost(req, resp);
  7. }
  8. @Override
  9. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  10. //设置编码集
  11. request.setCharacterEncoding("UTF-8");
  12. response.setCharacterEncoding("UTF-8");
  13. response.setHeader("Content-type", "text/html;charset=utf-8");
  14. //获取参数
  15. // String userName = request.getParameter("userName");
  16. // String password = request.getParameter("password");
  17. String userName = "root";
  18. String password = "admin";
  19. //判断密码和用户名是否正确
  20. if(userName.equals("root") && password.equals("admin")) {
  21. //将一个String类型的数据发送给前端
  22. String str = "我终于登录成功了";
  23. //将数据存入request域中
  24. request.setAttribute("str", str);
  25. User u1 = new User();
  26. u1.setName("张三");
  27. u1.setAge(19);
  28. u1.setAddress("重庆");
  29. //将整个对象存入request域中
  30. request.setAttribute("user", u1);
  31. User u2 = new User();
  32. u2.setName("李四");
  33. u2.setAge(22);
  34. u2.setAddress("成都");
  35. User u3 = new User();
  36. u3.setName("王五");
  37. u3.setAge(30);
  38. u3.setAddress("北京");
  39. List<User> list = new ArrayList<>();
  40. list.add(u1);
  41. list.add(u2);
  42. list.add(u3);
  43. //将集合存入request域中
  44. request.setAttribute("list", list);
  45. //跳转到成功页面
  46. RequestDispatcher rd = request.getRequestDispatcher("/jsp/success.jsp");
  47. rd.forward(request, response);
  48. }else {
  49. //跳转到失败的页面
  50. RequestDispatcher rd = request.getRequestDispatcher("/jsp/error.jsp");
  51. rd.forward(request, response);
  52. }
  53. }
  54. }
  • 前端jsp获取数据 ```html <%@ page language=”java” contentType=”text/html; charset=UTF-8” pageEncoding=”UTF-8”%> <%@ taglib uri=”http://java.sun.com/jsp/jstl/core“ prefix=”c”%> <!DOCTYPE html> 恭喜你,登录成功
    字符串的值:${str }

    获取对象里面的值:
    ${user.name } ${user.age } ${user.address }

    获取集合中的数据 ${list.get(0).name }

    遍历集合
    姓名 年龄 地址
    ${user.name } ${user.age } ${user.address }

  1. <a name="ouIX4"></a>
  2. # 作业步骤

1、创建web工程,并且将服务器的servlet依赖加入(build path—->服务器的jar包) 2、导入依赖jar包(mybatis核心包和依赖包,jdbc链接包、el表达式依赖包) 3、在WEB-INF目录下新建web.xml配置文件,dtd约束去服务器里面的web.xml拷贝 4、目录结构和包的创建,目录主要放在webContent目录下,存放前端的静态页面,包用于存放java代码 5、编写前端,简单编写一个form表单,可以提交数据即可 6、编写Servlet,并在web.xml配置文件中配置映射,配置好映射之后,先去前端的form表单中添加action请求路径 7、定义一个User用户失血模型 8、在Servlet里面,编写获取数据的内容,getParameter(String name);并将获取的值存入一个user对象中 9、编写mybatis框架的SqlMapConfig.xml配置文件,并编写db.properties配置文件,在SqlMapConfig配置文件中加载 10、编写Mapper的接口 11、根据接口编写mapper.xml配置文件,要在SqlMapConfig.xml文件里面加载 12、编写Dao的实现类 13、编写业务逻辑层,包括接口和实现类

  1. - 前端代码
  2. ```html
  3. <%@ page language="java" contentType="text/html; charset=UTF-8"
  4. pageEncoding="UTF-8"%>
  5. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9. <meta charset="UTF-8">
  10. <title>登录</title>
  11. </head>
  12. <body>
  13. <form action="/WebDemo4/login" method = "post">
  14. 电话号码:<input type = "text" id = "tel" name = "tel"><br />
  15. 密码:<input type = "password" id = "password" name = "password"><br />
  16. <input type = "submit" value = "提交">
  17. </form>
  18. </body>
  19. </html>
  • 用户失血模型

    1. /**
    2. *
    3. * <p>Title: User</p>
    4. * <p>Description: 用户的失血模型</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午10:01:27
    7. * @version 1.0
    8. */
    9. public class User {
    10. private String tel;
    11. private String password;
    12. public String getTel() {
    13. return tel;
    14. }
    15. public void setTel(String tel) {
    16. this.tel = tel;
    17. }
    18. public String getPassword() {
    19. return password;
    20. }
    21. public void setPassword(String password) {
    22. this.password = password;
    23. }
    24. }
  • Servlet类

    1. /**
    2. *
    3. * <p>Title: LoginServlet</p>
    4. * <p>Description: 登录的Servlet</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午9:56:31
    7. * @version 1.0
    8. */
    9. public class LoginServlet extends HttpServlet{
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. doPost(req, resp);
    13. }
    14. @Override
    15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    16. //设置编码集
    17. request.setCharacterEncoding("UTF-8");
    18. response.setCharacterEncoding("UTF-8");
    19. response.setHeader("Content-type", "text/html;charset=utf-8");
    20. //获取参数
    21. String tel = request.getParameter("tel");
    22. String password = request.getParameter("password");
    23. //创建User对象
    24. User user = new User();
    25. user.setTel(tel);
    26. user.setPassword(password);
    27. System.out.println("电话:"+tel+",密码:"+password);
    28. //调用Service层的方法
    29. UserService userService = new UserServiceImpl();
    30. boolean flag = userService.userLogin(user);
    31. if(flag) {
    32. request.getRequestDispatcher("/page/success.jsp").forward(request, response);
    33. }else {
    34. request.getRequestDispatcher("/page/fail.jsp").forward(request, response);
    35. }
    36. }
    37. }
  • web.xml配置文件

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    3. <servlet>
    4. <servlet-name>LoginServlet</servlet-name>
    5. <servlet-class>com.woniuxy.servlet.LoginServlet</servlet-class>
    6. </servlet>
    7. <servlet-mapping>
    8. <servlet-name>LoginServlet</servlet-name>
    9. <url-pattern>/login</url-pattern>
    10. </servlet-mapping>
    11. </web-app>
  • mybatis的SqlMapConfig.xml配置文件

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE configuration
    3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
    5. <configuration>
    6. <!-- 加载properties配置文件 -->
    7. <properties resource="db.properties"></properties>
    8. <!-- 配置别名 -->
    9. <typeAliases>
    10. <package name="com.woniuxy.model"/>
    11. </typeAliases>
    12. <!-- 可以配置多条数据源和事务管理的标签:当前使用,以后使用了spring整合之后,不再需要 -->
    13. <environments default="development">
    14. <!-- 配置单条的数据源和事务管理的标签 -->
    15. <environment id="development">
    16. <!-- 事务管理,暂时全部交给mybatis进行管理事务 -->
    17. <transactionManager type="JDBC" />
    18. <!-- 配置数据源 -->
    19. <dataSource type="POOLED">
    20. <!-- 配置数据库的驱动 -->
    21. <property name="driver" value="${driver}"/>
    22. <!-- 配置数据库的链接,里面就绑定好了数据库名 -->
    23. <property name="url" value="${url}"/>
    24. <!-- 配置数据库的用户名 -->
    25. <property name="username" value="${username}"/>
    26. <!-- 配置数据库的密码 -->
    27. <property name="password" value="${password}"/>
    28. </dataSource>
    29. </environment>
    30. </environments>
    31. </configuration>
  • 数据源信息的db,properties配置文件

    1. driver=com.mysql.jdbc.Driver
    2. url=jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=utf-8
    3. username=root
    4. password=
  • UserMapper接口

    1. /**
    2. *
    3. * <p>Title: UserMapper</p>
    4. * <p>Description: 用户的Mapper接口</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午10:39:54
    7. * @version 1.0
    8. */
    9. public interface UserMapper {
    10. /**
    11. *
    12. *<p>Title: queryUserByTel</p>
    13. *<p>Description:根据电话号码查询用户 </p>
    14. * @param tel
    15. * @return
    16. * @throws Exception
    17. */
    18. public User queryUserByTel(String tel) throws Exception;
    19. }
  • userMapper.xml配置文件

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <!-- 配置mapper -->
    6. <mapper namespace="com.woniuxy.mapper.UserMapper">
    7. <!-- 编写查询语句 -->
    8. <select id="queryUserByTel" parameterType="java.lang.String" resultType="User">
    9. SELECT tel,`password` FROM t_user WHERE tel = #{tel};
    10. </select>
    11. </mapper>
  • UserDao的实现类

    1. /**
    2. *
    3. * <p>Title: UserDao</p>
    4. * <p>Description: 用户Dao的实现类</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午10:47:55
    7. * @version 1.0
    8. */
    9. public class UserDao implements UserMapper{
    10. //声明会话工厂
    11. private SqlSessionFactory factory;
    12. //在构造方法里面初始化
    13. public UserDao() {
    14. try {
    15. //获取配置文件
    16. String path = "SqlMapConfig.xml";
    17. InputStream config = Resources.getResourceAsStream(path);
    18. factory = new SqlSessionFactoryBuilder().build(config);
    19. } catch (Exception e) {
    20. e.printStackTrace();
    21. }
    22. }
    23. @Override
    24. public User queryUserByTel(String tel) throws Exception {
    25. //开启会话
    26. SqlSession session = factory.openSession();
    27. //获取mapper对象
    28. UserMapper mapper = session.getMapper(UserMapper.class);
    29. //调用方法
    30. User user = mapper.queryUserByTel(tel);
    31. return user;
    32. }
    33. }
  • UserService接口

    1. /**
    2. *
    3. * <p>Title: UserService</p>
    4. * <p>Description: 用户的业务层接口</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午10:51:49
    7. * @version 1.0
    8. */
    9. public interface UserService {
    10. /**
    11. *
    12. *<p>Title: userLogin</p>
    13. *<p>Description: 用户登录</p>
    14. * @param user
    15. * @return
    16. * @throws Exception
    17. */
    18. public boolean userLogin(User user) throws Exception;
    19. }
  • UserServieImpl实现类

    1. /**
    2. *
    3. * <p>Title: UserServiceImpl</p>
    4. * <p>Description: 用户业务层实现类</p>
    5. * @author Alon
    6. * @date 2020年10月23日 上午10:55:26
    7. * @version 1.0
    8. */
    9. public class UserServiceImpl implements UserService {
    10. @Override
    11. public boolean userLogin(User user) throws Exception {
    12. //创建Dao的对象
    13. UserMapper userDao = new UserDao();
    14. //获取传递过来的电话和密码
    15. String tel = user.getTel();
    16. String password = user.getPassword();
    17. User u = userDao.queryUserByTel(tel);
    18. //比较
    19. if(password.equals(u.getPassword())) {
    20. return true;
    21. }
    22. return false;
    23. }
    24. }

    会话管理

    Session会话

  • 概念:作用在服务器端的会话技术,用来针对每一个用户产生一块内存区域,实现不同的Servlet之间的数据共享,一个用户独立占用一块内存。

  • 获取Session对象:request.getSession();
  • java代码
    1. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    2. //创建Session对象
    3. HttpSession session = request.getSession();
    4. String msg = "购买的Servlet";
    5. session.setAttribute("msg", msg);
    6. }
    7. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    8. //获取session对象
    9. HttpSession session = request.getSession();
    10. String msg = (String)session.getAttribute("msg");
    11. System.out.println(msg);
    12. }

Cookie会话

Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。
代码:
image.png