JavaWeb

视频地址:https://www.bilibili.com/video/BV12J411M7Sj?spm_id_from=333.999.0.0

0. 一些环境依赖

Tomcat10需要的jakarta.servlet-api(porm.xml)

  <dependencies>

   <dependency>
     <groupId>jakarta.servlet</groupId>
     <artifactId>jakarta.servlet-api</artifactId>
     <version>5.0.0</version>
   </dependency>

   <dependency>
     <groupId>jakarta.servlet.jsp</groupId>
     <artifactId>jakarta.servlet.jsp-api</artifactId>
     <version>3.0.0</version>
   </dependency>

   <dependency>
     <groupId>org.glassfish.web</groupId>
     <artifactId>jakarta.servlet.jsp.jstl</artifactId>
     <version>2.0.0</version>
   </dependency>

   <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.26</version>
   </dependency>


   <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
   <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.9</version>
   </dependency>

   <dependency>
     <groupId>jakarta.servlet.jsp.jstl</groupId>
     <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
     <version>2.0.0</version>
   </dependency>

   <dependency>
     <groupId>taglibs</groupId>
     <artifactId>standard</artifactId>
     <version>1.1.2</version>
   </dependency>

   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.11</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.junit.jupiter</groupId>
     <artifactId>junit-jupiter</artifactId>
     <version>RELEASE</version>
     <scope>compile</scope>
   </dependency>
 </dependencies>

web.xml格式有时需要换(不然有的时候会莫名其妙报错,不知道原因)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

</web-app>

Modules中需要添加Tomcat,不然导入不了HttpServlet这个包

1. 基本概念

1.1前言

  • web,网页的意思, www.baidu.com

  • 静态web

    • html,css

    • 提供给所有人看的数据始终不发生变化!

  • 动态web

    • 几乎所有的网站都是动态的,如淘宝

    • 提供给搜有人看的数据始终会发生变化,每个人在不同是的时间,不同的地点看到的信息各不相同!

    • 技术栈:Servlet/JSP, ASP,PHP

在Java中, 动态web资源开发的技术统称为JavaWeb

1.2 web应用程序

web应用程序:可以提供浏览器访问的程序;

  • a.html.b.htim….多个web资源,这些web资源可以被外界访问,对外界提供服务;

  • 你们能访问到的任何一个页面或者资源,都存在于这个世界的某一个角落的计算机上。

  • URL

  • html, css, js

  • Java程序

  • jar包

  • 配置文件(Properties)

web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来统一管理;

1.3 静态web

  • *.htm *.html,这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。通络;

  • 静态web存在的缺点

    • Web页面无法动态更新,所有用户看到都是同一个页面

      • 轮播图,点击特效:伪动态

      • JavaScript [实际开发中,它用的最多]

      • VBScript

    • 它无法和数据库交互(数据无法持久化,用户无法交互)

1.4 动态web

页面会动态展示: “Web的页面展示的效果因人而异”;

缺点:

  • 加入服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序

    • 停机维护

优点:

  • Web页面可以动态更新,所有用户看到都不是同一个页面

  • 它可以与数据库交互网络页面可以动态更新,所有用户看到都不是同一个页面

  • 它可以与数据库交互(数据持久化:注册,商品信息,用户信息….)

2. web服务器

2.1 技术讲解

ASP:

  • 微软:国内最早流行的就是ASP;

  • 在HTML中嵌入了VB的脚本,ASP+COM;

  • 在ASP开发中,基本一个页面都有几千行的业务代码,页面极其换乱

  • 维护成本高!

  • C#

  • IIS

php:

  • PHP开发速度很快,功能很强大,跨平台,代码很简单(70%,WP)无法承载大访问量的情况(局限性)

  • 无法承载大访问量的情况((局限性)

JSP/Servlet:

B/S:浏览器和服务器

C/S:客户端和服务器

  • sun公司主推的B/S架构

  • 基于Java语言的(所有的大公司,或者一些开源的组件,都是用ava写的)

  • 可以承载三高问题带来的影响(高服务,高并发,高性能);

  • 语法像ASP

…….

2.2 web服务器

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息

IIS

微软的; ASP… , Windows中自带的

Tomact

Tomcat实际上运行ISP.页面和Servlet。另外,Tomcat和IS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和SP容器,独立的Serlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。目前Tomcat最新版本为10.0.14。

3. Tomcat

3.1 简介

本地访问测试:http://localhost:8080/

3.2 发布一个web网站

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

网站应该有的结构

-webapps : Tomcat服务器目录
-ROOT 默认地址
-xxx : 网站的根目录
-WEB-INF
-classes : java程序
-lib : web应用所依赖的jar包
-web.xml : 网站配置文件
-index.html/index.jsp
-static
-css
-style.css
-js
-img
......

4. HTTP

4.1 什么是HTTP

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。

  • 文本:html,字符串,~……

  • 超文本:图片,音乐,视频,定位,地图…..

  • 默认端口:80

4.2 两个时代

  • http1.0

    • HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接

  • http2.0

    • HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。

4.3 http请求

  • 客户端—发请求(Resuest) —服务器

百度:

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK //状态吗
Remote Address: 39.156.66.14:443
Referrer Policy: strict-origin-when-cross-origin
Accept:text/htm7
Accept-Encoding:gzip, deflate,brAccept-Language :zh-CN,zh ; q=0.9
cache-contro1:max-age=O
connection :keep-alive
  1. 请求行

    • 请求行中的请求方式: GET

    • 请求方式: Get,psot,HEAD,DELETE,PUT,TRACT

      • get: 请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效

      • post: 请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。

  2. 消息头

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式GBK UTF-8GB2312IS08859-1
Accept-Language:告诉浏览器,它的语言环境
cache-contro1:缓存控制
connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机

4.4 http响应

  • 服务器—响应—客户端

百度:

cache-control: private  缓存控制
Connection :Keep-Alive  连接
content-Encoding:gzip   编码
content-Type :text/html 类型

1.响应体

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式GBK UTF-8GB2312IS08859-1
Accept-Language:告诉浏览器,它的语言环境
cache-contro1:缓存控制
connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;

2.响应状态码

  1. 200:请求响应成功200

  2. 3xx:请求重定向(重定向:你重新到我给你新位置去;)

  3. 4xx:找不到资源404(资源不存在)

  4. 5xx:服务器代码错误500,502:网关错误

常见面试题: 当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?\

5. Maven

  1. 在Javaweb开发中,需要使用大量的jar包,我们手动去导入;

  2. 如何能够让一个东西自动帮我导入和配置这个jar包。由此,Maven诞生了!

5.1 Maven项目架构管理工具

我们目前用来就是方便导入jar包的!

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

  • 有约束,不要去违反

阿里云镜像

    <mirror>
<id>nexus-a7iyun</id>
<mirrorof>*,!jeecg,!jeecg-snapshots</mirrorof>
<name>Nexus aliyun</name>
<ur1>http://maven.aliyun.com/nexus/content/groups/public</ur1>
</mirror>

 

本地仓库:

<localRepository>F:\迅雷下载\apache-maven-3.8.4-bin\apache-maven-3.8.4\maven-repo</localRepository>

5.2 在IDEA中使用Maven

  1. 建立一个Maven项目

2. 建立一个Maven项目

pom.xml:

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

<!--Maven版本和配置文件-->
<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>

<!--这里可以配置GAV-->
<groupId>org.example</groupId>
<artifactId>javawebMaven02</artifactId>
<version>1.0-SNAPSHOT</version>


<!--配置-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>

<!--导入jar包-->
<!--Maven的高级之处在于,他会帮你导入这个JAR包所依赖的其他jar-->
<dependencies>

</dependencies>
</project>

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

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<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>
</build>

3. 使用Maven仓库

https://mvnrepository.com/

4. 运行HelloWorld

package HelloWorld;

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 HelloWorld extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(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">

<!-- 注册Servlet -->
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld.HelloWorld</servlet-class>
</servlet>
<!-- 一个Servlet对应一个Mapping: 映射 -->
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<!-- 映射的请求路径 -->
<url-pattern>HelloWorld</url-pattern>
</servlet-mapping>

</web-app>

5. jakarta.servlet.ServletException;导入不进去问题

https://www.cnblogs.com/cn-chy-com/p/10992046.html

6. Servlet

6.1 简介

  • Servlet就是sun公司开发动态web的一门技术

  • Sun在这些API中提供一个接口叫做: Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:

    • 编写一个类,实现Servlet接口

    • 把开发好的Java类部署到web服务器中

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

6.2 HelloServlet

 

  1. 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven主工程;

  2. 关于父子工程的理解

    <modules>
    <module>Servlet01</module>
    </modules>

    父项目中的java子项目可以直接使用

  3. 编写一个Servlet程序

    1. 编写一个普通类

    2. 实现Serclet接口, 这里我们直接继承HttpServlet

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

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

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
  1. 编写Servlet的映射

    为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要再web服务中注册我们写Servlet,还需给他一个浏览器能够访问的路 径

    <!--注册Servlet-->
    <servlet>
    <servlet-name>Test01</servlet-name>
    <servlet-class>Test01.Test01</servlet-class>
    </servlet>

<!–Servlet的请求路径–> <servlet-mapping> <servlet-name>Test01</servlet-name> <url-pattern>/Test01</url-pattern> </servlet-mapping>


5. 配置Tomcat![](https://img2022.cnblogs.com/blog/2502815/202203/2502815-20220330200448389-1718049148.png)![](https://img2022.cnblogs.com/blog/2502815/202203/2502815-20220330200448149-931794982.png)发布路径对就可以了

### 6.3 Servlet原理

![](https://img2022.cnblogs.com/blog/2502815/202203/2502815-20220330200447714-1777007498.png)

### 6.4 Mapping问题

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

```xml
<servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test01</url-pattern>
</servlet-mapping>

2.一个Servlet可以指定多个映射路径

<servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test01</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test02</url-pattern>
</servlet-mapping> <servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test03</url-pattern>
</servlet-mapping>

3.一个Servlet可以指定通用映射路径

4.默认请求路径

<servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test01/*</url-pattern>
</servlet-mapping>

5.指定一些后缀或者前缀等等…

<servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>*.hanbing</url-pattern>
</servlet-mapping>

注意:*前面不能加项目映射的路径

6.优先级问题

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

6.5 ServletContext

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

 

1. 共享数据

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

protected void docet(HttpServletRequest req,HttpservletResponse resp)throws servletException,IOException {
servletcontext context = this.getservletcontext();string ur7 = context.getInitParameter("url");
resp. getwriter(.print(ur1);
}
}

2. 参数初始化

  <context-param>
<param-name>url</param-name>
<param-value>http://blog.hanbing777.top</param-value>
</context-param>
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().print(url);

3. 请求转发

public class Test01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
servletContext.getRequestDispatcher("/Get").forward(req,resp);
}
}
<servlet>
<servlet-name>Test01</servlet-name>
<servlet-class>Test01.Test01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Test01</servlet-name>
<url-pattern>/Test01</url-pattern>
</servlet-mapping>

4. 读取系统资源

Porperties

  • 在java目录下新建properties

  • 在resources目录下新建properties

发现:文件都被打包到了同一个路径下: classes,我们俗称这个路径为classpath; 思路:需要一个文件流;

<servlet>
<servlet-name>properties</servlet-name>
<servlet-class>Test01.propertiesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>properties</servlet-name>
<url-pattern>/porperties</url-pattern>
</servlet-mapping>
package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class propertiesServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String user = properties.getProperty("username");
String pwd = properties.getProperty("password");
resp.getWriter().print("user:"+user+" pwd:"+pwd);
}
}

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 sendError(int var1, String var2) throws IOException;

void sendError(int var1) throws IOException;

void sendRedirect(String var1) throws IOException;

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);

void setStatus(int var1);

响应的状态码

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2. 常见应用

1.向浏览器输出信息

ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

3.下载文件

  1. 要获取下载文件的路径

  2. 下载的文件名是啥?

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

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

  5. 创建缓冲区

  6. 获取OutputStream对象

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

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

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.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 {
//1. 要获取下载文件的路径
String realPath = "F:\\java\\JavaWeb-Servlet\\Servlet02\\src\\main\\rescources\\1.png";
//2. 下载的文件名是啥?
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
//3. 设置想办法让浏览器能够支持下载我们需要的东西
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缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
while ((len=in.read(buffer))!=-1){
out.write(buffer);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>Test01.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/file</url-pattern>
</servlet-mapping>

4. Responses验证码实现

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import javax.imageio.ImageIO;
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秒自动刷新
resp.setHeader("refresh","3");

//在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();//graphics图形,相当于画笔
//设置图片的背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0,0,80,20);//背景颜色覆盖范围
//给图片写数据
graphics.setColor(Color.BLUE);//设置颜色
graphics.setFont(new Font(null,Font.BOLD,20));//字体格式
graphics.drawString(makeNum(),0,20);//开始draw

//告诉浏览器,这个请求用图片方式打开
resp.setContentType("image/jpeg");
//网站有缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cacha");
//把图片写给浏览器
ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());
}
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
stringBuffer.append("0");
}
return stringBuffer.toString()+num;
}

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

}
<servlet>
<servlet-name>image</servlet-name>
<servlet-class>Test01.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>image</servlet-name>
<url-pattern>/image</url-pattern>
</servlet-mapping>

5. 实现重定向

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

常见场景:

  • 用户登录

6. 账号密码提交

<html>
<body>
<h2>Hello World!</h2>
<%--${pageContext.request.contextPath} 代表当前项目路径--%>
<form action="${pageContext.request.contextPath}/login" methom="get">
user:<input type="text" name="username"> <br>
password:<input type="password" name="password"> <br>
<input type="submit">
</form>
</body>
</html>
<servlet>
<servlet-name>requstTest</servlet-name>
<servlet-class>Test01.requestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>requstTest</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class requestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("success.html");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>

6.7 HttpServletResquest

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

1. 获取前台传递的传递的参数, 请求转发

porm.xml需要导入jakarta.servlet.jsp:


<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>

java:

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println("爱好:");
System.out.println("Arrays.toString(hobbies):"+Arrays.toString(hobbies));
System.out.println("hobbies:"+hobbies);
System.out.println("long:"+hobbies.length);
System.out.println("hobbies[0]:"+hobbies[0]);
for (String hobby : hobbies) {
System.out.println(hobby);
}
//通过请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}

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

web.xml

<servlet>
<servlet-name>login</servlet-name>
<servlet-class>Test01.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>

index.jsp

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/3 0003
Time: 19:59
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<div>
<form action="${pageContext.request.contextPath}/login" method="post">
账号:<input type="text" name="username"> <br>
密码:<input type="password" name="password"><br>
爱好:
<input type="checkbox" name="hobby" value="写代码"> 写代码
<input type="checkbox" name="hobby" value="跑步"> 跑步
<input type="checkbox" name="hobby" value="电子产品"> 电子产品
<br>
<input type="submit">
</form>
</div>
</body>
</html>

success.jsp

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/3 0003
Time: 20:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success</title>
</head>
<body>
<h1>success</h1>
</body>
</html>

面试题:请你聊一聊重定向个转发的区别

  • 相同点:

    • 页面都会实现跳转

  • 不同点:

    • 请求转发时候, url不会发生变化; 307

    • 重定向的时候, url会发生变化; 302

7.Cookie, Session

7.1 会话

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

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

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

客户端 服务端

  1. 服务端给客户端一个信件, 客户端下次访问服务端带上信件就可以了; cookie

  2. 服务器登记你来过了,下次你来的时候我来匹配你; session

7.2. 保存会话的两种技术

cookie

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

session

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

常见常见:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!

7.3 Cookie

  1. 从请求中拿到cookie信息

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

Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName();//获得cookie的key
cookie.getValue();//获取cookie的vaule
new Cookie("lastLoginTime", 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浏览器上限

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置成utf-8,防止中文乱码
resp.setContentType("text/html");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");

PrintWriter out = resp.getWriter();

//Cookie从客户端获取
Cookie[] cookies = req.getCookies();//获得cookie

//判断Cookie是否存在
if(cookies!=null){
out.write("你上一次的访问时间是");
for (Cookie cookie : cookies) {
if(cookie.getName().equals("lastLoginTime")){
long l = Long.parseLong(cookie.getValue());//获取时间
Date date = new Date(l);//转化成Data格式
String s = date.toString();//转化成字符串
out.write(s);
}

}
}else {
out.write("你是第一次访问网站");
}

//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");

//cookie设置时间,期限为一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
    <servlet>
<servlet-name>cookie01</servlet-name>
<servlet-class>Test01.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cookie01</servlet-name>
<url-pattern>/cookie01</url-pattern>
</servlet-mapping>

 

删除Cookie;

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

  • 设置有效期时间为0;

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

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

//建立一个cookie,名字必须换个要删除的一致
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");

//设置有效期时间为0
cookie.setMaxAge(0);

resp.addCookie(cookie);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>cookie02</servlet-name>
<servlet-class>Test01.CookieDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cookie02</servlet-name>
<url-pattern>/cookie02</url-pattern>
</servlet-mapping>

解决乱码问题:

//编码
Cookie cookie = new Cookie("name", URLEncoder.encode("韩冰","utf-8"));

//解码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));

7.4 Session(重点)

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个Seesion对象;

  • 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;

  • 用户登录之后,整个网站它都可以访问啊! –>保存用户的信息;保存购物车的信息.……

设置和取出Session中的值

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import pojo.Persion;

import java.io.IOException;
import java.io.PrintWriter;

public class SessionDemo01 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 Persion("韩冰",20));

String sessionID = session.getId();

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

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

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import pojo.Persion;

import java.io.IOException;
import java.io.PrintWriter;

public class SessionDemo02 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();

Persion name = (Persion)session.getAttribute("name");
System.out.println(name.toString());

}

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

public class Persion {
private String name;
private int 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;
}

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

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

 

<servlet-mapping>
<servlet-name>session01</servlet-name>
<url-pattern>/session01</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>session02</servlet-name>
<servlet-class>Test01.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>session02</servlet-name>
<url-pattern>/session02</url-pattern>
</servlet-mapping>

清除Session

package Test01;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.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.invalidate();//注销
}

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

设置Session的默认失效时间:

 

    <!--设置Session的默认失效时间-->
<session-config>
<!--15分钟后Session自动失效-->
<session-timeout>15</session-timeout>
</session-config>

 

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)

  • Session把用户的数据写到用户独占Session中,服务器端保存﹐(保存重要的信息,减少服务器资源的浪费)

  • Session对象由服务创建;

使用场景:

  • 保存一个登录用户的信息;

  • 购物车信息;

  • 在整个网站中经常会使用的数据,我们将它保存在Session中;

使用Session:

得到Session

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

Persion name = (Persion)session.getAttribute("name");
System.out.println(name.toString());

清除Session:

HttpSession session = req.getSession();
session.removeAttribute("name");//取消
session.invalidate();//注销

设置Session失效时间:

<session-config>
<!--15分钟后Session自动失效-->
<session-timeout>15</session-timeout>
</session-config>

8. JSP

8.0 Maven依赖

<!--Servlet 依赖-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>

<!--JSP依赖-->
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
</dependency>

<!--JSTL表达式的依赖-->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>2.0.0</version>
</dependency>

<!--standard标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

8.1. 什么是JSP

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

最大的特点:

  • 写JSP就像在写HTML

  • 区别:

    • HTML只给用户提供静态的数据

    • JSP页面中可以嵌入JAVA代码,为用户提供动态数据;

8.2 JSP原理

思路:jsp到底是怎么执行的!

  • 代码层面没有任何问题

  • 服务器内部工作

    Tomcat中有一个work目录

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

    页面会有转变成java程序

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

    JSP最终会转换成java类!

    JSP本身就是一个Servlet

    1.判断请求

    2,内置一些对象

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

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

 

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

如果是HTML代码,就会被转换为:out.write(“<html>\r\n”);

这样的格式, 输出到前端!

8.3 JSP基本语法

任何语言都有自己的语法,JAVA中有。JSP作为java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可!) , lava所有语法都支持!

 

JSP表达式

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>

--%>
<%=
new java.util.Date()
%>

</body>
</html>

JSP脚本片段<%—–%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式%>

--%>
<%=
new java.util.Date()
%>
<hr>

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

<%
for (int i = 0; i < 100; i++) {


%>
<h1>韩冰 <%=i%> </h1>
<%
}
%>

</body>
</html>

JSP声明(<%!——%>)

<%!
static {
fun();
System.out.println("Loading Servlet!");
}
private int globalvar=0;
public static void fun(){
System.out.println("进入了fun方法");
}

%>

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

在jsp中嵌入java代码即可

<%%>
<%=%>
<%!%>
<%--注释--%>

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

 

EL表达式:${i}(:${i}等价于<%=i%>)

8.4 JSP指令

<%@page ......%>

网页的头尾

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/6 0006
Time: 19:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%@include file="common/header.jsp"%>
<h1>网页主题</h1>
<%@include file="common/footer.jsp"%>

<%--jsp标签--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主题</h1>
<jsp:include page="common/footer.jsp"/>
</body>
</html>

jsp标签

<%@include file="common/header.jsp"%>
<h1>网页主题</h1>
<%@include file="common/footer.jsp"%>

<%--jsp标签--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主题</h1>
<jsp:include page="common/footer.jsp"/>

<%@include file=

本质是三合一页面

<jsp:include page=

拼接页面,本质还是三个(本身的参数变量互不影响)

8.5 九大内置对象

  1. PageContext (存东西)

  2. Request (存东西)

  3. Response

  4. Session (存东西)

  5. Application(SerlvetContext)存东西

  6. config (ServletConfig)

  7. out

  8. page 基本不用

  9. exception

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/6 0006
Time: 20:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
pageContext.setAttribute("name1","1"); //保存的数据只在一个页面中有效
request.setAttribute("name2","2"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","3"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","4"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>

<%
String s1 = (String)pageContext.getAttribute("name1");
String s2 = (String)request.getAttribute("name2");
String s3 = (String)session.getAttribute("name3");
String s4 = (String)application.getAttribute("name4");

%>
<%=s1%>
<%=s2%>
<%=s3%>
<%=s4%>

</body>
</html>
  • request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!

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

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

 

在jsp中写转发:

<%
pageContext.forward("/index.jsp");
request.getRequestDispatcher("/index.jsp").forward(request,response);
%>

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

 

EL表达式: ${}

如果遇到el表达式不生效(原样输出问题不被解析)问题,比如${yanggb}被原样输出成字符串,通常的原因是servlet3.0默认关闭了el表达式的解析,因此jsp页面忽视了el标签,要加入不忽略el表达式的page指令才行

<%@ page isELIgnored="false" %>
  1. 获取数据

  2. 执行运算

  3. 获取web开发的常用对象

 

jsp标签:

jsptag01.jsp

<jsp:forward page="jsptag02.jsp">
   <jsp:param name="name" value="hanbing"/>
   <jsp:param name="age" value="21"/>
</jsp:forward>

姓名:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>
<hr>
姓名:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>

jsptag02.jsp

姓名:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>

JSTL表达式

Maven配置(只能这个,其他的对tomcat10都不好使,别踩坑)

<dependencies>

 <dependency>
   <groupId>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.1.2</version>
 </dependency>

 <dependency>
   <groupId>taglibs</groupId>
   <artifactId>standard</artifactId>
   <version>1.1.2</version>
 </dependency>

 <dependency>
   <groupId>org.glassfish.web</groupId>
   <artifactId>jakarta.servlet.jsp.jstl</artifactId>
   <version>2.0.0</version>
 </dependency>

 <dependency>
   <groupId>org.apache.taglibs</groupId>
   <artifactId>taglibs-standard-spec</artifactId>
   <version>1.2.5</version>
 </dependency>


 <dependency>
   <groupId>org.apache.taglibs</groupId>
   <artifactId>taglibs-standard-impl</artifactId>
   <version>1.2.5</version>
 </dependency>
</dependencies>

 

核心标签(掌握部分)

3

<%--引入JSTL核心标签库,我们才能使用JSTL标签--%><%@taglib prefix="c"

uri="http://java.sun.com/jsp/jstl/core"%>

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

JSTL标签库使用步骤

  • 引入对应的taglib

 

 

使用其中的方法

if(c:if)
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ page isELIgnored="false" %>
<%--引入JSTL核心标签库,我们才能使用JSTL标签--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
   <title>Title</title>
</head>
<body>
   <h4>if测试</h4>
<hr>
<form action="JSTL.jsp" method="get">
  <%--
   EL表达式获取表单中的数据
   ${parm.参数名}
   --%>
   <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="${isAdmin}"></c:out>

</body>
</html>

choose(c:choose, c:when)
<%--
 Created by IntelliJ IDEA.
 User: 韩冰
 Date: 2022/3/9 0009
 Time: 21:01
 To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false" %>
<html>
<head>
   <title>Title</title>
</head>
<body>
<%--定义一个变量score--%>
<c:set var="score" value="88"/>
<c:choose>

   <c:when test="${score>90}">优秀</c:when>
   <c:when test="${score<=90 and score>80}">良好</c:when>
   <c:when test="${score<=80 and score>70}">良好</c:when>
   <c:otherwise>不及格</c:otherwise>
</c:choose>
</body>
</html>

for(c:forEach)

<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/9 0009
Time: 21:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
ArrayList<String> pepole = new ArrayList<>();
pepole.add(0,"韩冰1");
pepole.add(1,"韩冰2");
pepole.add(2,"韩冰3");
request.setAttribute("list",pepole);
%>

<c:forEach var="people" items="${list}">
<c:out value="${people}"></c:out>
<br>
</c:forEach>
</body>
</html>

9, JavaBean

实体类

JavaBean有特定的写法

  • 必须有一个午无参构造

  • 属性必须私有化

  • 必须有对象的get/set方法

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

ORM:对象映射关系

  • 表–>类

  • 字段–>属性

  • 航记录–>对象

id name age address
1 韩冰 21 开封
package test01;

public class people {
private int id;
private int age;
private String name;
private String address;

public people(){

}

public people(int id, int age, String name, String address) {
this.id = id;
this.age = age;
this.name = name;
this.address = address;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getAge() {
return age;
}

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

public String getName() {
return name;
}

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

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Override
public String toString() {
return "test0.people{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/9 0009
Time: 21:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:useBean id="people" class="test01.people" scope="page"></jsp:useBean>
<%--等价于people people = new people();--%>

<jsp:setProperty name="people" property="address" value="开封"></jsp:setProperty>
<jsp:setProperty name="people" property="name" value="韩冰"></jsp:setProperty>
<jsp:setProperty name="people" property="age" value="21"></jsp:setProperty>
<jsp:setProperty name="people" property="id" value="1"></jsp:setProperty>
<%--等价于使用构造方法/set方法--%>

姓名:<jsp:getProperty name="people" property="name"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
ID:<jsp:getProperty name="people" property="id"/>


</body>
</html>

10, MVC三层架构

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

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

servlet–CRUD–>数据库

弊端:程序十分臃肿,不利于维护 servlet的代码中:处理请求、响应、视图跳转、处理JDBc、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的! 程序猿调用

JDBC

Mysql oracle sqlserver ……

Model

  • 业务处理 : 业务逻辑(Service)

  • 数据持久层 : CRUD(Dao)

View

  • 展示数据

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

Controller(Servlet)

  • 接收用户的请求: (req:请求参数、Session信息….)

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

  • 控制视图的跳转

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

11. Filter(重点)

1.过滤中的所有代码,在过滤特定请求的时候都会执行

2.必须要让过滤器继续同行

filterChain.doFilter(req,resp); //让我们的请求继续走,如果不写,程序到这里就被拦截停止了

package hanbing.filter;

import jakarta.servlet.*;

import java.io.IOException;

public class filter implements Filter {
@Override
//web服务器启动,就已经初始化了
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter初始化");
}

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");

System.out.println("filter执行前");
filterChain.doFilter(req,resp); //让我们的请求继续走,如果不写,程序到这里就被拦截停止了
System.out.println("filter执行后");
}

@Override
public void destroy() {
System.out.println("filter销毁");
}
}
package hanbing.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class showServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("你好我是韩冰");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
</servlet>
<servlet-mapping>
<servlet-name>show</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>

<filter>
<filter-name>filter</filter-name>
<filter-class>hanbing.filter.filter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

12. 监听器

监听在线人数:

 

助听器:

<listener>
<listener-class>hanbing.listener.onlineCount</listener-class>
</listener>

 

计数类:

package hanbing.listener;

public class ConntUtils {
public static int loginCount;
public static void add(){
loginCount++;
}
public static void subtract(){
loginCount--;
}

public static int getLoginCount() {
return loginCount;
}
}

 

统计类:

package hanbing.listener;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSessionContext;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;

public class onlineCount implements HttpSessionListener {
int a=0;

int b = 0;
//创建session监听: 查看一举一动
//一旦创建Session就会触发这个事件
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println(++a+"+++++");
se.getSession().setMaxInactiveInterval(1);//session有效时间
ConntUtils.add();
}

@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println(++b+"-----");
ConntUtils.subtract();
}
}

 

jsp显示:

<%@page import="hanbing.listener.ConntUtils" %>
<html>
<body>
<h1>

<span><%=ConntUtils.getLoginCount()%></span>

</h1>

</body>
</html>

GUI监听

package hanbing.listener;

import java.awt.*;
import java.awt.event.WindowAdapter;
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,500);
frame.setBackground(new Color(0xA1D28D)); //设置背景颜色

panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0xB44747));

frame.add(panel);
frame.setVisible(true);

frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}

 

 

 

13, 过滤器,监听器常见应用(登录和注销)

Login(java):

package hanbing.servlet;

import hanbing.util.Constant;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

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

//获取前端请求的参数
String username = req.getParameter("username");

if(username.equals("admin")){ //登录成功
req.getSession().setAttribute(Constant.USER_SESSION,req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else { //登录失败
resp.sendRedirect("/error.jsp");
}

}

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

 

Logout(java):

package hanbing.servlet;

import hanbing.util.Constant;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class Logout extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object attribute = req.getSession().getAttribute(Constant.USER_SESSION);
if(attribute != null){
req.getSession().removeAttribute(Constant.USER_SESSION);
resp.sendRedirect("/Log.jsp");
}else{
resp.sendRedirect("/Log.jsp");
}
}

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

sysFilter(java):

package hanbing.filter;

import hanbing.util.Constant;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class sysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp =(HttpServletResponse)servletResponse;

if(req.getSession().getAttribute(Constant.USER_SESSION)==null){
resp.sendRedirect("/error.jsp");
}

filterChain.doFilter(req,resp);
}

@Override
public void destroy() {

}
}

 

 

Constant(java):

package hanbing.util;

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

 

Login.jsp:

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/12 0012
Time: 21:24
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="/servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>

 

success.jsp:

 

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/12 0012
Time: 21:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录成功</h1>
<p>
<a href="/Login.jsp">注销</a>
</p>

</body>
</html>

 

error.jsp:

<%--
Created by IntelliJ IDEA.
User: 韩冰
Date: 2022/3/12 0012
Time: 21:36
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>错误</h1>
<a href="/Login.jsp">返回登录页面</a>
</body>
</html>

 

 

web.xml:

<servlet>
<servlet-name>login</servlet-name>
<servlet-class>hanbing.servlet.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>logout</servlet-name>
<servlet-class>hanbing.servlet.Logout</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logout</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>

<filter>
<filter-name>sysFilter</filter-name>
<filter-class>hanbing.filter.sysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>

14. JDBC

先建表:

CREATE DATABASE jdbc;

USE jdbc;

CREATE TABLE uers(
id int PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday Date
);

 

statement;

import java.sql.*;

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

//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//连接数据库
Connection connection = DriverManager.getConnection(url, username, password);

//创建statement
Statement statement = connection.createStatement();

String sql = "select * from users";
ResultSet re = statement.executeQuery(sql);

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

re.close();
statement.close();
connection.close();
}
}

 

 

preparedStatement,预编译

import java.sql.*;

public class TestJDBC01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//useUnicode=true&characterEncoding=UTF-8 解决中文乱码
String url="jdbc:mysql://47.99.49.255:9000/jdbc?useUnicode=true&characterEncoding=UTF-8" ;
String username="root";
String password = "root";

//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//连接数据库
Connection connection = DriverManager.getConnection(url, username, password);

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

//创建preparedStatement,预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);

preparedStatement.setInt(1,4);
preparedStatement.setString(2,"韩冰");
preparedStatement.setString(3,"123456");
preparedStatement.setString(4,"742608569@qq.com");
preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));

int i = preparedStatement.executeUpdate();

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

preparedStatement.close();
connection.close();
}
}

 

事务

要么都成功,要么都失败

ACID原则: 保证数据的安全

开启事务
事务提交commit()
事务回滚rollback()
关闭事务

转账:
A:1000B :1000

A(900)--100-->B(1100)
package test01;

import org.junit.Test;

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

public class TestJDBC03 {
@Test
public void test(){
String url="jdbc:mysql://47.99.49.255:9000/jdbc?useUnicode=true&characterEncoding=UTF-8" ;
String username="root";
String password = "root";
Connection connection=null;
//加载驱动

try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

//连接数据库
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}

try {
//开启事务
connection.setAutoCommit(false);

String sql1 = "update account set money = money-100 where name='A'";
connection.prepareStatement(sql1).executeUpdate();

//制造错误
int i = 1/0;

String sql2 = "update account set money = money+100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();

connection.commit();//两个事务都执行成功了,提交事务
System.out.println("成功");

} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}



}

}

15Junit单元测试

 

依赖

<dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.11</version>
</dependency>

简单使用

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

 

test:

package test01;
import org.junit.Test;

public class junit {
   @Test
   public void test(){
       System.out.println("666");
  }
}
```xxxxxxxxxx package test01;import org.junit.Test;public class junit {    @Test    public void test(){        System.out.println("666");   }}java
版权声明:本文为hanbing777原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hanbing777/p/16078848.html