0%

JavaWeb

1静态web

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

  • 缺点

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

    • 无法和数据库交互(数据无法持久化)

2动态Web

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

2 web服务器

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

2.1 Tomcat

  • 在安装目录下找到conf,在service.xml文件中
    • 可以配置启动的端口号
    • tomcat的默认端口号 8080
    • mysql 3306
    • http 80
    • https 443

3 Http

3.1什么是http

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

  • 文本 :html,字符串…

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

拓展:TCP是什么?
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

说白了TCP就是一种传输协议,就像HTTP协议一样,HTTP的目的是指定了客户端可能发送给服务器什么样的消息以及得到什么样的 响应,而TCP的目的是为了确保数据传输的可靠性,我给你一个数据包,你一定就要收到,收不到的话那么我就会给你重发,直到我 超时放弃你了。

HTTP是建立在TCP之上的,当你建立起TCP连接之后,在上面传输的数据用的是HTTP协议。

3.2 请求行

  • 请求行中的请求方式:GET
  • 请求方式 GET,POST,HEAD,DELETE,PUT,TRACT
    • GET: 请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
    • POST:请求能够携带的参数多,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但是不高效

3.3响应状态

  • 200 请求响应成功

  • 3xx:请求重定向 即重新去浏览器所给的地址

  • 4xx:找不到资源 404

  • 5xx:服务器代码错误 500 网关错误 502

4.Servlet

4.1 servlet简介

Servlet是一种服务器端的Java程序,它的主要作用是接收并处理客户端请求,生成动态Web内容

首先,让我们来理解什么是Servlet。Servlet是用Java语言编写的小程序,它运行在Web服务器上,专门用来处理来自客户端(通常是指浏览器)的请求并做出响应。从技术角度看,Servlet由一个框架支持,这个框架被称为”servlet容器”,它为Servlet提供了所需的运行环境。Servlet能够读取客户端发送的数据,进行处理后,再将结果以HTML、XML或其他格式的内容回送至客户端显示。因此,Servlet非常适合用于创建动态网站和网络应用程序。

其次,我们探讨Servlet的作用。Servlet作为Java Web技术的核心组件之一,其作用至关重要。它通过请求-响应模式,不仅能够生成动态Web页面,还能有效地管理会话、处理表单数据以及访问后台数据库等操作。这种能力使得开发者可以构建出丰富多样的Web应用,如在线商城、社交网络平台以及企业管理系统等。此外,Servlet还定义了不同的上下文作用域,包括request(请求作用域)、session(会话作用域)和servletcontext(应用作用域),这些作用域对于跟踪用户状态和管理应用数据非常关键。

总结来说,Servlet是一个强大的工具,它极大地促进了Java在Web开发领域的发展。通过使用Servlet,开发人员可以实现复杂的业务逻辑,维护会话状态,并与数据库等后端系统交互,从而提供丰富的用户体验和高效的服务。

4.2HelloServlet

1.创建一个maven项目,删除其中的src包,就可以创建多个module,这个空的工程就是maven的主工程

2.配置maven,环境优化

3.编写一个servlet程序

​ 1.编写一个普通类

​ 2.实现servlet接口,可以直接继承servlet类

4.编写servlet的映射

​ 为什么需要映射,我们写的java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在

​ web服务器中注册我们的servlet,还需要给他一个浏览器能够访问的路径

5.配置tomcat

6.启动测试

4.3Mapping问题

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

2.一个servlet可以指定多个映射路径(即不同的url访问的都是同一个页面)

3.一个servlet可以指定通用映射路径 使用通配符*

4.可以指定一些前缀或者后缀等等

5.优先级问题 指定了固有的映射路径优先级最高,如果找不到就会走默认路径

4.4部署问题

在部署的时如果有多个则会增长打包的时间,如果找不到所需要打包的组件,就刷新maven

4.5 ServletContext

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

  • 共享数据
    • 我在这个servlet存储的东西可以在别的servlet中寻找

4.6 获取初始化数据

配置一些web应用初始化参数

1
2
3
4
<context-param>
<param-name>url</param-name>
<param-value>jdbc::mysql://localhost:3306/mybatis</param-value>
</context-param>
1
2
3
4
5
6
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().print(url);
}

4.7 请求转发

1
2
3
4
5
6
7
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
System.out.println("进入了方法demon4");
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/getparam");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forward实现请求转发
}

/getparam覆盖了当前的路径

4.8 读取资源文件

Properties

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

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

1
2
3
4
5
6
7
8
9
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("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);
}

思路:需要一个文件流

4.9 Response与Request

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

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

HttpServletResponse

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

1
2
3
ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

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

1
2
3
4
5
6
7
void setCharacterEncoding(String var1);

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

常见应用

  1. 向浏览器输出信息

  2. 下载文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.获取文件下载的路径
    String realPath ="D:\\java实验\\javaweb-01-servlet\\response\\src\\main\\resources\\1.png";
    //2.获取下载文件的名字
    String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
    //3.设置想办法让浏览器能够支持(Content-Disposition)下载我们所需要的东西
    resp.setHeader("Content-Disposition","attachment;filename"+filename);
    //4.获取下载文件的输入流
    FileInputStream in = new FileInputStream(realPath);
    //5.创建缓冲区
    int len=0;
    byte[] buffer=new byte[1024];
    //6.获取OutputStream对象
    ServletOutputStream outputStream = resp.getOutputStream();
    //7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
    while ((len=in.read(buffer))>0){
    outputStream.write(buffer,0,len);
    }
    in.close();
    outputStream.close();
    }

​ 3.验证码功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器3s自动刷新一次
resp.setHeader("refresh","300");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics();
//设置图片的背景色
g.setBackground(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/png");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num=random.nextInt(9999999)+"";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
num=sb.toString()+num;
return num;
}

4.实现重定向

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

常见场景:

  • 用户登录
1
2
3
4
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/response_war/image");
}

实现重定向,会跳转到resp.sendRedirect里面所指向的地址

面试题

重定向与转发之间的区别

相同点

  • 页面都会发生跳转

不同点

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

HttpServletRequest

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

  1. 获得前端传递的参数 请求转发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setCharacterEncoding("utf-8");
    req.setCharacterEncoding("utf-8");
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    System.out.println("----------------");
    System.out.println(username);
    System.out.println(password);
    String[] hobbies = req.getParameterValues("hobby");
    for (String hobby : hobbies) {
    System.out.print(hobby+" ");
    }
    System.out.println("----------------");
    resp.sendRedirect("/req/success.jsp");
    }

5.Cookie与Session

5.1会话

会话:用户打开浏览器,点击了很多链接,访问多个web资源,关闭浏览器,这个过程就叫做会话

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

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

你 西开

​ 1.发票 西开给你发票

​ 2.学校登记 西开标记你来过了

一个网站怎么证明你来过

客户端 服务端

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

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

5.2 保存会话的两种技术

cookie:是服务器保存在浏览器端的一小段文本信息,通常以key/value形式进行存储

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

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息? 我们可以把信息或者数据放在session中
  1. 从请求中获取cookie信息
  2. 服务器响应给客户端cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码问题
/* req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");*/
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("GBK");

PrintWriter out = resp.getWriter();
//Cookie是服务器从客户端获取的
Cookie[] cookies = req.getCookies();//返回数组,说明可能有多个cookie
//判断Cookie是否存在
if(cookies!=null){
for (Cookie cookie : cookies) {
//获取cookie的名字
if(cookie.getName().equals("lastLogintime")){
//获取cookie的值
long lastlogintime = Long.parseLong(cookie.getValue());
Date date = new Date(lastlogintime);
out.write("你上一次访问该界面在"+date.toLocaleString());
}
}
}else {
out.write("这是你第一次访问该页面");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLogintime",System.currentTimeMillis()+"");
//设定cookie的有效期为一天
cookie.setMaxAge(24*60*60);
//响应给客户端一个cookie
resp.addCookie(cookie);
}

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

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

  • 一个cookie只能保存一个信息
  • 一个web站点(即服务器)可以给浏览器发送多个cookie,最多存放20个cookie
  • 浏览器(即客户端)可以存放300个cookie
  • cookie大小有限制 4kb

删除cookie

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

5.4 Session(重点)

什么是session:Session是服务器为了保存用户状态而创建的一个特殊的对象,用于在多个页面之间共享数据

  • 服务器会给每一个客户端创建一个session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,那么这个Session就存在
  • 用户登录之后,整个网站都可以访问——>保存用户的信息,保存购物车的信息……..
  • Session存放没有限制
  • Session在打开浏览器的瞬间就被创建了

Session与cookie的区别

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

Session使用场景

  • 保存用户的登录信息
  • 保存购物车等信息
  • 在网站中经常使用的数据,我们保存在session中

使用session

创建session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("UTF-8");
req.setCharacterEncoding("UTF-8");
//设置响应的格式
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//给session中存东西
session.setAttribute("name",new Person("王少飞",18));
//获取session的id
String sessionId = session.getId();
//判断Session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功,ID:"+sessionId);
}else {
resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
}
//session创建的时候做了什么事情
// Cookie cookie = new Cookie("JSESSIONID", sessionId);
// resp.addCookie(cookie);

}

得到session

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("UTF-8");
req.setCharacterEncoding("UTF-8");
//设置响应的格式
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//获取session的属性
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}

手动销毁session

1
2
3
4
5
6
7
8
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//得到session
HttpSession session = req.getSession();
//移除属性
session.removeAttribute("name");
session.invalidate();
}

会话自动过期:可以在web.xml配置中设置自动销毁的时间

1
2
3
<session-config>
<session-timeout>1</session-timeout>
</session-config>

6.JSP

6.1 什么是jsp

Java Service Pages:java服务器端页面,跟Servlet一样也是用户开发动态Web的技术

最大的特点:

  • 写jsp就像是在写html

  • jsp与html的区别

    • HTML只给用户提供静态数据(使用js可以动态,但是是伪动态)
    • JSP页面中可以嵌入JAVA代码,为用户提供动态代码

6.2 JSP原理

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

  • 代码层面没有任何问题

  • 服务器内部工作

    tomcat中有一个work目录

    IDEA中使用tomcat的时候会在IDEA的tomcat中产生一个work目录

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

jsp最终会被转换成一个java类

JSP本质上就是一个Servlet

1.判断请求

2.内置一些对象

在JSP页面中:

只要是JAVA代码就会原封不动的输出;

如果是HTML代码,就会转换为

out.write("所输出的内容")

这样的格式,输出到前端

6.3 JSP基础语法

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

JSP表达式

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

JSP脚本片段

1
2
3
4
5
6
7
<%
int sum=0;
for (int i = 1; i <100 ; i++) {
sum+=i;
}
out.print("<h1>Sum="+sum+"<h1>");
%>

JSP脚本片段再实现:可以在代码中嵌入html

1
2
3
4
5
6
7
8
  <%
for (int i = 0; i <5 ; i++) {

%>
<h1> hello world</h1>
<%
}
%>

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

1
2
3
4
5
6
7
8
9
<%! 
static {
System.out.println("loding servlet");
}
private int age=18;
public void write(){
System.out.println("进入了write方法");
}
%>

JSP的注释不会显示在客户端,html的注释不会显示在客户端(在检查源代码的时候)

6.4 9大内置对象

  • Pagecontext 存东西
  • Request
  • Response 存东西
  • Session 存东西
  • Application (ServletContext) 存东西
  • config ( ServletConfig)
  • out
  • page(不用了解)
  • exception

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

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

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

6.5 JSP标签 JSTL标签 EL表达式

使用前需要导入两个包

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

EL表达式: ${ }

  • 获取数据

  • 执行运算

  • 获取web开发的常用对象

JSTL表达式

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

核心标签 (掌握部分)

格式化标签

SQL标签

XML标签

https://www.freeimg.cn/i/2024/04/05/6610194fc12b6.png

JSTL标签库的使用步骤

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

7.JavaBean

实体类

javabean的特点

  • 必须要有无参构造
  • 属性必须私有化
  • 必须提供对应的get,set方法

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

ORM :对象关系映射

  • 表———>类
  • 字段——>属性
  • 行记录—>对象

8.MVC三层架构

什么是mvc: model view controller 模型视图控制器

8.1 早期开发

https://www.freeimg.cn/i/2024/04/06/6610bb70b8919.jpg

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

1
2
3
4
5
servlet---crud---数据库
弊端:程序十分臃肿,不利于维护
servlet代码中:处理请求,响应,视图跳转,处理JDBC,处理业务代码,处理逻辑代码

架构:没有什么是加一层解决不了的

8.2三层架构

以查找对象为例使用三层架构

https://www.freeimg.cn/i/2024/04/06/6610c3724438e.jpg

Model

  • 业务处理:业务逻辑(service)
  • 数据持久层:Dao层 (data access object 数据访问对象)

View

  • 展示数据
  • 提供链接发起的请求

Controller(servlet)

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

以登录网页为例子

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

9.Filter

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

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

https://www.freeimg.cn/i/2024/04/09/6614c0e8122b2.jpg

Filter开发步骤:

  1. 导包 javax.servlet下的Filter包

  2. 编写过滤器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class CharacterEncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("characterEncoding已经初始化");
    }
    // chain 链
    /*
    1.过滤器中的所有代码,在执行过滤的过程中都会被执行
    2.必须要让过滤器继续执行
    * */
    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-16");

    System.out.println("characterEncoding执行前");
    filterChain.doFilter(servletRequest,servletResponse);//让请求继续走,如果没有这段话,程序到这里就会停止
    System.out.println("characterEncoding执行后");
    }
    public void destroy() {
    System.out.println("characterEncoding已经销毁");
    }
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <filter>
    <filter-name>filter</filter-name>
    <filter-class>com.test01.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>