JavaWeb学习笔记

JavaWeb

1、基本概念

2、web服务器

Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。最主流的三个Web服务器是Apache、 Nginx 、IIS。

  • 被动程序,有请求才会响应
  • Apach
  • Nginx
  • IIS

工作原理:连接过程、请求过程、应答过程以及关闭连接

3、Tomcat

Tomcat 服务器是一个免费的开放源代码的**Web 应用服务器。当在一台机器上配置好Apache 服务器,可利用它响应HTML标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。Tomcat 实际上运行JSP 页面和Servlet。

3.4发布一个web网站

将自己写的网站放到Tomcat中指定的web应用的文件夹(webapps)下就可以访问了

网站应该有的结构:

--wwbapps:Tomact服务器的web目录
    -ROOT
    -kuangstudy:网站的目录名
    	-WEB-INF
    		-classes:java程序
    		-lib:web应用依赖的jar包
    		-web.xml:网站配置文科
    	-index.html 默认的首页
    	-static
    		-css
    			-style.css
    		-js
    		-img
    	-...

4、HTTP

4.1什么是http

超文本传输协议(Hyper Text [Transfer Protocol](https://baike.baidu.com/item/Transfer Protocol/612755?fromModule=lemma_inlink),HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。

4.2两个时代

  • http1.0

    • http/1.0:客户端可以与web服务器建立连接后,只能获得一个web资源,然后就断开了(短连接 可以使用keep-alive参数来建立长连接
  • http2.0

    • http/1.1:客户端与服务器建立连接后,可以获得多个web资源(长连接

4.3http请求

Request URL: https://baike.baidu.com/wapui/subpage/book?lemmaId=243074&lemmaTitle=HTTP&output=json
Request Method: GET  get/post请求-->get/post的区别?1.内容位置2.安全性3.缓存4.历史记录5.回退/刷新6.数据包个数7.携带数据
Status Code: 200 OK	状态码 
Remote Address: 39.156.66.35:443

1、请求行

GET和POST区别:

  • get一般用来获取数据,post一般用来提交数据
  • get请求参数放在url中,安全性低,有长度限制;post请求参数放在请求体中,安全性高,没有长度限制
  • get可以被缓存,会被保存在历史记录中,刷新或回退没有影响;post不能被缓存,不会保存在历史记录中,刷新或回退需要再次提交请求
  • get产生一个tcp数据包,header和date一起发送,200成功;post先header,100成功,再发送date,200成功

2、请求头

Accept: application/json 告诉浏览器,它所支持的数据类型
Accept-Encoding: gzip, deflate, br 支持哪种编码
Accept-Language: zh-CN,zh;q=0.9 告诉浏览器,它的语言环境
Cache-Control 缓存控制
Connection: keep-alive
4.3.1状态码

成功 2XX

  • 200 请求响应成功
  • 204 处理成功 没有资源返回

重定向 3XX

  • 301 永久重定向
  • 302 临时重定向
  • 303 请求的资源被分配了新的URL,应该使用GET方法定向获取请求的资源

客户端错误 4XX

  • 400 错误请求,服务器不理解请求的语法
  • 401 未授权 请求要求进行身份验证
  • 403 已禁止 服务器拒绝请求
  • 404 未找到 服务器找不到请求的页面
  • 408 请求超时

服务端错误 5XX

  • 500 服务器内部错误
  • 501 尚未实施,服务器不具备完成请求的功能
  • 502 错误网关
  • 503 服务不可用
  • 504 网关超时
  • 505 http版本不受支持

4.3http响应

Connection: keep-alive 连接
Content-Encoding: br 编码
Content-Length: 147 长度
Content-Type: application/json 数据类型
Date: Tue, 02 May 2023 07:38:41 GMT
Server: nginx/1.8.0

响应体

Accept: application/json 告诉浏览器,它所支持的数据类型
Accept-Encoding: gzip, deflate, br 支持哪种编码
Accept-Language: zh-CN,zh;q=0.9 告诉浏览器,它的语言环境
Cache-Control 缓存控制
Connection: keep-alive
Refrush 告诉客户端,多久刷新一次
Location 让网页重新定位

5、Maven

Why use maven?

在JavaWeb开发中,需要使用大量的jar包,手动去导入。而Maven可以自动导入jar包

5.1 Maven项目架构管理工具

Maven的核心思想:约定大于配置

  • 有约束不要去违反

Maven会规定好如何去编写Java代码,必须按照这个规范来

5.2 下载

官网:https://maven.apache.org/

5.3 环境配置

  • M2_HOME
  • MAVEN_HOME
  • 在系统的path中配置%MAVEN_HOME%\bin

5.4 修改阿里云镜像

<mirror>  
      <id>alimaven</id>  
      <name>aliyun maven</name>  
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>          
  </mirror>

5.5 本地仓库

<localRepository>D:\JAVA\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn_resp</localRepository>

5.6 IDEA中使用Maven

5.7 创建一个普通的maven项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wFown0m7-1685870174074)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230502172514251.png)]

5.8 maven侧边栏

image-20230502175559855

maven由于它的约定大于配置,之后可能会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:

<!--在build中配置resources,来防止我们资源导出失败问题-->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <excludes>
          <exclude>**/*.properties</exclude>
          <exclude>**/*.xml</exclude>
        </excludes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

5.9 IDEA操作

6、Servlet

6.1 Servlet简介

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

  • Sun公司开发动态web的一门技术
  • Sun在这些API中提供一个接口,叫做Servlet。如果想开发一个Servlet程序,只需要完成两个步骤:
    • 编写一个类,实现servlet接口
    • 把开发好的Java类部署到web服务器中

把实现了Servlet接口的Java程序叫做Servlet

1、实现过程

  • 客户端发送请求到服务端
  • 服务端将请求信息发送至Servlet
  • Servlet生成响应内容并传送给服务器。响应内容动态生成,通常取决于客户端的请求
  • 服务器将响应返回给客户端

2、生命周期

  • 客户端请求Servlet
  • 加载Servlet类到内存
  • 实例化并调用init()方法初始化该Servlet
  • 执行service()(根据请求方法不同调用doGet()或者doPost(),此外还有doHead(),doPut(),doTrace(),doDelete(),doOptions(),doDestroy())
  • 加载和实例化Servlet,一般是动态执行的。但是通常会提供一个管理的选项,用于在Server启动时强制装载和初始化特定的Servlet
  • 服务器关闭或重启时,会调用destroy()销毁所有的Servlet实例
init()初始化,一个带参init(ServletConfig config),一个无参
service()
destroy()
getServletConfig()获取ServletConfig对象,该对象可以获取到Servlet的一些信息,如ServletName、ServletContext(Servlet对象上下文,通过该对象可以获取servlet的路径、方法等信息)、InitParameter、InitParameterNames。

6.2 HelloServlet

Servlet接口在Sun公司有两个默认的实现类:HttpServlet,GenericServlet

1、构建一个Maven项目

2、关于maven父子工程的理解:

父项目中会有:

 <modules>
        <module>servlet-01</module>
    </modules>

子项目中会有

<parent>
        <artifactId>javaweb-02-servlet</artifactId>
        <groupId>com.itwrj</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

父项目中的jar包子项目可以使用

3、Maven环境优化

换成最新的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-app>

插入java、resources

image-20230502193403981

4、编写一个Servlet程序

  1. 编写一个普通类
  2. 实现一个Servlet接口,继承HttpServlet
public class HelloServlet extends HttpServlet {

    //由于get和post只是实现请求的不同方式,可以互相调用,业务逻辑都一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter(); //响应流
        
        writer.print("Hello,Servlet");
    }

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

5、编写Servlet的映射

why?我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以需要在web服务器中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径

<!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.itwrj.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

6、配置Tomcat

image-20230502220925340 image-20230502220947853

7、启动测试,OK!

6.3 Servlet原理

Servlet是由web服务器调用(Tomcat),web服务器在收到浏览器请求后会

image-20230505171422345

6.4 Mapping问题

  1. 一个Servlet请求可以指定一个映射路径

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    
  2. 一个Servlet请求可以指定多个映射路径

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello2</url-pattern>
        </servlet-mapping>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello3</url-pattern>
        </servlet-mapping>
    
  3. 一个Servlet请求可以指定通用映射路径

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello/*</url-pattern>
        </servlet-mapping>
        //*通配符
    
  4. 指定一些后缀或者前缀等…

    <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>*.wrj</url-pattern>
        </servlet-mapping>
        //*.xxx 自定义后缀 *之前不能加任何路径 例如/*.wrj /hello/*.wrj都不行
    
  5. 优先级问题

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

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

6.5 ServletContext

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

1、共享数据

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

image-20230505181059176
//创建内容的类
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //PrintWriter writer = resp.getWriter();
        //writer.print("I love you");
        System.out.println("Hello");

        //this.getInitParameter(); 初始化参数
        //this.getServletConfig(); 获取Servlet配置
        //this.getServletContext(); 获取Servlet上下文

        ServletContext context = this.getServletContext();

        String username = "王溶基";//数据
        context.setAttribute("username",username);//将一个数据保存在了ServletContext中,名字为username 值为username

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
//获取的类
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();

        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
//配置xml
<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.itwrj.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.itwrj.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

测试访问结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DHOEAi0m-1685870174076)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230505182520907.png)]

2、获取初始化参数
  1. 在web.xml中配置初始化参数

    <!--配置一些web应用的初始化参数-->
        <context-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
        </context-param>
    
  2. 获取

    public class ServletDemo3 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
    
            String url = context.getInitParameter("url");
            resp.getWriter().print(url);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    
  3. 测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yU6PhJiI-1685870174078)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230505185226213.png)]

3、请求转发

请求转发和重定向的区别?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wnqKq3tK-1685870174079)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230505190259934.png)]

public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("进入了sd4");
        //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
        //requestDispatcher.forward(req,resp);//调用forward实现请求转发
        context.getRequestDispatcher("/gp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<servlet>
        <servlet-name>sd4</servlet-name>
        <servlet-class>com.itwrj.servlet.ServletDemo4</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>sd4</servlet-name>
        <url-pattern>/sd4</url-pattern>
    </servlet-mapping>
4、读取资源文件

Properties类

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTsDmAt8-1685870174079)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230505191436868.png)]

需要一个文件流:

username=root
password=1314521Wrj.
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();

        InputStream is = context.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().print(user + ":" + pwd);
    }

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

测试结果:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1BPHQm4-1685870174080)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230505193501196.png)]

6.6 HttpServletResponse

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

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

1、简单分类

负责向浏览器发送数据的方法

ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException; //中文用它

负责向浏览器发送响应头的方法

void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

void setDateHeader(String var1, long var2);

void addDateHeader(String var1, long var2);

void setHeader(String var1, String var2);

void addHeader(String var1, String var2);

void setIntHeader(String var1, int var2);

void addIntHeader(String var1, int var2);

响应的状态码

int SC_OK = 200;

int SC_MOVED_PERMANENTLY = 301; //永久重定向

int SC_MOVED_TEMPORARILY = 302; //暂时重定向

int SC_NOT_FOUND = 404; //未找到

int SC_INTERNAL_SERVER_ERROR = 500; //服务器错误

int SC_BAD_GATEWAY = 502; //网关错误

2、常见应用

  1. 向浏览器输出消息

  2. 下载文件

    1. 获取下载文件的路径

    2. 下载文件的文件名

    3. 想办法让浏览器能够支持下载我们需要的东西

    4. 获取下载文件的输入流

    5. 创建缓冲区

    6. 获取OutputStream对象

    7. 将FileOutputStream流写入到buffer缓冲区

    8. 使用OutputStream将缓冲区中的数据输出到客户端

      public class FileServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //1. 获取下载文件的路径
              String realPath ="D:\\idea\\idea-project\\javaweb-02-servlet\\response\\src\\main\\resources\\王溶基.png";
              System.out.println("获取下载文件的路径:"+realPath);
              //2. 下载文件的文件名
              String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
              //3. 想办法让浏览器能够支持下载我们需要的东西,中文文件名URLEncoder.encode编码
              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 {
              super.doPost(req, resp);
          }
      }
      
      
  3. 验证码功能

    验证码怎么实现?

    • 前端实现
    • 后端实现,需要用到Java的图片类,产生一个图片
    public class ImageServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            //如何让浏览器5s自动刷新一次
            resp.setHeader("refresh","3");
    
            //在内存中创建一个图片
            BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
            //得到图片
            Graphics2D g = (Graphics2D) image.getGraphics(); //笔
            //设置图片的背景颜色
            g.setColor(Color.white);
            g.fillRect(0,0,80,20);
            //给图片写数据
            g.setColor(Color.blue);
            g.setFont(new Font(null,Font.BOLD,20));
            g.drawString(makeNum(),0,20);
    
            //告诉浏览器这个请求用图片的方式打开
            resp.setContentType("image/jpeg");
            //网站存在缓存,不让浏览器缓存
            resp.setDateHeader("expires",-1);
            resp.setHeader("Cache-Control","no-cache");
            resp.setHeader("Pragma","no-cache");
    
            //把图片写给浏览器
            boolean write = ImageIO.write(image,"jpg",resp.getOutputStream());
    
        }
    
        //生成随机数
        private String makeNum(){
            Random random = new Random();
            String num = random.nextInt(9999999) + "";
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i <7-num.length(); i++) {
                sb.append("0");
            }
            String s = sb.toString() + num;
            return num;
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    
    <servlet>
        <servlet-name>ImageServlet</servlet-name>
        <servlet-class>com.itwrj.servlet.ImageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ImageServlet</servlet-name>
        <url-pattern>/img</url-pattern>
    </servlet-mapping>
    
    image-20230506204627699
  4. Response重定向

image-20230506202024698

一个web资源B收到客户端A请求后,B会通知A客户端去访问另外一个web资源C,这个过程叫重定向

常见场景:

  • 用户登录(登录成功跳转到另一个页面)
void sendRedirect(String var1) throws IOException;
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        /**
         * resp.setHeader("Location","/r/img");
         * resp.setStatus(302);*/

        resp.sendRedirect("/r/img");
    }
<servlet>
    <servlet-name>RedirectServlet</servlet-name>
    <servlet-class>com.itwrj.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RedirectServlet</servlet-name>
    <url-pattern>/red</url-pattern>
</servlet-mapping>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l5KtS2XX-1685870174081)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230506204759587.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Woxma3ZZ-1685870174082)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230506204824419.png)]

面试题:重定向和请求转发的区别?

相同点:

  • 页面都会实现跳转

不同点:

  • 请求转发的时候,地址栏的url不会变化
  • 重定向的时候,地址栏的url会发生变化

测试:

public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入这个请求了");

        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+":"+password);

        //重定向的时候注意路径问题 否则会404
        resp.sendRedirect("/r/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
<html>
<body>
<h2>Hello World!</h2>

<%--这里提交的路径需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username">
    密码:<input type="password" name="password">
    <input type="submit">
</form>


</body>
</html>
<servlet>
    <servlet-name>RequestTest</servlet-name>
    <servlet-class>com.itwrj.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RequestTest</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eeOx866m-1685870174082)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230506205002294.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dofrjjdv-1685870174083)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230506205016570.png)]

成功跳转到success.jsp

6.7 HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过http协议访问服务器,http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息

1、 获取前端传递的参数 + 请求转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aVYKIxhV-1685870174084)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230517185617339.png)]

public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");

        System.out.println("=================================");
        //后台接收中文乱码问题
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("=================================");

        System.out.println(req.getContextPath());
        //通过请求转发
        //这里的"/"代表当前的web应用
        req.getRequestDispatcher("/success.jsp").forward(req,resp);

    }

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

请求转发(307)和重定向(302)的区别?
  1. 地址栏显示

    • 请求转发是服务器内部的重定向,服务器直接访问目标地址的url,把里面的东西取出来,但是客户端并不知道,因此请求转发的url不会改变
    • 重定向是服务器根据逻辑,发送一个状态码,高速浏览器去重新请求这个地址,所以地址栏显示的是新的url
  2. 数据共享

    • 请求转发由于在整个过程中使用的是一个request,因此请求转发会将request的信息带到被重定向的jsp或者servlet中使用。即可以数据共享
    • 重定向不能共享
  3. 应用

    • 请求转发一般用于用户登录的时候,根据角色转发到响应的模块
    • 重定向一般用于用户注销的时候返回主页面或跳转到其他的页面
  4. 效率

    请求转发>重定向

  5. 本质

    请求转发是服务器上的行为,重定向是客户端的行为

7、Cookie、Session

7.1、会话

**会话:**用户打开一个浏览器,点击了很多超连接,访问多个web资源,关闭浏览器。这个过程叫会话。

**有状态会话:**一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话

你能怎么证明你是西开的学生?

你 西开

  1. 发票 西开给你发票
  2. 学校登记 西开标记你来过了

一个网站,怎么证明你来过了?

客户端 服务端

  1. 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了------------>cookie
  2. 服务器登记你来过了,下次你来的时候我来匹配你 ---------------->session

7.2、保存会话的两种技术

cookie

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

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把信息或数据放在session中

常见应用:网站登录之后下次不用再登录,可以直接访问

7.3、Cookie

image-20230518170107975
  1. 从请求中拿到cookie信息

  2. 服务器响应给客户端cookie

    Cookie[] cookies = req.getCookies();//获得Cookie
    cookie.getName();//获得cookie中的key
    cookie.getValue();//获得cookie中的value
    Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
    cookie.setMaxAge(24*60*60);//设置cookie的有效期
    resp.addCookie(cookie);//响应给客户端一个cookie
    

cookie一般会保存在本地的用户目录下的appdate

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

  • 一个cookie只能保存一个信息
  • 一个web服务器可以给浏览器发送多个cookie,每个服务器最多存放20个cookie
  • 浏览器最多保存300个cookie
  • cookie大小有限制为4kb

删除Cookie

  • 不设置有效期,关闭浏览器,自动失效
  • 设置有效期为0

编码解码解决中文数据传递乱码问题

URLEncoder.encode("王溶基","utf-8")
URLDecoder.decode(cookie.getValue(),"utf-8")

7.4、Session(重点)

image-20230518170343595

什么是Session?

  • 服务器会为每一个用户(浏览器)创建一个Session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后,整个网站都可以访问------>保存购物车信息;保存用户信息…
Session和Cookie的区别?
  • Cookie把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
  • Session把用户的数据写到用户独占的Session中,服务端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建
使用场景
  • 保存一个用户登录的信息
  • 购物车信息
  • 在整个网站中经常会使用的数据,我们将它保存在Session中
package com.itwrj.servlet;

import com.itwrj.pojo.Person;

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

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        resp.setCharacterEncoding("utf-16");
        req.setCharacterEncoding("utf-16");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session
        HttpSession session = req.getSession();

        //给Session中存东西
        session.setAttribute("name",new Person("王溶基",22));

        //获取sessionid
        String id = session.getId();

        //判断session是不是新创建的
        if (session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+id);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:"+id);
        }

        //Session创建的时候做了什么事情
        //Cookie cookie = new Cookie("JSESSSIONID", "id");
        //resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
package com.itwrj.servlet;

import com.itwrj.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 SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        resp.setCharacterEncoding("utf-16");
        req.setCharacterEncoding("utf-16");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session
        HttpSession session = req.getSession();

        Person person = (Person) session.getAttribute("name");

        System.out.println(person.toString());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
package com.itwrj.servlet;

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 SessionDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手动注销session
        session.invalidate();
    }

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

设置session自动过期:web.xml配置

    <!--设置session默认的失效时间-->
    <session-config>
        <!--15min后session自动失效,以分组为单位-->
        <session-timeout>15</session-timeout>
    </session-config>

8、JSP

8.1、什么是JSP

Java Server Pages:Java服务器端页面,也和Servlet一样,用于开发动态web

最大的特点:写JSP就像在写HTML

区别:

  • HTML只给用户提供静态的数据
  • JSP页面中可以嵌入Java代码,为用户提供动态数据

8.2、JSP原理

思路:JSP到底怎么执行的?

  • 代码层面没有任何问题

  • 服务器内部工作

    tomcat中有一个work目录

    IDEA中使用Tomcat的会在IDEA中生成一个work目录

    image-20230518174744623
C:\Users\wang\AppData\Local\JetBrains\IntelliJIdea2022.1\tomcat\42505f15-3178-4606-b195-51b9223376cc\work\Catalina\localhost\ROOT\org\apache\jsp

发现页面转变成了Java程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZIGyvLmC-1685870174084)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230518174951737.png)]

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet

JSP最终也会被转化为一个Java程序

JSP本质上就是一个Servlet

//初始化  
public void _jspInit() {
  }
//销毁
  public void _jspDestroy() {
  }
//JSPService
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

1.判断请求

2.内置一些对象

    final javax.servlet.jsp.PageContext pageContext;	//页面上下文
    javax.servlet.http.HttpSession session = null;		//session
    final javax.servlet.ServletContext application;		//applicationContext
    final javax.servlet.ServletConfig config;			//config
    javax.servlet.jsp.JspWriter out = null;				//out
    final java.lang.Object page = this;					//page 当前
	final javax.servlet.http.HttpServletRequest request	//请求
	final javax.servlet.http.HttpServletResponse response//响应
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;

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

response.setContentType("text/html");			//设置页面的响应类型
pageContext = _jspxFactory.getPageContext(this, request, response,
                                          null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;

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

image-20230525141127368

在JSP页面中,只要是Java代码就会原封不动的输出

如果是HTML代码,就会被转化为out.write()输出到前端

8.3、JSP基础语法

任何语言都有自己的语法。JSP作为Java技术的一种应用,拥有一些自己扩充的语法,Java的所有语法都支持

JSP表达式

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

JSP脚本片段

  <%--JSP脚本片段--%>
  <%
    int sum = 0;
    for(int i=1; i<=100; i++){
      sum += i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
  %>
<%
    int x = 10;
    out.println(x);
  %>
  <p>这是一个JSP文档</p>
  <%
    int y = 2;
    out.println(y);
  %>

  <hr>

  <%--在代码中嵌入HTML元素--%>
  <%
    for (int i = 0; i < 5; i++) {
  %>
  <h1>Hello World <%= i%></h1>
  <%
    }
  %>

JSP声明

<%!
    static {
      System.out.println("Loading Servlet!");
    }

    private int globalVal = 0;

    public void kuang(){
      System.out.println("进入了这个方法");
  }
  %>

JSP声明会被编译到JSP生成Java的类中。其他的会被生成到jspService方法中

8.4、JSP指令

<%@ page ...%>


<%@ include file=""%> 

<%--@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"/>

8.5、9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application [ServletContext] 存东西
  • Config [ServletConfig]
  • out
  • page
  • exception
pageContext.setAttribute("name1","1号");//保存的数据只在一个页面中有效
request.setAttribute("name2","2号");//保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","3号");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","4号");//保存的数据只在服务器中有效,从打开服务器到关闭服务器

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

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

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

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

</dependency>
<!--JSTL表达式的依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
</dependency>
<!--stanard标签的依赖-->
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.5</version>
    <scope>runtime</scope>
</dependency>

EL表达式:${}

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

JSP标签

<jsp:include></jsp:include>
<jsp:parem...></jsp:parem...>
<jsp:forward...></jsp:forward...>
<jsp:usebean></jsp:usebean>
<jsp:setproperty></jsp:setproperty>
<jsp:getproperty></jsp:getproperty>

<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="wrj"/>
    <jsp:param name="age" value="12"/>
</jsp:forward>

JSTL表达式

为了弥补HTML标签的不足;他自定义许多标签可以供我们使用,标签的功能和Java代码一样

核心标签

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
image-20230525192004541

格式化标签

SQL标签

XML标签

JSTL标签库使用步骤

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat中也需要引入jstl和standard的包,否则会报错:JSTL解析错误
<body>

<h4>if测试</h4>

<hr>

<form action="coreif.jsp" method="get">
    <%--EL表达式获取表单中的数据
    ${param.参数}
    --%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>

<%--判断如果提交的用户名是管理员,则登录成功--%>

<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您"></c:out>
</c:if>

<c:out value="${idAdmin}"></c:out>

</body>

9、JavaBean

实体类

JavaBean有特定的写法

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

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

ORM:对象关系映射

  • 表对应类
  • 表中的字段对应类的属性
  • 表中的行对应类的一个对象

10、SpringMVC三层架构

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

10.1、早些年

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S4tO3ss9-1685870174086)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230526111216067.png)]

用户直接访问控制层,控制层就可以直接操作数据库

servlet-->CRUD-->数据库
弊端:程序臃肿,不利于维护
servlet的代码中:处理请求、响应、试图跳转、处理JDBC、处理业务代码、处理逻辑代码

10.2、三层架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bGj8e04b-1685870174086)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230526112030856.png)]

Model

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

View

  • 展示数据
  • 提供连接发起Servlet请求

Controller

  • 接收用户请求:request 请求参数、Session信息

  • 交给业务层处理对应的代码

  • 控制视图的跳转

    登录--->接收用户的登录请求--->处理用户的请求(获取登录的参数:username,password)--->交给业务层处理登录业务(判断用户密码是否正确:事务)--->Dao层查询用户名和密码是否正确--->数据库
    

11、过滤器Filter

用来过滤网站的是数据

  • 处理中文乱码
  • 登录验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pbsGhR25-1685870174087)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230526112816692.png)]

Filter开发步骤:

  1. 导包

        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.3</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp.jstl</groupId>
                <artifactId>jstl-api</artifactId>
                <version>1.2</version>
            </dependency>
            <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.47</version>
            </dependency>
        </dependencies>
    
  2. 编写过滤器

    public class CharacterEncodingFilter implements Filter {
    
        //初始化 web服务器启动,就已经初始化了,随时等待监听过滤
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("已经初始化了");
        }
    
        //filterChain:链
        /*
        1.过滤器中的所有代码,在过滤特定请求的时候都会执行
        2.必须要让过滤器继续执行
        filterChain.doFilter(servletRequest,servletResponse);
         */
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            servletRequest.setCharacterEncoding("utf-16");
            servletResponse.setCharacterEncoding("utf-16");
            servletResponse.setContentType("text/html;charset=UTF-8");
    
            System.out.println("CharacterEncodingFilter执行前......");
            filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里就会被拦截停止!
            System.out.println("CharacterEncodingFilter执行后......");
        }
    
        //web服务器关闭的时候过滤器会销毁
        public void destroy() {
            System.out.println("已经销毁了");
        }
    }
    
    <filter>
            <filter-name>CharacterEncodingFilter</filter-name>
            <filter-class>com.itwrj.filter.CharacterEncodingFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <!--只要是/servlet的任何请求,都会经过这个过滤器-->
            <url-pattern>/servlet/*</url-pattern>
            <!--<url-pattern>/*</url-pattern>-->
        </filter-mapping>
    

12、监听器

实现一个监听器的接口。有n种

  1. 编写一个监听器

    //统计在线人数:统计session
    public class OnlineCountListener implements HttpSessionListener {
        //创建session监听
        //一旦创建一个session,就会触发一次这个事件  观察者模式
        public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            ServletContext context = httpSessionEvent.getSession().getServletContext();
    
            System.out.println(httpSessionEvent.getSession().getId());
    
            Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
    
            if(onlineCount==null){
                onlineCount = new Integer(1);
            }else {
                int count = onlineCount.intValue();
                onlineCount = new Integer(count+1);
            }
    
            context.setAttribute("OnlineCount",onlineCount);
        }
    
        //销毁session监听
        //一旦销毁一个session,就会触发一次这个事件  观察者模式
        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            ServletContext context = httpSessionEvent.getSession().getServletContext();
            Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
    
            if(onlineCount==null){
                onlineCount = new Integer(0);
            }else {
                int count = onlineCount.intValue();
                onlineCount = new Integer(count-1);
            }
    
            context.setAttribute("OnlineCount",onlineCount);
    
        }
        
        /*
        Session销毁
        1.手动销毁 getSession().invalidate();
        2.自动销毁 在web.xml中配置session过期时间
        <session-config>
            <session-timeout>1</session-timeout>
        </session-config>
         */
    }
    
    
  2. web.xml中注册监听器

        <listener>
            <listener-class>com.itwrj.listener.OnlineCountListener</listener-class>
        </listener>
    

13、过滤器、监听器的常见应用

监听器:GUI编程中经常使用

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,500);
        frame.setBackground(new Color(0,0,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);
            }

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

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

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

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

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

用户登录之后才能进入主页。用户注销之后就不能进入主页。

  1. 用户登录之后,向Session中放入用户的数据

  2. 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
    
        if(request.getSession().getAttribute(Constant.USER_SESSION)==null){
            response.sendRedirect("/error.jsp");
        }
    
        filterChain.doFilter(servletRequest,servletResponse);
    }
    

14、JDBC

需要jar包的支持

  • java.sql
  • javax.sql
  • mysql-connector…

环境搭建

CREATE TABLE users(
id int PRIMARY KEY,
name VARCHAR(40),
password VARCHAR(40),
email VARCHAR(60),
birthday DATE
);

INSERT INTO users(id,name,password,email,birthday)
VALUES (1,"张三","123456","zs@qq.com","2001-01-01");
INSERT INTO users(id,name,password,email,birthday)
VALUES (2,'李四',"123456","zs@qq.com","2001-01-01");
INSERT INTO users(id,name,password,email,birthday)
VALUES (3,'王五',123456,"zs@qq.com","2001-01-01");

SELECT *
FROM users

导入数据库依赖

 <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
    </dependencies>

IDEA中连接数据库

public class TestJDBC {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=true";
        String username = "root";
        String password = "1314521Wrj.";

        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);
        //3.向数据库发送SQL的对象statement
        Statement statement = connection.createStatement();
        //4.编写SQL
        String sql = "select * from users";
        //5.执行查询SQL
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()){
            System.out.println(resultSet.getObject("id"));
            System.out.println(resultSet.getObject("name"));
            System.out.println(resultSet.getObject("password"));
            System.out.println(resultSet.getObject("email"));
            System.out.println(resultSet.getObject("birthday"));
        }
        //6.关闭连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

JDBC固定步骤:

  1. 加载驱动
  2. 连接数据库,connection代表数据库
  3. 向数据库发送SQL的执行对象statement
  4. 编写SQL
  5. 执行SQL
  6. 关闭连接

事务

ACID原则

开启事务
事务提交
事务回滚
关闭事务

Junit单元测试*

依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

简单使用

@Test注解只有在方法上有效,只要加了这个注解的方法就可以直接运行

public class TestJunit {

    @Test
    public void test(){
        System.out.println("Hello");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vsEeirIX-1685870174089)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230526184313661.png)]

public class TestJunit {

    @Test
    public void test(){
        System.out.println(1/0);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Z9IV1wV-1685870174092)(C:\Users\wang\AppData\Roaming\Typora\typora-user-images\image-20230526184346916.png)]
{
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//useUnicode=true&characterEncoding=utf-8 解决中文乱码
String url = “jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8&useSSL=true”;
String username = “root”;
String password = “1314521Wrj.”;

    //1.加载驱动
    Class.forName("com.mysql.cj.jdbc.Driver");
    //2.连接数据库,代表数据库
    Connection connection = DriverManager.getConnection(url, username, password);
    //3.向数据库发送SQL的对象statement
    Statement statement = connection.createStatement();
    //4.编写SQL
    String sql = "select * from users";
    //5.执行查询SQL
    ResultSet resultSet = statement.executeQuery(sql);
    while (resultSet.next()){
        System.out.println(resultSet.getObject("id"));
        System.out.println(resultSet.getObject("name"));
        System.out.println(resultSet.getObject("password"));
        System.out.println(resultSet.getObject("email"));
        System.out.println(resultSet.getObject("birthday"));
    }
    //6.关闭连接
    resultSet.close();
    statement.close();
    connection.close();
}

}


**JDBC固定步骤:**

1. 加载驱动
2. 连接数据库,connection代表数据库
3. 向数据库发送SQL的执行对象statement
4. 编写SQL
5. 执行SQL
6. 关闭连接



**事务**

ACID原则

```java
开启事务
事务提交
事务回滚
关闭事务

Junit单元测试*

依赖

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>

简单使用

@Test注解只有在方法上有效,只要加了这个注解的方法就可以直接运行

public class TestJunit {

    @Test
    public void test(){
        System.out.println("Hello");
    }
}

[外链图片转存中…(img-vsEeirIX-1685870174089)]

public class TestJunit {

    @Test
    public void test(){
        System.out.println(1/0);
    }
}

[外链图片转存中…(img-9Z9IV1wV-1685870174092)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值