JavaWeb

JavaWeb

视频地址:https://www.bilibili.com/video/BV12J411M7Sj

一、基本概念

1.1 前言

web

  • web,即网页
  • 静态web
  • html、css
  • 提供给所有人看的数据始终不会变
  • 动态web
    • 淘宝等几乎所有的网站
    • 提供给所有人看的数据会变,每个人不同时间地点看到的信息各不相同
    • 技术栈:Servlet/Jsp、ASP、PHP

1.2 web应用程序

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

  • a.html等多个web资源,这些web资源可以被外界访问,对外界提供服务
  • 能访问到的任何页面和资源,都存在于这个世界上的某个角落的计算机上
  • URL:统一资源定位器
  • 这些统一的web资源会被放在同一个文件夹下---->Tomcat,服务器
  • 一个web应用由多个部分组成(静态web,动态web)
  • html,css,js
  • jsp,servlet
  • java程序
  • jar包
  • 配置文件(Properties,xml)
    web应用程序编写完成后,想要被外界访问:需要一个服务器统一管理;

1.3 静态web

  • **.htm、*.html这些都是后缀,如果网络上存在这些东西我们就可以访问
    JavaWeb
  • 缺点:
    • web页面无法动态更新,所有用户看到的页面都一样
      • 轮播图、点击特效、伪动态
      • Javascript
      • VBScript
    • 它无法和数据库交互(数据无法持久化,用户无法交互)

1.4 动态web

页面展示因人而异
JavaWeb

  • 缺点:

    • 假如web资源出现了错误,我们需要重新编写后台程序,重新发布
  • 优点:

  • web页面可以动态更新,所有用户看到的页面都不一样
  • 它可以和数据库交互(数据持久化)
    JavaWeb

二、web服务器

2.1 技术讲解

ASP:微软,国内最早流行,IIS
PHP:开发速度快,功能强大,跨平台,无法承载 大访问量
JSP/Servlet:B/S架构,基于java,可承载高并发

2.2 web服务器

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

IIS:windows自带的
Tomcat

下载Tomcat:

  • 安装 or 解压
  • 了解配置文件即目录结构
  • 作用

三、Tomcat

3.1 安装Tomcat

  1. 官网下载
  2. 解压

3.2 Tomcat启动和配置

文件夹信息
JavaWeb
启动、关闭
启动 ---- 双击bin目录下startup.bat文件
关闭 ---- 双击bin目录下shutdown.bat文件
访问:http://localhost:8080/

可能遇到的问题:

  1. java环境变量没有配置,可能闪退
  2. 闪退问题:需要配置兼容性
  3. 乱码问题:配置文件中设置

3.3 配置

JavaWeb
配置主机端口号:

<Connector port="8080" redirectPort="8443" connectionTimeout="20000" protocol="HTTP/1.1"/>

配置主机名称、网站应用存放位置:

<Host name="localhost" autoDeploy="true" unpackWARs="true" appBase="webapps">

面试题:
网站是如和进行访问的???
1、输入域名,回车
2、检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名的映射
3、有,直接返回对应的IP地址;没有,去DNS服务器找

3.4 发布第一个web网站

不会就先模仿—>

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

网站结构:
JavaWeb

四、HTTP

4.1 什么是HTTP

HTTP(超文本传输协议)是一个简单拿到请求-响应协议,他运行再TCP之上。

  • 文本:html、字符串…
  • 超文本:音频、视频、图片、定位、地图 …

4.2 两个时代

http1.0时代

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

http2.0时代

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

4.3 http请求

客户端----请求(request)----服务器

Request URL: https://www.baidu.com/    ## 请求信息
Request Method: GET    ## 请求方式get/post
Status Code: 200 OK    ## 状态码
Remote Address: 220.181.38.150:443    ## 远程地址

request headers:

Accept: text/htm
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive

1、 请求行

请求行中的请求方式:GET
请求方式:get、post、head、delete、put、tract

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

2、 消息头

Accept: 告诉浏览器,它所支持的类型
Accept-Encoding: 支持哪种编码格式
Accept-Language: 告诉浏览器,它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接

4.4 http响应

服务器----响应(response)----客户端

Cache-Control: private    ## 缓存控制
Connection: keep-alive    ## 连接:保持
Content-Encoding: gzip    ## 编码
Content-Type: text/html;charset=utf-8    ## 类型

1、 响应体

Accept: 告诉浏览器,它所支持的类型
Accept-Encoding: 支持哪种编码格式
Accept-Language: 告诉浏览器,它的语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
Reflush:告诉客户端多久刷新
Location:让网页重新定位

2、 响应状态码
200:请求响应成功
3xx:请求重定向
404:找不到资源
5xx:服务器代码错误

问题:输入网址按下回车发生了什么??
https://www.jianshu.com/p/db17b4412eb8
https://www.cnblogs.com/beiyang/p/10293642.html

五、Maven

5.1 Maven项目架构管理工具

目前引入Maven是为了导入和配置jar包
Maven的核心思想:约定大于配置

5.2 下载安装Maven

下载完成后解压即可

5.3 配置环境变量

配置如下:

  • M2_HOME maven目录下的bin目录地址(暂时用不到,以后会用到)
  • MAVEN_HOME maven目录地址
  • 在系统Path中配置 %MAVEN_HOME%\bin

5.4 阿里云镜像

加速下载

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

5.5 本地仓库

<localRepository>D:\soft\apache-maven-3.8.2\maven-repo</localRepository>

5.6 IDEA中使用Maven创建web项目

1、打开IDEA

2、创建MavenWeb项目
JavaWeb

JavaWeb
3、等待项目初始化完毕

JavaWeb
4、观察maven-repo文件
5、IDEA中Maven设置
IDEA中项目创建成功后,看一眼Maven的配置
JavaWeb
6、到这里Maven在IDEA中的配置和使用就OK了

5.7 不使用模板创建Maven项目

不勾选模板,一路next 没有让选择仓库配置,开始有坑
JavaWeb

5.8 标记文件夹

tips: 标记文件夹功能
JavaWeb
JavaWeb
JavaWeb

5.9 IDEA中配置Tomcat

进入项目后首先在Templates中配置Tomcat模板,之后点击加号配置当前项目的Tomcat

JavaWeb
配置当前项目Tomcat界面
JavaWeb
处理界面中warning
为什么会有问题??我们访问网站需要指定一个文件夹名字
JavaWeb
JavaWeb

5.10 Maven中的pom.xml文件

pom.xml是Maven的核心配置文件

<?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信息 packaging是打包方式,war是javaweb的打包方式-->
  <groupId>com.li</groupId>
  <artifactId>javaweb-01-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>javaweb-01-maven Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!-- 配置 -->
  <properties>
    <!-- 项目默认构建编码 -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 编码版本 -->
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!-- 依赖 -->
  <dependencies>
    <!-- 具体依赖的jar包 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- 项目构建用的东西 -->
  <build>
    <!-- 略-->
  </build>
</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>

5.11 IDEA中的操作

Maven中jar包的结构树

5.12 解决一些问题

IDEA中maven项目每次都要重新配置
解决:IDEA中的全局默认配置中去配置
JavaWeb
Maven中默认web项目中的web.xml版本问题
改为tomcat中自带的web.xml配置文件,和tomcat中保持一致
JavaWeb

六、Servlet

6.1 Servlet简介

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

总结:把实现了servlet接口的Java程序叫servlet

6.2 HelloServlet

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

1、 构建一个普通的Maven项目,删掉src目录,以后的学习就在这个项目里面建立Module;这个空的工程就是Maven的主工程
2、 主工程下建立Maven的web项目,关于Maven父子工程的理解:
父项目中会有

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

子项目会有parent,3.6版本后没有
3、 Maven环境优化
修改web.xml为与Tomcat配套的
将Maven结构搭建完整
4、 编写一个Servlet程序
编写普通类
继承HttpServlet

package com.li.servlet;

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

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

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

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

<!-- web.xml是配置我们web应用的核心应用 -->
<!-- 注册Servlet -->
<servlet>
  <servlet-name>helloServlet</servlet-name>
  <servlet-class>com.li.servlet.HelloServlet</servlet-class>
</servlet>

<!--一个Servlet对应一个mapping:映射-->
<servlet-mapping>
  <!--  servlet-name和上面的对应  -->
  <servlet-name>helloServlet</servlet-name>
  <!--  url-pattern 请求路径  -->
  <url-pattern>/lili</url-pattern>
</servlet-mapping>

6、 配置Tomcat
7、 启动测试

6.3 Servlet原理

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

6.4 Mapping问题

1、 一个Servlet指定一个映射路径

<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径  -->
<url-pattern>/lili</url-pattern>

2、 一个Servlet指定多个映射路径

<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径  -->
<url-pattern>/lili</url-pattern>
<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径  -->
<url-pattern>/lili1</url-pattern>
<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径  -->
<url-pattern>/lili2</url-pattern>

3、 一个Servlet指定通用映射路径

<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径  -->
<url-pattern>/lili/*</url-pattern>

4、 默认请求路径(少用,会干掉首页)

<!--默认请求路径-->
<servlet-name>helloServlet</servlet-name>
<!--  访问时会进入helloServlet,不进index.jsp  -->
<url-pattern>/*</url-pattern>

5、 指定后缀

<servlet-name>helloServlet</servlet-name>
<!--  url-pattern 请求路径 /*.do会报错-*前面不能加映射路径 -->
<url-pattern>*.do</url-pattern>

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

6.5 ServletContext

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

应用一、共享数据:在这个servlet中保存的数据可以在另外一个servlet中拿到

//ServletContext中添加数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    System.out.println("hello");
    ServletContext context = this.getServletContext();
    String username = "学习";
    context.setAttribute("username",username);
}
//读取ServletContext中的数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String username = (String)context.getAttribute("username");

    resp.setContentType("text/html;charset=utf-8"); //一条语句设置响应内容和编码格式
    resp.getWriter().println("名字"+username);

}

应用二、获取初始化参数

<!-- 配置一些初始化参数信息demo03中通过this.getInitParameter("url");取 -->
<context-param>
  <param-name>url</param-name>
  <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();

    // 获得初始化的参数信息
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

应用三、请求转发
A(客户端)找B要资源,B没有找C要,C给B,B再给A(URL不会变化)
JavaWeb

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    // 获得请求转发----请求路径是当前路径,显示内容是/gc路径下的内容
    RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gc");//转发的请求路径
    requestDispatcher.forward(req,resp); //调用forward实现请求转发

}

应用四、读取资源文件

Properties类

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

发现:都被打包到同一个路径下:class(java路径下没有导出问题见本文 5.10 中),我们俗称这个路径为classpath

读取properties思路:需要一个文件流

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
    Properties prop = new Properties();
    prop.load(in);
    String name = prop.getProperty("name");
    String pwd = prop.getProperty("password");
    resp.getWriter().print(name + pwd);
}

6.6 HttpServletResponse

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

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

简单分类:

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

ServletOutputStream getOutputStream() throws IOException;//写其他流
PrintWriter getWriter() throws IOException;//写中文,其他情况会造成字符串丢失

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

void setCharacterEncoding(String 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);

3、响应的状态码

int SC_OK = 200;
int SC_MULTIPLE_CHOICES = 300;
int SC_SEE_OTHER = 303;
int SC_BAD_REQUEST = 400;
int SC_NOT_FOUND = 404;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;

常见应用:

1、 向浏览器输出消息(一直在讲)
两种–response.getWriter()、response.getOutputStream()

2、 下载文件
第一步:获取下载文件路径
第二步:下载文件名是什么?
第三步:想办法让浏览器支持下载我们需要的东西
第四步:获取下载文件输入流
第五步:创建缓存区
第六步:获取OutputStream对象
第七步:将FileOutputStream流写入到buffer缓冲区
第八步:使用OutputStream将缓冲区中的数据输出到客户端!

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //第一步:获取下载文件路径
        //String realPath = this.getServletContext().getRealPath("/1.png");
        String realPath = "D:\\softWorkspace\\Idea_workspace\\javaweb-02-servlet\\response\\target\\response\\WEB-INF\\classes\\1.png";
        //第二步:下载文件名是什么?
        String filname = realPath.substring(realPath.lastIndexOf("\\")+1);
        //第三步:想办法让浏览器支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
        resp.setHeader("Content-Disposition","attachment;filname="+ URLEncoder.encode(filname,"UTF-8"));
        //第四步:获取下载文件输入流
        FileInputStream in = new FileInputStream(realPath);
        //第五步:创建缓存区
        int len = 0;
        byte[] buffer = new byte[1024];
        //第六步:获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
        //第七步:将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
        while((len = in.read(buffer))>0){
            out.write(buffer,0,len);
        }

        in.close();
        out.close();
    }

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

3、 验证码功能

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何让浏览器3秒自动刷新一次
        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); //填充范围00到8020
        //给图片写数据
        g.setColor(Color.BLACK);
        g.setFont(new Font(null,Font.ITALIC,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");

        //把图片写给浏览器
        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;
    }

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

4、 实现重定向
JavaWeb
A(客户端)找B要资源,B说在C那边,A去找C(URL会变化)

常见场景:用户登录

void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.sendRedirect("/response_war/image");//重定向
    /*重定向原理
    * resp.setHeader("Location","/response_war/image");
    * resp.setStatus(302);
    * */
}

面试题:请求转发和重定向的区别
相同点:页面都会实现跳转
不同点:请求转发url不会变化,重定向url会变化

6.7 HttpServletRequest

HttpServletRequest 代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest方法,获得客户端的所有信息;
应用: :获取前端传递的参数,请求转发
JavaWeb

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求编码格式
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String[] hobbys = req.getParameterValues("hobbys");
        System.out.println(username+"--"+pwd+"--"+ Arrays.toString(hobbys));

        //通过请求转发---url地址不变
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

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

面试题:请求转发和重定向的区别
相同点:页面都会实现跳转
不同点:请求转发url不会变化(307),重定向url会变化(302)

注意: 请求转发不用加当前项目,重定向和jsp中跳转需要加当前项目

6.8 Cookie和Session

会话: 用户打开一个浏览器,点击了很多web资源,关闭浏览器,这个过程称之为会话
有状态会话: 浏览器访问过客户端之后,再次访问客户端,客户端知道它曾经访问过

保存会话的两种技术:
cookie 客户端技术
session 服务器技术,用这个技术可以保存用户的会话信息,我们可以把信息放在session中

另:可以把信息放进去之后再取的技术:ServletContext、HttpServletRequest、session

常见场景 网站登录后,下次不用登录直接可以进

6.8.1 cookie

从请求中拿到cookie信息,服务器响应给客户端cookie

Cookie[] cookies = req.getCookies();//获得请求中的cookie信息
cookies[i].getName();//得到cookie的名字
cookies[i].getValue();//得到cookie的值
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");//新建cookie
resp.addCookie(cookie);//响应给客户端信息中中cookie
cookie.setMaxAge(24*60*60);//设置cookie有效期

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

一个网站cookie是否存在上限!细节问题

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

删除cookie:

  • 不设有效期,关闭浏览器,自动失效;
  • 设置有效期时间为0,(相当于手动删除)

通信过程中的编码解码

URLEncoder.encode("中文传输过程中乱码问题","utf-8")
URLDecoder.decode(cookies[i].getValue(),"utf-8")

6.8.2 Session(重点)

什么是Session???

服务器会给每一个用户(浏览器)创建一个Session对象
一个session独占一个浏览器,只要浏览器没有关闭,这个session就会存在
用户登录后整个网站的所有界面都可以访问–>保存用户信息…
JavaWeb

另:可以跨servlet取数据的:ServletContext、session

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

Session使用场景: 保存用户的登录信息;购物车信息;整个网站中经常会使用的数据。将其保存在Session中;

七、JSP

7.1 什么是JSP

JSP(Java Server Pages),Java服务器端页面,也和Servlet一样,用于动态web技术

7.2 JSP原理

思路:JSP是怎么执行的!
代码层面,target目录中jsp文件没有任何异常
服务器层面,tomcat中有一个work目录,IDEA中使用Tomcat也会在IDEA中产生work目录,路径为C:\Users\dd\.IntelliJIdea2019.2\system\tomcat\Unnamed_javaweb-02-servlet\work\Catalina\localhost\session_cookie_war\org\apache\jsp可以看到已经变成了.java文件
JavaWeb
浏览器向服务器发送请求,不管访问什么资源,但是在访问Servlet
jsp最终也会转换成一个java类
JSP本质也是Servlet,jsp继承HttpJspBase,它又继承HttpServlet

在JSP页面中:
只要是JAVA代码,会原封不动的输出
如果是HTML代码,会被转换为out.write("");

7.3 JSP基础语法

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

JSP表达式

<%--  -jsp表达式 -<%= 变量或表达式%> -将结果输出到客户端--%>
<%= new java.util.Date()%>

JSP脚本片段

<%
    for (int i = 0; i < 10; i++) {
        System.out.println(i); //向控制台输出
    }
    out.println("//"); //向客户端输出
%>

脚本片段再实现

<%--脚本片段在实现--%>
<%
    int x= 10;
    out.println(x);
%>
<h1>这是html片段</h1>
<%
    int y= 20;
    out.println(y);
%>
<hr>
<%--在代码中嵌入HTML元素--%>
<%
    for (int i = 0; i <5 ; i++) {
%>
<h1>hello</h1>  <%= i %>
<%
    }
%>

JSP声明 会被编译到jsp生成的java类中

<%--JSP声明,生成的java文件中会被声明在jsp之前,作用域更大--%>
<%!
    static {
        System.out.println("---");
    }
    private int goloble=0;
%>

7.4 JSP指令

导包

<%@ page import="java.util.Date" %>

定制错误界面

方法一:jsp界面进行设置
<%@ page errorPage="500.jsp" %>
方法二:web.xml文件进行设置
<error-page>
    <error-code>500</error-code>
    <location>/error/500.jsp</location>
</error-page>

提取公共页面

方法一:jsp界面进行设置
<%@ include file="500.jsp" %>

引入标签库

//引入JSTL核心标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

7.5 9大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • application 【ServletContext】存东西
  • config【ServletConfig】
  • out 【向客户端写】
  • page
  • exception
final javax.servlet.http.HttpServletRequest request
final javax.servlet.http.HttpServletResponse response
------
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
pageContext.setAttribute("name1","生命1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","生命2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","生命3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","生命4号"); //保留的数据只在服务器中有效,从打开服务器到关闭服务器

应用场景:
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的
session:客户端向服务器发送请求,产生的数据,用户看完用户还有用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完了其他用户还可以用,比如:聊天数据

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

<!-- 依赖 -->
<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>

EL表达式:${ }

  • 获取数据,,获取参数要用param.参数名
  • 执行运算
  • 获取web开发常用对象
  • 调用java方法(不用)

JSP标签:

<%--引用jspTag01界面--%>
<jsp:include page="/jspTag02.jsp"></jsp:include>
<%--跳转到jspTag02界面,携带参数, 如http://localhost:8080/jsp_war/jspTag01.jsp?name=lelele&age=100 --%>
<jsp:forward page="jspTag02.jsp">
    <jsp:param name="name" value="lelelele"/>
    <jsp:param name="age" value="100"/>
</jsp:forward>

JSTL(JavaServerPages Standard Tag Library)表达式:

JSTL标签库引入是为了弥补HTML标签的不足;他自定义了许多标签,可以供我们使用,标签功能和Java代码一毛一样
使用前先引入对应的taglib,再使用其中的方法

1、 核心标签
常用 <c:out> 、<c:choose><c:when><c:otherwise>、<c:forEach>
2、 国际化和格式化标签
3、 SQL标签
4、 XML标签

7.7 JavaBean

实体类
JavaBean有特定的写法:
1、必须有一个无参构造
2、属性必须私有化
3、必须有对应的get/set方法
一般用来和数据库字段做映射,ORM

ORM:对象关系映射
表—>类
字段—>属性
行记录—>对象

public class People {

}
<%--新建一个people对象--%>
<jsp:useBean id="people" class="com.li.pojo.People" scope="page" />
<%--给新建的对象中添加属性值--%>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="lili"/>
<jsp:setProperty name="people" property="age" value="100"/>
<jsp:setProperty name="people" property="address" value="哈尔滨"/>
<%--取对象中的属性值--%>
ID:<jsp:getProperty name="people" property="id"/>
姓名:<jsp:getProperty name="people" property="name"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>

八、过滤器(Filter)

Filter:过滤器,用来过滤网站数据
如,处中文乱码问题、登录验证。。。
JavaWeb
步骤:
1、导包

import javax.servlet.Filter;

2、编写过滤器

public class CharacterFilter implements Filter {
    // 初始化,tomcat启动时会执行,随时等待过滤对象
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterFilter初始化。。。");
    }

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

        System.out.println("CharacterFilter执行前。。。");
        filterChain.doFilter(servletRequest,servletResponse); // 让我们的请求继续走,如果不写程序就停到这里了
        System.out.println("CharacterFilter执行后。。。");
    }

    //服务器关闭的时候会销毁
    public void destroy() {
        System.out.println("CharacterFilter销毁。。。");
    }
}

3、web.xml中注册配置过滤器

<filter>
  <filter-name>CharacterFilter</filter-name>
  <filter-class>com.li.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CharacterFilter</filter-name>
  <!-- 过滤器过滤什么样的请求? 所有/servlet下单任何的请求  -->
  <url-pattern>/servlet/*</url-pattern>
</filter-mapping>

过滤器应用:用户登录后才会进入主页,用户注销后就不能进入主页了

九、监听器

实现一个监听接口(有N种)

步骤:
1、编写监听器,实现监听器接口

//统计在线人数:统计session
public class OnlinCountListener implements HttpSessionListener {
    //创建Session监听
    //一旦创建Session就会触发这个事件
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlinCount = (Integer) ctx.getAttribute("OnlinCount");
        if(onlinCount==null){
            onlinCount = new Integer(1);
        }else{
            int cont = onlinCount.intValue();
            onlinCount = new Integer(cont+1);
        }
        ctx.setAttribute("OnlineCount",onlinCount);
    }

    //销毁session监听
    //一旦销毁Session就会触发这个事件
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlinCount = (Integer) ctx.getAttribute("OnlinCount");
        if(onlinCount==null){
            onlinCount = new Integer(1);
        }else{
            int cont = onlinCount.intValue();
            onlinCount = new Integer(cont-1);
        }
        ctx.setAttribute("OnlineCount",onlinCount);
    }
}

2、web.xml文件中注册监听器

<listener>
  <listener-class>com.li.listener.OnlinCountListener</listener-class>
</listener>

3、看情况是否使用


监听应用:GUI中经常使用

十、MVC三层架构

MVC: Module View Control 模型、视图、控制器

10.1 早期的MVC

用户直接访问控制层,控制层就可以操作数据库
此时的Servlet需要处理:请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
JavaWeb

10.2 MVC三层架构

JavaWeb
View: 专门负责和用户打交道
1、展示数据
2、提供链接发起Servlet请求(a,form,img…)
Control: 协调V和M的关系
1、接收用户的请求(req请求参数、session信息…)
2、交给业务层处理对应的代码
3、控制视图的跳转
Model: 专门负责用户所需要的东西
1、业务处理:业务逻辑(Service)
2、数据持久层:CRUD(Dao)

JavaWeb

JSP:只负责显示数据,显示信息;
Servlet:只负责接收jsp的参数,以及视图跳转,将参数传递给Service
Service:负责将各个表的数据融合一下;符合JSP需要的数据
Dao:只负责操作自己表的CRUD操作(SQL)
DB:数据库,只接收SQL语句
POJO:从上到下传递的数据就是POJO(Entity)
测试类:每写完Service代码,都要测试一下;

一个POJO对应一张表
一个Dao对应一张表
一个Service持有多个Dao
一个Servlet持有多个Service

开发的时候从下往上开发;
读别人的代码从上往下读;

上一篇:(37)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Zuul请求响应信息输出


下一篇:Servlet文件下载