JAVA WEB

请求和响应

package com.tom.servlet;

import javax.servlet.ServletException;
//引用Servlet包
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class HelloServlet extends HttpServlet {
    //Request 请求
    //Response 响应 返回
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //响应返回类型为text/html
        resp.setContentType("text/html");
        //获取响应的输出流
        PrintWriter out= resp.getWriter();
        //定义编码
        resp.setCharacterEncoding("utf-8");
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello Head</title>");
        out.println("</head>");
        out.println("<h1>Hello World! Java</h1>");
        out.println("<boby>");
        out.println("</html>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     doGet(req, resp);
    }
}

web.xml 核心配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
<!--  web.xml中是配置web的核心应用-->
<!--  注册Servlet name是可以任意取的-->
  <servlet>
    <servlet-name>Hello</servlet-name>
    <servlet-class>com.tom.servlet.HelloServlet</servlet-class>
  </servlet>
<!--  一个Servlet对应一个Mapping:映射-->
  <servlet-mapping>
<!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
<!--    映射请求路径-->
    <url-pattern>/tom</url-pattern>
  </servlet-mapping>
</web-app>

HttpServlet需要加载maven依赖

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

tomcat的控制的中文乱码问题

1、找到tomcat 安装目录下的 conf /logging.properties 文件打开

2、将 java.util.logging.ConsoleHandler.encoding = UTF-8 修改为

​ java.util.logging.ConsoleHandler.encoding = GBK

3、保存后 重启idea

tomcat启动时出现报错

java.io.IOException: [C:\Program Files\Tomcat\apache-tomcat-9.0.40\webapps\com_tom_down_war] 无法被创建

解决办法:以管理员身份启动idea即可 因为idea启动的tomcat没有权限

或者设置默认管理员打开,设置办法如下

右键idea选择属性-兼容性-以管理员身份运行此程序打上勾即可。

maven资源导出问题解决

   <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

web.xml的servlet-mapping问题

1、一个servlet可以指定一个映射路径

 <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/tom</url-pattern>
  </servlet-mapping>

2、一个servlet可以指定多个映射路径

  <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/tom</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/tom2</url-pattern> 
  </servlet-mapping>

3、一个servlet可以指定通用映射路径

 <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/tom/*</url-pattern>
  </servlet-mapping>

4、默认请求路径

  <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

5、指定一些前缀或后缀等等…

  <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    可以自定义后缀实现请求映射
           注意点*前面不能加映射路径 -->
    <url-pattern>*.tom</url-pattern>
  </servlet-mapping>

6、优先级问题

指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

定义Error404页面

1、Servlet定义

package com.tom.Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ErrorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");//定义编码
        resp.setContentType("text/html");//定义类型为html
        PrintWriter out = resp.getWriter();//定义输出
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Error</title>");
        out.println("</head>");
        out.println("<h1>404 nod find</h1>");
        out.println("<boby>");
        out.println("</html>");
        System.out.println("进入404页面");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

2、web.xml配置映射

<!--  404-->
<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.tom.Servlet.ErrorServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

共享数据

在这个Servlet中保存的数据,可以在另一个servlet中拿到;

package com.tom.Servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        this.getInitParameter() 初始化参数值参数
//        this.getServletConfig() Servlet配置
//        this.getServletContext() Servlet 上下文
        ServletContext servletContext=this.getServletContext();
        String uname="大黄";//数据
        servletContext.setAttribute("uname",uname);//将一个数据保存在servletContext中名为"uname"值为uname

        System.out.println("Hello");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

另一个ServletContext取值

package com.tom.Servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String uname= (String) servletContext.getAttribute("uname");
        resp.setContentType("text/html");//定义类型为html
        resp.setCharacterEncoding("utf-8");//定义字符编码
        resp.getWriter().println("名字"+uname);


    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}


web.xml加载Servlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    <servlet>
        <servlet-name>Hello</servlet-name>
        <servlet-class>com.tom.Servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/tom</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>Get</servlet-name>
        <servlet-class>com.tom.Servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Get</servlet-name>
        <url-pattern>/get</url-pattern>
    </servlet-mapping>
</web-app>

context-param 和getInitParameter

定义初始化参数值

    <servlet>
        <servlet-name>Demo</servlet-name>
        <servlet-class>com.tom.Servlet.DemoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo</servlet-name>
        <url-pattern>/Demo</url-pattern>
    </servlet-mapping>
<!--    配置一些web应用初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://121.4.118.195:3306/WanQuanZhuang?useSSL=false"</param-value>
    </context-param>

获取初始化参数

package com.tom.Servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DemoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        String url=servletContext.getInitParameter("url");//获取web.xml定义的初始化参数
        resp.getWriter().println(url);//打印获取的url
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

请求转发

注url地址不会变

package com.tom.Servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DemoServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        System.out.println("进入跳转Servlet");
        String url=servletContext.getInitParameter("url");//获取web.xml定义的初始化参数
        resp.getWriter().println(url);//打印获取的url
//        RequestDispatcher requestDispatcher =servletContext.getRequestDispatcher("/Demo");//转发的请求路径
//        requestDispatcher.forward(req,resp);//调用forward实现请求转发
        servletContext.getRequestDispatcher("Demo").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

读取资源文件Properties

  • 在java目录下新建properties

  • 在resources目录下新建properties
    发现:都被打包到了同一个路径下: classes,我们俗称这个路径为classpath

  • 需要一个文件流

    username=root
    password=123
    
package com.tom.Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class Demo04Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将资源变成一个io流
        InputStream is=this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop = new Properties();
        prop.load(is);//获取这个流
        String user = prop.getProperty("username");
        String pwd= prop.getProperty("password");
        resp.getWriter().println(user+":"+pwd);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

    <servlet>
        <servlet-name>Demo04</servlet-name>
        <servlet-class>com.tom.Servlet.Demo04Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Demo04</servlet-name>
        <url-pattern>/Demo04</url-pattern>
    </servlet-mapping>

访问展示数据即可

HttpServletResponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse; l

如果要获取客户端请求过来的参数:找HttpServletRequest

如果要给客户端响应一些信息:找HttpServletResponse

1、文件下载功能实现

package Servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(1111);
//        1.要获取下载文件的路径
        String realPath="C:\\w_ja\\com.tom.down\\target\\classes\\汤姆.jpeg";
        System.out.println("下载文件的路径: "+realPath);
//        2.下载的文件名是啥?
        String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//        3.设置想办法让浏览器能够支持(Content-disposition)下载我们需要的东西 中午文件名URLEncoder.encode(fileName,"utf-8")编码,否则有可能乱码
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));
//        4.获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
//        5.创建级冲区
        int len = 0;
        byte[] buffer = new byte[1024];
//        6.获取Outputstream对象
        ServletOutputStream out = resp.getOutputStream();
//        7.将Fileoutputstream流写入到buffer缓冲区
        while ((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
//        8.使用Outputstream将缓冲区中的数据输出到客户端!

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <servlet>
    <servlet-name>filedown</servlet-name>
    <servlet-class>Servlet.FileServlet</servlet-class>

  </servlet>
  <servlet-mapping>
    <servlet-name>filedown</servlet-name>
    <url-pattern>/down</url-pattern>
  </servlet-mapping>
</web-app>

2、验证码功能实现

package Servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class ImageServlet extends HttpServlet {
    //验证码实现
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //让浏览器3秒自动刷新 后台发送刷新请求 refresh 固定参数 "3" 时间单位为秒
        resp.setHeader("refresh","3");
        //在内存中创建一个图片对象
        BufferedImage Image = new BufferedImage(80,30,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g= (Graphics2D) Image.getGraphics(); //g 画笔
        // 设置图片的背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,30);
        //给图片写数据
        //定义字体颜色
        g.setColor(Color.red);
        //定义字体
        g.setFont(new Font(null,Font.BOLD,30));
        g.drawString(makeNum(),0,30);
        //告诉浏览器,这个请求用图片的方式打开
        resp.setContentType("image/png");
        // 网站存在缓存,不让浏览器缓存  expires 缓存 固定值
        resp.setDateHeader("expires",-1);
        //固定值不缓存的意思
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
        // 吧图片写给浏览器
        ImageIO.write(Image,"jpg",resp.getOutputStream());

    }
    //生成随机数
    private String makeNum(){
      Random random= new Random();
      //生成五位随机数
      String num = random.nextInt(99999) + "";
      StringBuffer sb = new StringBuffer();
        for (int i = 0; i <5-num.length() ; i++) {
            sb.append("0");
        }
        String s = sb.toString() + num;
        return num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <!--  web.xml中是配置web的核心应用-->
  <!--  注册Servlet name是可以任意取的-->
  <servlet>
    <servlet-name>Hello</servlet-name>
    <servlet-class>Servlet.ImageServlet</servlet-class>
  </servlet>
  <!--  一个Servlet对应一个Mapping:映射-->
  <servlet-mapping>
    <!--    映射上面定义的Servlet-name-->
    <servlet-name>Hello</servlet-name>
    <!--    映射请求路径-->
    <url-pattern>/img</url-pattern>
  </servlet-mapping>
</web-app>

3、实现重定向


package Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        System.out.println("进入这个请求");
        String username=req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username+":"+password);
        resp.sendRedirect("/tom/success.jsp");
        System.out.println("");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  <servlet>
    <servlet-name>Request</servlet-name>
    <servlet-class>Servlet.RequestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Request</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--指定编码--%>
<html>
<body>
<h2>Hello World!</h2>

<%--这里提交路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前项目的路径--%>
<%--使用web.xml文件中的/login method="get" 使用对应请求Servlet里的get请求 还是post的请求--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    <%--type="text" 普通文本框  name="username"框里面的值等于username   --%>
    账号:<input type="text" name="username"> <br>
        <%-- type="password" 密码框 br换行--%>
    密码:<input type="password" name="password"> <br>
        <%--type="submit"提交当前的form表单--%>
    <input type="submit">
</form>
</body>
</html>

面试题:请你聊聊重定向和转发的区别?
相同点
●页面都会实现跳转
不同点
●请求转发的时候,url不会产生变化 307
●重定向时候,url地址栏会发生变化; 302

4、JSP的依赖

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>

HttpServletRequest

Cookie、Session

1、会话

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话

**有状态会话:**客户端访问这个页面,下次在访问,就会知道这个客户端曾经访问过

2、保存会话的两种技术

cookie

  • 客户端技术 (响应,请求)

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息?我们可以吧信息或者数据放在Session中!

3、Cookie

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
package Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

//保存用户上一次访问的时间
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务器,告诉你,你来的时间,把这个时间封装成为个信件,你下带来,我就知道你来了
        //解决中文乱码
        req.setCharacterEncoding("GBK");
       resp.setCharacterEncoding("GBK");
        resp.setContentType("text/html");
       PrintWriter out=resp.getWriter();
       //Cookie,服务端从客户端获取
      Cookie[] cookies =  req.getCookies();//这里返回数组,说明Cookie存在多个
        //判断Cookie是否存在
        if (cookies!=null){
            //如果存在就取出这个Cookie
            for (int i = 0; i <cookies.length ; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("time")){
                    //获取cookie name为time中的值
                    Long time=Long.parseLong(cookie.getValue());
                  Date date =  new Date(time);
                  out.write("上次一访问本站:"+date.toLocaleString());

                }
            }
        }else {
            out.write("这是第一次访问本站");
        }
      Cookie cookie= new Cookie("time",System.currentTimeMillis()+"");
        //cookie 有效期为1天
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

Cookie[] cookies =  req.getCookies();//获得cookie这里返回数组,说明Cookie存在多个
cookie.getName();//获得cookie的key
cookie.getValue();//获得cookie的Value
new Cookie("time",System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
 resp.addCookie(cookie);//响应一个cookie给客户端

cookie: -般会保存在本地的用户目录下appdata;

一个网站cookie是否存在上限?

  • 一个Cookie只能保存一一个信息;
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
  • Cookie大小有限制4kb;
  • 300个cookie浏览器上限

删除Cookie;

  • 不设置有效期,关闭浏览器,自动失效;
  • 设置有效期时间为0
package Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

//保存用户上一次访问的时间
public class CookieServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      Cookie cookie= new Cookie("time",System.currentTimeMillis()+"");

        cookie.setMaxAge(0);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

Cookie编码问题

 //编码
        Cookie cookie= new Cookie("name", URLEncoder.encode("汤姆","utf-8"));
  //解码
                    out.write(URLEncoder.encode(cookie.getValue(),"utf-8"));
package Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Date;

//cookie中文数据传递
public class CookieServlet03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("GBK");
        resp.setCharacterEncoding("GBK");
        Cookie[] cookies =  req.getCookies();//这里返回数组,说明Cookie存在多个
        PrintWriter out=resp.getWriter();
        //判断Cookie是否存在
        if (cookies!=null){
            //如果存在就取出这个Cookie
            for (int i = 0; i <cookies.length ; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("name")){
//                    System.out.println(cookie.getValue());
                    //解码
                    out.write(URLEncoder.encode(cookie.getValue(),"utf-8"));
//                    out.write(cookie.getValue());
                }
            }
        }else {
            out.write("这是第一次访问本站");
        }
//        Cookie cookie= new Cookie("name","汤姆");
        //编码
        Cookie cookie= new Cookie("name", URLEncoder.encode("汤姆","utf-8"));
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

4、Session(重点)

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个Seesion对象;
  • 一个Seesion独占-一个浏览器,只要浏览器没有关闭,这个Session就存在;
  • 用户登录之后,整个网站它都可以访问;

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保持多个)
  • Session把用户的数据写到用户独占Session中, 服务器端保存 (保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务创建;

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据,我们将它保存在Session中;

创建并获取Session

package Servlet;

import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理编码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //的到Session
        HttpSession session = req.getSession();
        //给Session 赋值
        session.setAttribute("name",new Person("汤姆",22));
        //获取Session的ID
        String sessionId=session.getId();
        //判断Session是不是新创建的
        if (session.isNew()){
            resp.getWriter().write("Session创建成功;ID:"+sessionId);
        }else {
            resp.getWriter().write("Session存在;ID:"+sessionId);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

获取Session实例化对象

package pojo;

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

package Servlet;

import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理编码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //的到Session
        HttpSession session = req.getSession();
        //获取Session的name
        Person Personname= (Person) session.getAttribute("name");
        System.out.println(Personname.toString());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

根据Session的key删除Session的值 并注销Session

package Servlet;

import pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class SessionServlet03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //的到Session
        HttpSession session = req.getSession();
        //删除key为name的Session
        session.removeAttribute("name");
        //手动 注销这个Session
        session.invalidate();


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

自动删除Session 定义过期时间

<!-- 设置Session的失效时间   -->
    <session-config>
<!--        1分钟后Session自动失效 以分钟为单位-->
        <session-timeout>1</session-timeout>
    </session-config>

JSP

1、什么是JSP

Java Server Pages : Java服务器端页面, 也和Servlet一 样,用于动态Web技术!

最大的特点:

  • 写JSP就像在写HTML
  • 区别:
    • HTML只给用户提供静态的数据
    • JSP页面中可以嵌入AVA代码,为用户提供动态数据;

2、JSP原理

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终也会被转换成为一个Java类 !
JSP本质上就是-一个Servlet

//初始化
pub1ic void _jspInit() {
}
//销毁
pub1ic void _jspDestroy() {
}
//JSPService
pub1ic void  _jspservice(.HttpServletRequest request,HttpServletResponse response)

  1. 判断请求
  2. 内置一些对象
final javax.servlet. sp.pageContext pageContext;  //页面上下文
javax. servlet.http.HttpSession session = null;   //session
fina1 javax. serv1et. ServletContext application;   //applicati onContext
final javax. servlet. Serv1etConfig config;         //config
javax. servlet. jsp.Jspwriter out = null;           //out
final java.lang.Object page = this;             //page:当前
HttpServletRequest request						//请求
HttpServletResponse response					//响应

3.输出页面前增加的代码

response.setcontentType( text/htm1);//设置响应的贞面类型
pageContext = _jspxFactory.getPageContext(this,request,response,
nu11, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getservletContext();
config = pageContext.getservletConfig();
session = pageContext.getsession();
out = pageContext.getout();
_jspx_out = out;

4.以上的这些个对象我们可以在JSP页面中直接使用!

在JSP页面中;
只要是JAVA代码就会原封不动的输出;
如果是HTML代码,就会被转换为

 out.write("name:");

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    for (int i = 0; i < 10; i++) {
        out.println(i);
    }%>
<%
   String name= "tom";
%>
name:<%=name%>
</body>
</html>

3、JSP基础语法

1、所需的maven依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>javaweb_jsp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <!--Servlet 依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>
<!--  JSP 依赖  -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.2.1</version>
    </dependency>
    <!--JSTL表达式的依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <!--standard标签库 -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

  </dependencies>
</project>

2、JSP表达式

<body>
<%--JSP 表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
</body>

3、脚本片段

<%--<hr>分割线--%>
<hr>
<%--jsp脚本片段 --%>

<%
    int sum=0;
    for (int i = 1; i <100 ; i++) {
        sum+=i;
    }
    out.println("<h1>sum="+sum+"</h1>");
%>
</body>

4、在代码中添加html元素

<%--在代码中添加html元素--%>
<%
    for (int i = 0; i <5 ; i++) {
    %>
<h1>hello,tom <%=i%> </h1>
<%
    }
%>

5、JSP声明

<%--jsp声明--%>
<%!
static{
    System.out.println("加载静态代码块");
}
private int age = 22;

public void user(){
    System.out.println("TOM年龄是"+age);
}
%>

JSP声明:会被编译到SP生成Java的类中!其他的,就会被生成到_jspService方法中!

在JSP,嵌入ava代码即可!

JSP的注释,不会在客户端显示,HTML就会!

6、自定义错误页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--定制500错误页面--%>
<%@ page errorPage="/error/500error.jsp" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
int i=1/0;
%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>error</title>
</head>
<body>
<%--width="100%"; height="100%" 自动填充窗口宽为100% 高为100%--%>
<img src="/img/500.png" alt="500" width="100%"; height="100%" >
</body>
</html>

7、xml配置中心定义错误页面

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <error-page>
    <error-code>500</error-code>
    <location>/error/500.jsp</location>
  </error-page>
  <error-page>
    <error-code>404</error-code>
    <location>/error/404.jsp</location>
  </error-page>
</web-app>

8、jsp页面头尾合一


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<%--@include 会将两个页面合二为一--%>
    <%@include file="/common/header.jsp"%>
    <h1>网页主体</h1>
    <%@include file="/common/footer.jsp"%>
    <hr>
<%--JSP标签
jsp:include 拼接页面,本质还是三个
--%>
<jsp:include page="common/header.jsp"/>
    <h1>页面主体</h1>
<jsp:include page="common/footer.jsp"/>
</body>
</html>

测试结果

head
网页主体
footer

head
页面主体
footer

4、九大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application 【ServletContext】 存东西
  • config 【servletConfig】
  • out
  • page
  • exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
    //存东西
    pageContext.setAttribute("name1","汤姆");//保存的数据只在一个页面中有效
    request.setAttribute("name2","小明");//保存的数据只在一次请求中有效, 请求转发会携带这个数据
    session.setAttribute("name3","大黄");//保存的数据只在次会话中有效,从打开测览器到关闭浏览器
    application.setAttribute("name4","小王");//保存的数据只在服务器中有效,从打开服务器到天的服务器
%>

<%
    //通过pageContext取,通过寻找的方式来
    //从底层到高层(作用域):page->request->session->application
    String name1= (String) pageContext.findAttribute("name1");
    String name2= (String) pageContext.findAttribute("name2");
    String name3= (String) pageContext.findAttribute("name3");
    String name4= (String) pageContext.findAttribute("name4");
    String name5= (String) pageContext.findAttribute("name5");
%>
<%--使用EL 表达式输出 ${} --%>
<h1>取出的为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<h3><%=name5%></h3>
<%pageContext.forward("index.jsp");%>
<%--携带name2值转发--%>
</body>
</html>

另一个页面取值

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<%--加载pageContextDemo01.jsp获取下面的值--%>
<h3>${name1}</h3>
<%--无值 因为值保存在pageContextDemo01.jsp这个页面--%>
<h3>${name2}</h3>
<%--无值 因为值保存在pageContextDemo01.jsp这个页面的中--%>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>

作用域


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--
//scope 作用域
    public void setAttribute(String name, Object attribute, int scope) {
        switch(scope) {
        case 1:
            this.mPage.put(name, attribute);
            break;
        case 2:
            this.mRequest.put(name, attribute);
            break;
        case 3:
            this.mSession.put(name, attribute);
            break;
        case 4:
            this.mApp.put(name, attribute);
            break;
        default:
            throw new IllegalArgumentException("Bad scope " + scope);
        }

    }
--%>

<%--
    public static final int PAGE_SCOPE = 1;
    public static final int REQUEST_SCOPE = 2;
    public static final int SESSION_SCOPE = 3;
    public static final int APPLICATION_SCOPE = 4;
--%>
<%
    pageContext.setAttribute("hello1","hello1",PageContext.SESSION_SCOPE);
    // session.setAttribute("hello1","hello1");
    String hello = (String) pageContext.findAttribute("hello1");
%>
<%--转发--%>
<%
    pageContext.forward("index.jsp");
//    request.getRequestDispatcher("index.jsp").forward(request,response);
%>
</body>
</html>

    //存东西
    pageContext.setAttribute("name1","汤姆");//保存的数据只在一个页面中有效
    request.setAttribute("name2","小明");//保存的数据只在一次请求中有效, 请求转发会携带这个数据
    session.setAttribute("name3","大黄");//保存的数据只在次会话中有效,从打开测览器到关闭浏览器
    application.setAttribute("name4","小王");//保存的数据只在服务器中有效,从打开服务器到天的服务器

**request:**客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的

**session:**客户端向服务器发送请求,产生的数据,用户用完一会还有用, 比如:购物车;

**application:**客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数
据;

5、JSP、JSTL标签、EL表达式

<!--JSTL表达式的依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <!--standard标签库 -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

EL表达式:${}

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象

1、JSP标签

<body>
<%-- 页面合一 --%>
<%--<jsp:include page="jspTagTest.jsp"></jsp:include>--%>
<%--  页面转发 --%>
<%--
http://localhost:8080/jspTag01.jsp?uid=1&username=tom&password=123
--%>
<jsp:forward page="jspTagTest.jsp">
    <jsp:param name="uid" value="1"/>
    <jsp:param name="username" value="tom"/>
    <jsp:param name="password" value="123"/>
</jsp:forward>
</body>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>进入测试页面</h1>
<%--取出参数--%>
ID: <%=request.getParameter("uid")%>
账号:<%=request.getParameter("username")%>
密码:<%=request.getParameter("password")%>
</body>
</html>

2、JSTL表达式

JSTL标签库的使用就是为了弥补HTML标签的不足:它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!

核心标签(掌握部分)

JAVA WEB_xml

JSTL标签库使用步骤

  • 引入对应的taglib
  • 使用其中的方法

如果解析报错 在Tomcat也需要引入jstI的包,否则会报错: JSTL解析错误

1、c:if
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>if测试</h1>
<%--以get的提交方式提交到jspTag02.jsp --%>
<form action="jspTag02.jsp" method="get">
<%--
    EL表达式获取表单中的数据
    ${param.参数名}
--%>
    <input type="text" name="tom" value="${param.tom}">
<%--    按钮--%>
    <input type="submit" value="登录">
</form>
<%-- 判断用户提交的是否是Admin--%>
<c:if test="${param.tom=='admin'}" var="isAdmin">
    <c:out value="登录成功"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>
</body>
</html>

2、c:choose
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--定义一个变量score,值为99 --%>
<c:set var="score" value="99"></c:set>
<c:choose>
    <c:when test="${score>=90}">
        <c:out value="${score}"></c:out>
        优秀
    </c:when>
    <c:when test="${score>=70}">
        <c:out value="${score}"></c:out>
        合格
    </c:when>
    <c:when test="${score>=40}">
        <c:out value="${score}"></c:out>
        差
    </c:when>
</c:choose>
</body>
</html>

3、c:forEach
<%@ page import="java.util.ArrayList" %><%--引入JSTL标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"tom");
    people.add(1,"bob");
    people.add(2,"大黄");
    people.add(3,"小明");
    session.setAttribute("list",people);
%>

<%--
var 每一次遍历出来的变量
items 要遍历的对象
--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"></c:out><br>
</c:forEach>
<hr>
<%--
begin 哪里开始 默认0
end 到哪里 默认结尾
step 步长 默认1
--%>
<c:forEach var="people" items="${list}" begin="" end="3" step="2">
    <c:out value="${people}"></c:out><br>
</c:forEach>
</body>
</html>

JavaBean

实体类

JavaBean有特定的写法

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库的字段做映射 ORM

ORM: 对象关系映射

  • 表–》类
  • 字段–》属性
  • 行记录–》对象

USER表

uid uname uage
1 tom 22
class user{
    private int uid;
    private String uname;
    private int uage;
}

class test{
    new user (1,"TOM",22);
}

jsp:getProperty

<%@ page import="com.tom.pojo.pojo" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
//    pojo pojo = new pojo();
%>
<%--等同于上面那个  scope="page作用域--%>
<jsp:useBean id="pojo" class="com.tom.pojo.pojo" scope="page"/>

<%
//pojo.setUid(1);
//pojo.setUname("tom");
//pojo.setUage(22);
%>
<%-- 等同于上面那个--%>
<jsp:setProperty name="pojo" property="uid" value="1"/>
<jsp:setProperty name="pojo" property="uname" value="tom"/>
<jsp:setProperty name="pojo" property="uage" value="22"/>

<%--<%=pojo.getUid()%>--%>
<%--<%=pojo.getUname()%>--%>
<%--<%=pojo.getUage()%>--%>

id:<jsp:getProperty name="pojo" property="uid"/>
uname:<jsp:getProperty name="pojo" property="uname"/>
uage:<jsp:getProperty name="pojo" property="uage"/>
</body>
</html>

MVC三层架构

什么是MVC:Model view Controller模型、视图、控制器

JAVA WEB_java_02

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求(a,form,img…)

Controller

  • 接受用户的请求:(req:请求参数、Session信息)
  • 交给业务层处理对应的代码
  • 控制视图跳转

登录–》接受用户的登录请求–》处理用户的请求(获取用户登录的参数,username,password)–》交给

业务层处理登录业务(判断用户名密码是否正确:事务)–》Dao层查询用户名和密码是否正确–》数据库

Filter(重点)

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码
  • 登录验证…
    JAVA WEB_ide_03

1、导入maven依赖

  <dependencies>
    <!--Servlet 依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>
    <!--  JSP 依赖  -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.2.1</version>
    </dependency>
    <!--JSTL表达式的依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <!--standard标签库 -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
<!--    连接数据库-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.49</version>
    </dependency>
  </dependencies>

2、编写过滤器

注意导包 import javax.servlet.*;

实现Filter接口,重写对应的方法即可

package com.tom.filter;

import javax.servlet.*;
import java.io.IOException;

public class CharaterEncodngFilter implements Filter {
    //初始化 web服务器启动,就已经初始化了,随时等待过滤对象出现;
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharaterEncodngFilter 初始化");

    }
//FilterChain 过滤链
    /**
     1、过滤中的所有代码,在过滤特定请求的时候都会执行
     2、必须要让过滤器继续同行
     filterChain.doFilter(servletRequest,servletResponse);
     */
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");//定义请求编码
        servletResponse.setCharacterEncoding("utf-8");//定义响应编码
        servletResponse.setContentType("text/html;charset=UTF-8");//定义响应文本类型

        System.out.println("CharaterEncodngFilter 执行前....");
        filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就被拦藏停止!
        System.out.println("CharaterEncodngFilter 执行后....");
    }
//销毁 web服务器关闭的时候 过滤器会销毁
    public void destroy() {
        System.out.println("CharaterEncodngFilter 销毁");
    }
}

3、在web.xml中配置Filter过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <servlet>
    <servlet-name>ShowServler</servlet-name>
    <servlet-class>com.tom.Servlet.ShowServler</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ShowServler</servlet-name>
    <url-pattern>/show</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ShowServler</servlet-name>
    <url-pattern>/servlet/show</url-pattern>
  </servlet-mapping>
  <filter>
    <filter-name>CharaterEncodngFilter</filter-name>
    <filter-class>com.tom.filter.CharaterEncodngFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>CharaterEncodngFilter</filter-name>
<!--    只要是在/servlet中的任何请求,都会经过这个过滤器-->
    <url-pattern>/servlet/*</url-pattern>
<!--    <url-pattern>/*</url-pattern>-->
  </filter-mapping>
</web-app>

4、展示数据

package com.tom.Servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ShowServler extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("你好汤姆");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

监听器

1、编写一个监听器

实现监听器的接口和重写方法

package com.tom.Listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

//Listener 监听
//统计网站在线人数:统计session
public class OnlineCountListener implements HttpSessionListener {
    //创建Session监听
    //一旦创建Session 就会触发一次这个事件
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
        //打印获取的Session的id
        System.out.println(se.getSession().getId());
        //判断是否存在Session
        if (onlineCount==null){
            //没有就加一
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue(); //将int转换成Integer
//            onlineCount = new Integer(onlineCount+1);
            onlineCount = new Integer(count+1); //如果有就是自身的值加一
        }
        ctx.setAttribute("OnlineCount",onlineCount);
    }
//销毁Session 监听
//一旦销毁Session 就会触发一次这个事件
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
        //判断是否存在Session
        if (onlineCount==null){
            //没有就加一
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue(); //将int转换成Integer
//            onlineCount = new Integer(onlineCount+1);
            onlineCount = new Integer(count-1); //如果有就是自身的值加一
        }
        ctx.setAttribute("OnlineCount",onlineCount);

        /**
         Session销毁
         1.手动销毁 getSession().invalidate();
         2.自动销毁 在xml中配置
         */
    }
}

2、在web.xml中注册监听器

<!--  注册监听器-->
  <listener>
    <listener-class>com.tom.Listener.OnlineCountListener</listener-class>
  </listener>
<!--  定义Session过期时间-->
  <session-config>
    <session-timeout>1</session-timeout>
  </session-config>

3、页面获取Session的值

看情况是否使用

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--style="color: red"定义颜色--%>
<h1>当前访问在线人数是<span style="color: red">
<%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%>
</span>
</h1>
</body>
</html>

4、过滤器、监听器常见应用

1、监听器对窗口的实现

package com.tom.Listener;

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("你好汤姆"); //新建一个窗体
        Panel panel = new Panel(null); //面板‘
        frame.setLayout(null); //设置窗体的布局

        frame.setBounds(300,300,500,600); //设置坐标和宽高
        frame.setBackground(new Color(0, 4, 255)); //设置背景颜色

        panel.setBounds(50,50,300,300); //设置坐标和宽高
        panel.setBackground(new Color(0,255,0)); //设置背景颜色
        frame.add(panel);//将面板加入到窗体

        frame.setVisible(true);//设置窗体可见性

        frame.addWindowListener(new WindowListener() {
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");
            }

            public void windowClosing(WindowEvent e) {
                System.out.println("关闭ing");
                System.exit(0); //0正常终止,1非正常终止
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("关闭ed");
            }

            public void windowIconified(WindowEvent e) {

            }

            public void windowDeiconified(WindowEvent e) {

            }

            public void windowActivated(WindowEvent e) {
                System.out.println("激活");
            }

            public void windowDeactivated(WindowEvent e) {
                System.out.println("未激活");
            }
        });
    }
}

只监听关闭事件

        //监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(1);
                super.windowClosing(e);
            }
        });

2、用户登录之后才能进入主页!用户注销后就不能进入主页了!

将接受用的Session定义成常量

package com.tom.util;

public class Constant {
    public static final String USER_SESSION = "USER_SESSION";
}

1、用户登录之后,向Sesison中放入用户的数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/servlet/login" method="post" >
    账号:<input type="text" name="username"><br>
    密码:<input type="text" name="password">
    <input type="submit">
</form>
</body>
</html>

package com.tom.Servlet;

import com.tom.util.Constant;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       resp.setCharacterEncoding("utf-8");
       resp.setContentType("text/html");
        //获取前端请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(password);
        //判断账号密码是否正确
        if (username.equals("admin")){
            //将值放入到Session中
            req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId());
            //跳转到首页
            resp.sendRedirect("/sys/succes.jsp");
        }else {
            resp.sendRedirect("/login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

2、注销登录删除Session
package com.tom.Servlet;

import com.tom.util.Constant;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LogOutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object user_session = req.getSession().getAttribute(Constant.USER_SESSION); //获取存在的Session
        if (Constant.USER_SESSION != null) {
            req.getSession().removeAttribute(Constant.USER_SESSION); //移除这个Session
            System.out.println(getServletContext().getAttribute(Constant.USER_SESSION));
            resp.sendRedirect("/login.jsp");
        }else {
            resp.sendRedirect("/login.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、进入主页的时候要判断用户是否已经登录;

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<h1>首页</h1>
<a href="/login.jsp" >注销</a>
</body>
</html>

配置监听器

package com.tom.filter;

import com.tom.util.Constant;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request1 = (HttpServletRequest) servletRequest;
        HttpServletResponse response1 = (HttpServletResponse) servletResponse;

        Object userSession = request1.getSession().getAttribute(Constant.USER_SESSION);
        if (userSession == null){
            response1.sendRedirect("/login.jsp");
        }


        filterChain.doFilter(servletRequest,servletResponse);
    }

    public void destroy() {

    }
}

 <!--  注册监听器-->
  <filter>
    <filter-name>sysfilter</filter-name>
    <filter-class>com.tom.Listener.SysFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sysfilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
  </filter-mapping>

全文xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <servlet>
    <servlet-name>ShowServler</servlet-name>
    <servlet-class>com.tom.Servlet.ShowServler</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>login</servlet-name>
    <servlet-class>com.tom.Servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>login</servlet-name>
    <url-pattern>/servlet/login</url-pattern>
  </servlet-mapping>


  <!--  注册监听器-->
  <filter>
    <filter-name>sysfilter</filter-name>
    <filter-class>com.tom.filter.SysFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sysfilter</filter-name>
    <url-pattern>/sys/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>logout</servlet-name>
    <servlet-class>com.tom.Servlet.LogOutServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>logout</servlet-name>
    <url-pattern>/servlet/logout</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ShowServler</servlet-name>
    <url-pattern>/show</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ShowServler</servlet-name>
    <url-pattern>/servlet/show</url-pattern>
  </servlet-mapping>
  <filter>
    <filter-name>CharaterEncodngFilter</filter-name>
    <filter-class>com.tom.filter.CharaterEncodngFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>CharaterEncodngFilter</filter-name>
<!--    只要是在/servlet中的任何请求,都会经过这个过滤器-->
    <url-pattern>/servlet/*</url-pattern>
<!--    <url-pattern>/*</url-pattern>-->
  </filter-mapping>
<!--  注册监听器-->
  <listener>
    <listener-class>com.tom.Listener.OnlineCountListener</listener-class>
  </listener>

<!--  定义Session过期时间-->
  <session-config>
    <session-timeout>1</session-timeout>
  </session-config>
</web-app>

JDBC

JDBC:java连接数据库

JAVA WEB_xml_04

需要jar包的支持;

  • java.sql
  • javax.sql
  • mysql-connector-java 连接驱动 (必须要导入)

1、数据库环境

CREATE TABLE JDBC (
	id INT PRIMARY KEY auto_increment,
	`name` VARCHAR (30) NOT NULL,
	`password` VARCHAR (30),
	 email VARCHAR (30),
	 birthday DATE
);


INSERT INTO JDBC (id,`name`,`password`,email,birthday)
VALUES(1,'张三','123','123@qq','2000-01-11');
INSERT INTO JDBC 
VALUES(null,'汤姆','456','456@qq','2000-01-11');
INSERT INTO JDBC 
VALUES(NULL,'大黄','789','789@qq','2000-01-11');

SELECT * FROM JDBC;

DROP TABLE JDBC;
COMMIT;
-- 查看表结构
DESC JDBC;

2、导入数据库依赖

<!--        mysql的驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
    </dependencies>

3、JDBC使用

package com.tom.test;

import java.sql.*;

public class TestJDBC {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        //useSSL=false 防止SSl连接问题
        String url = "jdbc:mysql://121.4.118.195:3306/*****?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        String username = "root";
        String password = "*****";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.向数据库发送SQL的对象Statement :CRUD  PreparedStatement 预编译 安全的
        Statement statement = connection.createStatement();
//        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //4.编写SQL
//        String sql = "SELECT * FROM JDBC";
        String sql ="DELETE FROM JDBC WHERE ID = 3;";

        //5.执行sql 返回一个结果集 resultSet
        ResultSet rs= statement.executeQuery(sql);
        int i = statement.executeUpdate(sql); //i 受影响的行 增删改都使用executeUpdate

        while (rs.next()){
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("password="+rs.getObject("password"));
            System.out.println("email="+rs.getObject("email"));
            System.out.println("birthday="+rs.getObject("birthday"));
            System.out.println();
        }

        //6.关闭连接,释放资源 先开后关
        rs.close();
        statement.close();
        connection.close();
    }
}

4、JDBC添加实现

package com.tom.test;

import java.sql.*;

public class TestJDBC02 {
    public  static void main(String[] args) throws Exception {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        //useSSL=false 防止SSl连接问题
        String url = "jdbc:mysql://121.4.118.195:3306/****?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        String username = "root";
        String password = "*****";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.编写SQL
        String sql ="insert into JDBC (id,name,password,email,birthday) value (?,?,?,?,?);";

        //4.向数据库发送SQL的对象PreparedStatement:CRUD  PreparedStatement 预编译 安全的
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setInt(1,5);//给第一个占位符? 的值赋值为1;
        ps.setString(2,"root");//给第二个占位符? 的值赋值为root;
        ps.setString(3,"123@qq");//给第三个占位符? 的值赋值为123@qq;
        ps.setString(4,"123");
        ps.setDate(5,new Date(new java.util.Date().getTime()));
        //ps.setObject(5,"2020-10-19");



        //5.执行sql 返回一个结果集 resultSet
        int i = ps.executeUpdate(); //i 受影响的行 增删改都使用executeUpdate

        if (i>0){
            System.out.println("插入成功");
        }

        //6.关闭连接,释放资源 先开后关
        ps.close();
        connection.close();
    }
}

事务
要么都成功,要么都失败!
ACID原则:保证数据的安全。

开启事务  start transaction
事务提交 commit()
事务回滚 rollback()
关闭事务
    
转账
A:1000    
B:1000
    
A(900)---100> B(1100)    

5、Junit单元测试

依赖

<!--        单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

简单实用 @Test可以让标记的方法不需要main方法直接跑起来

import org.junit.Test;
	@Test
    public void test(){
        System.out.println("hello tom");
    }

6、sql事务代码操作及回滚

package com.tom.test;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class TestJDBC03 {

    @Test
    public void test()  {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        //useSSL=false 防止SSl连接问题
        String url = "jdbc:mysql://121.4.118.195:3306/****?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        String username = "root";
        String password = "******";

        Connection connection = null;

        //1.加载驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //2.连接数据库,代表数据库
            connection = DriverManager.getConnection(url, username, password);

            //3.通知数据库开启事务 false 开启
            connection.setAutoCommit(false);

            String sql = "UPDATE account  SET money = money-100 WHERE name = 'A';";
            //执行sql
            connection.prepareStatement(sql).executeUpdate();
            //制造错误
            int i = 1/0;

            String sql2 = "UPDATE account  SET money = money+100 WHERE name = 'B';";
            connection.prepareStatement(sql2).executeUpdate();
            //以上两条sql都执行成功了,就提交事务;
            connection.commit();
            System.out.println("成功");
        } catch (Exception e) {
            try {
                //如果出现异常,就通知数据库回滚
                connection.rollback();
            }catch (SQLException e1){
                e1.printStackTrace();
            }finally {
                try {
                    connection.close();
                }catch (SQLException e2){
                    e2.printStackTrace();
                }
            }
        }
    }
}

建表sql

CREATE TABLE account (
     id INT PRIMARY KEY AUTO_INCREMENT,
     `name` VARCHAR(40) NOT NULL ,
      money FLOAT NOT NULL 
);
DESC  account;

INSERT INTO account (`name`,money) VALUES('TOM',99999);
INSERT INTO account (`name`,money) VALUES('A',1000);
INSERT INTO account (`name`,money) VALUES('B',1000);
INSERT INTO account (`name`,money) VALUES('C',1000);
COMMIT;

SELECT id,`name`,money FROM account;

DROP TABLE account;

sql模拟事务回滚

start transaction ; #开启事务

UPDATE account  SET money = money-100 WHERE name = 'A';
UPDATE account  SET money = money+100 WHERE name = 'B';

rollback ;  #回滚
# COMMIT ;

SELECT id,`name`,money FROM account;
   <scope>test</scope>
    </dependency>

**简单实用**  @Test可以让标记的方法不需要main方法直接跑起来

```java
import org.junit.Test;
	@Test
    public void test(){
        System.out.println("hello tom");
    }

6、sql事务代码操作及回滚

package com.tom.test;

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class TestJDBC03 {

    @Test
    public void test()  {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        //useSSL=false 防止SSl连接问题
        String url = "jdbc:mysql://121.4.118.195:3306/****?useUnicode=true&characterEncoding=utf-8&useSSL=false";
        String username = "root";
        String password = "*****";

        Connection connection = null;

        //1.加载驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //2.连接数据库,代表数据库
            connection = DriverManager.getConnection(url, username, password);

            //3.通知数据库开启事务 false 开启
            connection.setAutoCommit(false);

            String sql = "UPDATE account  SET money = money-100 WHERE name = 'A';";
            //执行sql
            connection.prepareStatement(sql).executeUpdate();
            //制造错误
            int i = 1/0;

            String sql2 = "UPDATE account  SET money = money+100 WHERE name = 'B';";
            connection.prepareStatement(sql2).executeUpdate();
            //以上两条sql都执行成功了,就提交事务;
            connection.commit();
            System.out.println("成功");
        } catch (Exception e) {
            try {
                //如果出现异常,就通知数据库回滚
                connection.rollback();
            }catch (SQLException e1){
                e1.printStackTrace();
            }finally {
                try {
                    connection.close();
                }catch (SQLException e2){
                    e2.printStackTrace();
                }
            }
        }
    }
}

建表sql

CREATE TABLE account (
     id INT PRIMARY KEY AUTO_INCREMENT,
     `name` VARCHAR(40) NOT NULL ,
      money FLOAT NOT NULL 
);
DESC  account;

INSERT INTO account (`name`,money) VALUES('TOM',99999);
INSERT INTO account (`name`,money) VALUES('A',1000);
INSERT INTO account (`name`,money) VALUES('B',1000);
INSERT INTO account (`name`,money) VALUES('C',1000);
COMMIT;

SELECT id,`name`,money FROM account;

DROP TABLE account;

sql模拟事务回滚

start transaction ; #开启事务

UPDATE account  SET money = money-100 WHERE name = 'A';
UPDATE account  SET money = money+100 WHERE name = 'B';

rollback ;  #回滚
# COMMIT ;

SELECT id,`name`,money FROM account;