Java Web 笔记(杂)

FLowUs邀请链接:https://flowus.cn/login?code=AXNU63
FlowUs邀请码:AXNU63


Java Web 概述

什么是Java Web

在Sun的Java Servlet 规范中,对Java Web 应用做了这样的定义:

"Java Web" 应用由一组Servlet、HTML页、类、以及其它的可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的Servlet容器中运行。

Java Web 应用中可以包含如下内容:

  • Servlet
  • JSP
  • 实用类
  • 静态文档,如HTMl、图片等
  • 描述Web应用的信息(web.xml)

Servlet 本质上就是一个java类。

Servlet与Servlet容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCZTNgVX-1578968812256)(https://ws1.sinaimg.cn/large/0074Poapgy1fz0jkmtv1gj30w10gan1s.jpg)]

Servlet容器的概念
Servlet容器为JavaWeb应用提供运行时环境,它负责管理Servlet和JSP的生命周期,以及管理他们的共享数据。

Servlet容器也称为JavaWeb应用容器,或者Servlet/JSP容器。

目前最流行的Servlet容器软件包括

  • Tomcat
  • Resin
  • J2EE服务器(如weblogic)中也提供了内置的Servlet容器

Tomcat介绍

Tomcat是一个免费的开放源代码的Servlet容器,它是Apache软件基金会的一个顶级项目,由Apache、Sun和其他一些公司及个人共同开发而成。由于有了Sun的参与与支持,最新的Servlet和JSP规范总是能在Tomcat中得到体现。

Tomcat的目录结构

  • bin:主要存放启动和关闭Tomcat的脚本文件
  • conf:存放Tomcat服务器的各种配置文件
  • lib:存放Tomcat服务器和所有web应用程序需要访问的jar文件
  • logs:存放Tomcat的日志文件
  • tmp:存放Tomcat运行时产生的临时文件
  • webapps:当发布web应用时,通常把web应用程序的目录及文件放到这个目录下
  • work:Tomcat将JSP生成的Servlet源文件和字节码文件放到这个目录下

Tomcat的部署

解压Tomcat压缩包到一个非空的目录下(最好是非中文路径下)
配置好JAVA_HOME或者JRE_HOME

启动Tomcat
通过tomcat目录下的bin下的startup脚本启动Tomcat(可以配一个path环境变量)
启动之前要配好JAVA_HOME或者JRE_HOME
在浏览器地址栏中输入http://localhost:8080/
如果出现一只猫的网页,说明启动成功

如果已经启动了一个Tomcat,再启动的话就会因为端口被占用而启动不了
出现:java.net.BindException异常:Already in use:JVM_Bind:8080

修改Tomcat的默认端口号

  • 打开 conf 目录下的 server.xml 文件
  • 修改端口号

找到,并修改port属性的值即可,port的值即端口号

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

Tomcat相关环境变量

通过阅读bin下的startup启动脚本得知,启动服务器的是catalina.bat文件,并且需要配置环境变量

CATALINA_HOME:Tomcat的根目录

catalina方式启动、关闭

catalina常用参数
catalina run:同一命令行窗口下启动服务器
catalina start:开启一个新窗口启动服务器
catalina stop:关闭服务器

Tomcat的管理程序

Tomcat提供了一个管理程序:manager,用于部署到Tomcat服务器中的应用程序

要访问manager web 应用程序,需要添加具有管理员权限的账号,编辑conf目录下的tomcat-users.xml 文件,添加manager角色,设置用户名和密码

文件是这样的

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users version="1.0" xmlns="http://tomcat.apache.org/xml" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd">
<!--
  NOTE:  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary. It 
  is
  strongly recommended that you do NOT use one of the users in the 
  commented out
  section below since they are intended for use with the examples web
  application.
-->
<!--
  NOTE:  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
</tomcat-users>

添加:

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
    <role rolename="manager" />
    <user username="" password="" role="manager" />
</tomcat-users>

Web应用程序的结构

web应用程序的组成

一个web程序是由一组Servlet、HTML页面、类,以及其他资源组成的运行在web服务器上的完整的应用程序,以一种结构化的有层次的目录形式存在

组成web应用程序的这些文件要部署在相应的目录层次中,根目录代表整个web应用程序的根

通常将web应用程序的目录放在webapps目录下,在webapps目录下的每一个子目录都是一个独立的web应用程序,子目录的名字就是web应用程序的名字,也就是web应用程序的“根”。用户通过web应用程序的“根”来访问web应用程序中的资源。

web应用程序的目录层次

目录结构的标准位于:
http://localhost:8080/docs/appdev/deployment.html

  • WebContent
    • WEB-INF
      • classes:放置编译后的class文件
      • lib:放置用到的jar包
      • web.xml:web应用的配置文件
    • html页面、jsp页面等

HTTP协议

  • 什么是协议

双方在交互、通讯的时候,遵守的一种规范、规则

  • HTTP协议

针对网络上的客户端 与 服务器端再执行http请求的时候,遵守的一种规范,其实就是规定了客户端在访问服务器的时候,要带上哪些东西,服务器端返回数据的时候也要带上什么东西。

  • 版本

    HTTP1.0:请求数据,服务器返回后,将会断开连接

    HTTP1.1:请求数据,服务器返回后,连接还会保持。除非服务器|客户端关掉。如果一段时间没有使用这个连接,会自动断开。

客户端如何与服务器端通讯

在地址栏中键入网络地址 回车, 或者是平常注册登录的时候,点击了按钮, 浏览器都能显示出来一些东西,那么背地里到低浏览器和服务器是怎么通讯的。 它们都传输了哪些数据。

  1. 安装抓包工具,如:HttpWatcher(一个IE的插件)

  2. 开启Tomcat, 打开浏览器,输入http://localhost:8080

  3. 在tomcat首页上找到example

  4. 选择Servlet例子 --> Request Parameter

  5. 接着点击 Request Parameter 的 Excute 的链接

  6. 测试提交数据,并用抓包工具观察收发的文件,对照着查看细节

请求数据的内容解释

请求的数据里面包含三个部分内容:请求行、请求头、请求体

  • 请求行:第一行

    • 请求的方式
    • 请求的地址
    • http协议的版本
  • 请求头:中间行

    • Accept:客户端向服务器端表示,我能支持什么类型的数据
    • Referer:真正请求的地址路径,全路径
    • Accept-Language:支持的语言格式
    • User-Agent:用户代理,向服务器表名当前来访的客户端信息
    • Content-Type:提交的数据类型,如form表单的数据
    • Accept-Encoding:gzip,deflate:压缩算法。
    • Host:主机地址
    • Content-Length:数据长度
    • Connection:连接(Keep-Alive 保持连接)
    • Cache-Control:对缓存的操作,no-case
  • 请求体:后面行

浏览器真正发送给服务器的数据
发送的数据呈现的是key=value,如果存在多个数据,那么使用 &

响应数据的内容解释

响应的数据同样包含三部分:响应行、响应头、响应体

  • 响应行:第一行

    • 协议版本:http协议的版本
    • 状态码:这次交互是一个什么样的结果
    • 状态:对应前面的状态码
  • 响应头

    • Server: 服务器是哪一种类型。 Tomcat
    • Content-Type : 服务器返回给客户端你的内容类型
    • Content-Length : 返回的数据长度
    • Date : 通讯的日期,响应的时间

常见的状态码

  • 200:成功,正常处理,得到数据
  • 403:forbidden,拒绝
  • 404:not found,没有找到
  • 500:服务器异常

GET和POST请求方式的区别

  • post

    1. 数据是以流的方式写过去,不会在地址栏上面显示。 现在一般提交数据到服务器使用的都是POST
    2. 以流的方式写数据,所以数据没有大小限制。
  • get

    1. 会在地址栏后面拼接数据,所以有安全隐患。 一般从服务器获取数据,并且客户端也不用提交上面数据的时候,可以使用GET
    2. 能够带的数据有限, 1kb大小
  • 区别:

    1. 请求路径不同。post请求,在url后面不跟生任何的数据,get请求,直接在地址后面跟上数据
    2. 带上的数据不同。post请求会使用流的方式写数据。get请求是在地址栏上跟数据。
    3. 由于post请求使用流的方式写数据,所以一定需要一个Content-Length的头来说明数据的长度有多少。

Web资源

在http协议当中,规定了请求和响应双方,客户端和服务器端。与web相关的资源。

web资源有两种分类:

  • 静态资源:html、js、css、图片、等等文件(不变的)
  • 动态资源:servlet、jsp、...

Servlet

Servlet是什么?

其实就是一个java程序,运行在我们的web服务器上,用于接收和响应 客户端的http请求。

更多的是配合动态资源来做。 当然静态资源也需要使用到servlet,只不过是Tomcat里面已经定义好了一个 DefaultServlet

Hello Servlet

  1. 新建要给web工程
  2. 测试运行web工程
    1. 新建一个类,实现Servlet接口
    2. 配置Servlet,用意:告诉服务器,我们的应用有这么些个Servlet
<!-- 向tomcat报告, 我这个应用里面有这个servlet, 名字叫做HelloServlet ,
 具体的路径是com.itheima.servlet.HelloServlet -->
<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.itheima.servlet.HelloServlet</servlet-class>
</servlet>

<!-- 注册servlet的映射。  servletName : 找到上面注册的具体servlet,
     url-pattern: 在地址栏上的path 一定要以/打头 -->![img05](undefined)
<servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <url-pattern>/a</url-pattern>
</servlet-mapping>

在地址栏上输入 http://localhost:8080/项目名称/a
即可访问这个Servlet

HelloServlet执行流程分析:

Servlet的通用写法

  • Servlet接口
    • GenericServlet
      • HttpServlet(用于处理Http请求)

定义一个类,继承HttpServlet,重写doGet和doPost方法

Servlet配置方式

  • 全路径匹配

以 / 开始 /a /aa/bb
localhost:8080/项目名称/aa/bb

  • 路径匹配 , 前半段匹配

以 / 开始 , 但是以 * 结束 /a/* /*
其实是一个通配符,匹配任意文字
localhost:8080/项目名称/aa/bb

  • 以扩展名匹配

写法: 没有/ 以 * 开始 *.扩展名 *.aa *.bb

Servlet的生命周期

  • 生命周期

从创建到销毁的一段时间

  • 生命周期方法

从创建到销毁,所调用的那些方法。

  • init方法
    在创建该servlet的实例时,就执行该方法。
    一个servlet只会初始化一次, init方法只会执行一次
    默认情况下是 : 初次访问该servlet,才会创建实例。

  • service方法
    只要客户端来了一个请求,那么就执行这个方法了。
    该方法可以被执行很多次。 一次请求,对应一次service方法的调用

  • destroy方法
    servlet销毁的时候,就会执行该方法

    1. 该项目从tomcat的里面移除。
    2. 正常关闭tomcat就会执行 shutdown.bat

doGet 和 doPost不算生命周期方法,所谓的生命周期方法是指,从对象的创建到销毁一定会执行的方法, 但是这两个方法,不一定会执行。

Servlet初始化提前

  1. 默认情况下,只有在初次访问servlet的时候,才会执行init方法。 有的时候,我们可能需要在这个方法里面执行一些初始化工作,甚至是做一些比较耗时的逻辑。

  2. 那么这个时候,初次访问,可能会在init方法中逗留太久的时间。 那么有没有方法可以让这个初始化的时机提前一点。

  3. 在配置的时候, 使用load-on-startup元素来指定, 给定的数字越小,启动的时机就越早。 一般不写负数, 从2开始即可。 (默认为3)

<servlet>
    <servlet-name>HelloServlet04</servlet-name>
    <servlet-class>com.itheima.servlet.HelloServlet04</servlet-class>

    <!-- 让Servlet创建的时机提前 -->
    <load-on-startup>2</load-on-startup>
</servlet>

ServletConfig

ServletConfig是什么

可以获取Servlet的一些配置信息

ServletConfig如何使用

//1. 得到servlet配置对象 专门用于在配置servlet的信息
ServletConfig config = getServletConfig();

//获取到的是配置servlet里面servlet-name 的文本内容
String servletName = config.getServletName();
System.out.println("servletName="+servletName);


//2、。 可以获取具体的某一个参数。 
String address = config.getInitParameter("address");
System.out.println("address="+address);


//3.获取所有的参数名称
Enumeration<String> names = config.getInitParameterNames();
//遍历取出所有的参数名称
while (names.hasMoreElements()) {
    String key = (String) names.nextElement();
    String value = config.getInitParameter(key);
    System.out.println("key==="+key + "   value="+value);
    
}

ServletConfig有哪些方法

为什么需要有这个ServletConfig

  1. 未来我们自己开发的一些应用,使用到了一些技术,或者一些代码,我们不会。 但是有人写出来了。它的代码放置在了自己的servlet类里面。

  2. 刚好这个servlet 里面需要一个数字或者叫做变量值。 但是这个值不能是固定了。 所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声明init-params

在开发当中比较少用。

ServletContext

ServletContext是什么

Servlet 上下文

每个web工程都只有一个ServletContext对象。 说白了也就是不管在哪个servlet里面,获取到的这个类的对象都是同一个。

ServletContext如何获取

//获取对象
ServletContext context = getServletContext();

ServletContext有什么作用

  1. 获取全局配置参数
  2. 获取web工程中的资源
  3. 存取数据,servlet间共享数据 域对象

获取全局配置参数

获取全局参数:

获取web应用中的资源

  1. 获取资源在tomcat里面的绝对路径
/*先得到路径,然后自己new InpuStream*/

context.getRealPath("") //这里得到的是项目在tomcat里面的根目录。

//D:\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\Demo03\

String path = context.getRealPath("file/config.properties");

//D:\tomcat\apache-tomcat-7.0.52\apache-tomcat-7.0.52\wtpwebapps\Demo03\file\config.properties
  1. getResourceAsStream 获取资源 流对象

    直接给相对的路径,然后获取流对象。

通过classloader获取web工程下的资源

使用ServletContext存取数据

定义一个登陆的html页面,定义一个form表单

定义一个Servlet,名为LoginServlet

针对成功或者失败,进行判断,然后跳转到不一样的网页

ServletContext存取值分析

获取成功登陆次数

细节:

	<!-- 	
	A路径: Servlet的路径
		http://localhost:8080/Demo4/login
	
	B路径: 当前这个html的路径:
		http://localhost:8080/Demo4/login.html -->
	
	
	<form action="login" method="get">
		账号:<input type="text" name="username"/><br>
		密码:<input type="text" name="password"/><br>
		<input type="submit" value="登录"/>
	</form>

ServletContext 何时创建, 何时销毁?

服务器启动的时候,会为托管的每一个web应用程序,创建一个ServletContext对象

从服务器移除托管,或者是关闭服务器。

  • ServletContext 的作用范围

只要在这个项目里面,都可以取。 只要同一个项目。 A项目 存, 在B项目取,是取不到的? ServletContext对象不同。

HttpServletRequest

这个对象封装了客户端提交过来的一切数据

可以获取客户端请求头信息

//得到一个枚举集合  
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
    String name = (String) headerNames.nextElement();
    String value = request.getHeader(name);
    System.out.println(name+"="+value);
}

获取客户端提交过来的数据

String name = request.getParameter("name");
String address = request.getParameter("address");
System.out.println("name="+name);
System.out.println("address="+address);

-------------------------------------------------

//name=zhangsan&name=lisi&name=wangwu 一个key可以对应多个值。

Map<String, String[]> map = request.getParameterMap();

Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()) {
    String key = (String) iterator.next();
    System.out.println("key="+key + "--的值总数有:"+map.get(key).length);
    String value = map.get(key)[0];
    String value1 = map.get(key)[1];
    String value2 = map.get(key)[2];
    
    System.out.println(key+" ======= "+ value + "=" + value1 + "="+ value2);
}

获取中文数据

客户端提交数据给服务器端,如果数据中带有中文的话,有可能会出现乱码情况,那么可以参照以下方法解决。

如果是GET方式

String username = request.getParameter("username");
String password = request.getParameter("password");

System.out.println("userName="+username+"==password="+password);

//get请求过来的数据,在url地址栏上就已经经过编码了,所以我们取到的就是乱码,
//tomcat收到了这批数据,getParameter 默认使用ISO-8859-1去解码

//先让文字回到ISO-8859-1对应的字节数组 , 然后再按utf-8组拼字符串
username = new String(username.getBytes("ISO-8859-1") , "UTF-8");
System.out.println("userName="+username+"==password="+password);

直接在tomcat里面做配置,以后get请求过来的数据永远都是用UTF-8编码。
可以在tomcat里面做设置处理 conf/server.xml 加上URIEncoding="utf-8"

<Connector connectionTimeout="20000" 
port="8080" protocol="HTTP/1.1" 
redirectPort="8443" URIEncoding="UTF-8"/>

如果是POST方式

//这个说的是设置请求体里面的文字编码。  get方式,用这行,有用吗? ---> 没用
//这行设置一定要写在getParameter之前。
request.setCharacterEncoding("UTF-8");

HttpServletResponse

负责返回数据给客户端。

输出数据到页面上

//以字符流的方式写数据	
//response.getWriter().write("<h1>hello response...</h1>");

//以字节流的方式写数据 
response.getOutputStream().write("hello response2222...".getBytes());

响应中文乱码问题

通过字符流输出:response.getWriter()

//1. 指定输出到客户端的时候,这些文字使用UTF-8编码
response.setCharacterEncoding("UTF-8");

//2. 直接规定浏览器看这份数据的时候,使用什么编码来看。
response.setHeader("Content-Type", "text/html; charset=UTF-8");

response.getWriter().write("拉拉阿拉啦...");

以字节流输出:response.getOutputStream()

//1. 指定浏览器看这份数据使用的码表
response.setHeader("Content-Type", "text/html;charset=UTF-8");

//2. 指定输出的中文用的码表
response.getOutputStream().write("啦啦啦啦啦啦啦.".getBytes("UTF-8"));

不管是字节流或者字符流,直接使用这一行

response.setContentType("text/html;charset=UTF-8");

资源下载

  1. 直接以超链接的方式下载,不写任何代码。也能够把东西下载下来
让tomcat的默认servlet去提供下载:<br>
<a href="download/aa.jpg">aa.jpg</a><br>
<a href="download/bb.txt">bb.txt</a><br>
<a href="download/cc.rar">cc.rar</a><br>

原因是tomcat里面有一个默认的Servlet -- DefaultServlet 。这个DefaultServlet 专门用于处理放在tomcat服务器上的静态资源。

中文文件下载

针对浏览器类型,对文件名字做编码处理 Firefox (Base64) , IE、Chrome ... 使用的是URLEncoder

/*
    * 如果文件的名字带有中文,那么需要对这个文件名进行编码处理
    * 如果是IE ,或者  Chrome (谷歌浏览器) ,使用URLEncoding 编码
    * 如果是Firefox , 使用Base64编码
    */
//获取来访的客户端类型
String clientType = request.getHeader("User-Agent");

    if(clientType.contains("Firefox")){
        fileName = DownLoadUtil.base64EncodeFileName(fileName);
    }else{
        //IE ,或者  Chrome (谷歌浏览器) ,
        //对中文的名字进行编码处理
        fileName = URLEncoder.encode(fileName,"UTF-8");
}

请求转发与重定向

重定向

/*
之前的写法
response.setStatus(302);
response.setHeader("Location", "login_success.html");*/

//重定向写法: 重新定位方向 参数即跳转的位置
response.sendRedirect("login_success.html");
  1. 地址上显示的是最后的那个资源的路径地址

  2. 请求次数最少有两次, 服务器在第一次请求后,会返回302 以及一个地址, 浏览器在根据这个地址,执行第二次访问。

  3. 可以跳转到任意路径。 不是自己的工程也可以跳。

  4. 效率稍微低一点, 执行两次请求。

  5. 后续的请求,没法使用上一次的request存储的数据,或者 没法使用上一次的request对象,因为这是两次不同的请求。

请求转发

//请求转发的写法: 参数即跳转的位置
request.getRequestDispatcher("login_success.html").forward(request, response);
  1. 地址上显示的是请求servlet的地址。 返回200 ok

  2. 请求次数只有一次, 因为是服务器内部帮客户端执行了后续的工作。

  3. 只能跳转自己项目的资源路径 。

  4. 效率上稍微高一点,因为只执行一次请求。

  5. 可以使用上一次的request对象。

Cookie

Cookie是什么

饼干. 其实是一份小数据, 是服务器给客户端,并且存储在客户端上的一份小数据

应用场景:

  • 自动登陆
  • 浏览记录
  • 购物车
  • 。。。。。。

为什么要有Cookie

http的请求是无状态。 客户端与服务器在通讯的时候,是无状态的,其实就是客户端在第二次来访的时候,服务器根本就不知道这个客户端以前有没有来访问过。 为了更好的用户体验,更好的交互 [自动登录],其实从公司层面讲,就是为了更好的收集用户习惯[大数据]

给客户端添加Cookie

添加Cookie给客户端
在响应的时候,添加cookie

Cookie cookie = new Cookie("aa", "bb");
//给响应,添加一个cookie
response.addCookie(cookie);

客户端收到的信息里面,响应头中多了一个字段 Set-Cookie

获取客户端带过来的Cookie

//获取客户端带过来的cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
    for (Cookie c : cookies) {
        String cookieName = c.getName();
        String cookieValue = c.getValue();
        System.out.println(cookieName + " = "+ cookieValue);
    }
}

Cookie的常用方法

//关闭浏览器后,cookie就没有了。 ---> 针对没有设置cookie的有效期。
//	expiry: 有效 以秒计算。
//正值 : 表示 在这个数字过后,cookie将会失效。
//负值: 关闭浏览器,那么cookie就失效, 默认值是 -1
cookie.setMaxAge(60 * 60 * 24 * 7);

//赋值新的值
//cookie.setValue(newValue);

//用于指定只有请求了指定的域名,才会带上该cookie
cookie.setDomain(".itheima.com");

//只有访问该域名下的cookieDemo的这个路径地址才会带cookie
cookie.setPath("/CookieDemo");

例子:显示最近访问的时间

  1. 判断账号是否正确

  2. 如果正确,则获取cookie。 但是得到的cookie是一个数组, 我们要从数组里面找到我们想要的对象。

  3. 如果找到的对象为空,表明是第一次登录。那么要添加cookie

  4. 如果找到的对象不为空, 表明不是第一次登录。

if("admin".equals(userName) && "123".equals(password)){
    //获取cookie last-name --- >
    Cookie [] cookies = request.getCookies();
    
    //从数组里面找出我们想要的cookie
    Cookie cookie = CookieUtil.findCookie(cookies, "last");
    
    //是第一次登录,没有cookie
    if(cookie == null){
        
        Cookie c = new Cookie("last", System.currentTimeMillis()+"");
        c.setMaxAge(60*60); //一个小时
        response.addCookie(c);
        
        response.getWriter().write("欢迎您, "+userName);
        
    }else{
        //1. 去以前的cookie第二次登录,有cookie
        long lastVisitTime = Long.parseLong(cookie.getValue());
        
        //2. 输出到界面,
        response.getWriter().write("欢迎您, "+userName +",上次来访时间是:"+new Date(lastVisitTime));
        
        
        //3. 重置登录的时间
        cookie.setValue(System.currentTimeMillis()+"");
        response.addCookie(cookie);
    }
}else{
    response.getWriter().write("登陆失败 ");
}

Cookie总结

  1. 服务器给客户端发送过来的一小份数据,并且存放在客户端上。

  2. 获取cookie, 添加cookie

    request.getCookie();

    response.addCookie();

  3. Cookie分类

    会话Cookie
    默认情况下,关闭了浏览器,那么cookie就会消失。

    持久Cookie

     在一定时间内,都有效,并且会保存在客户端上。 
    
     cookie.setMaxAge(0); //设置立即删除
    
     cookie.setMaxAge(100); //100 秒
    
  4. Cookie的安全问题。

由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题 ---> Session .

Session

什么是Session

会话 , Session是基于Cookie的一种会话机制。 Cookie是服务器返回一小份数据给客户端,并且存放在客户端上。 Session是,数据存放在服务器端。

Session常用的API

//得到会话ID
String id = session.getId();

//存值
session.setAttribute(name, value);

//取值
session.getAttribute(name);

//移除值
session.removeAttribute(name);

Session创建or销毁

  • 创建

如果有在servlet里面调用了 request.getSession()

  • 销毁

session 是存放在服务器的内存中的一份数据。 当然可以持久化. Redis . 即使关了浏览器,session也不会销毁。

  1. 关闭服务器
  1. session会话时间过期。 有效期过了,默认有效期: 30分钟。

例子:简单购物车

response.setContentType("text/html;charset=utf-8");

//1. 获取要添加到购物车的商品id
int id = Integer.parseInt(request.getParameter("id")); // 0 - 1- 2 -3 -4 
String [] names = {"Iphone7","小米6","三星Note8","魅族7" , "华为9"};
//取到id对应的商品名称
String name = names[id];

//2. 获取购物车存放东西的session  Map<String , Integer>  iphoen7 3
//把一个map对象存放到session里面去,并且保证只存一次。 
Map<String, Integer> map = (Map<String, Integer>) request.getSession().getAttribute("cart");
//session里面没有存放过任何东西。
if(map == null){
    map = new LinkedHashMap<String , Integer>();
    request.getSession().setAttribute("cart", map);
}


//3. 判断购物车里面有没有该商品
if(map.containsKey(name)){
    //在原来的值基础上  + 1 
    map.put(name, map.get(name) + 1 );
}else{
    //没有购买过该商品,当前数量为1 。
    map.put(name, 1);
}

//4. 输出界面。(跳转)
response.getWriter().write("<a href='product_list.jsp'><h3>继续购物</h3></a><br>");
response.getWriter().write("<a href='cart.jsp'><h3>去购物车结算</h3></a>");

移除Session中的元素

//强制干掉会话,里面存放的任何数据就都没有了。
session.invalidate();

//从session中移除某一个数据
//session.removeAttribute("cart");

JSP

什么是JSP

Java Server Page

什么是jsp

从用户角度看待 ,就是是一个网页 , 从程序员角度看待 , 其实是一个java类, 它继承了servlet,所以可以直接说jsp 就是一个Servlet.

为什么会有jsp?

html 多数情况下用来显示静态内容 , 一成不变的。 但是有时候我们需要在网页上显示一些动态数据, 比如: 查询所有的学生信息, 根据姓名去查询具体某个学生。 这些动作都需要去查询数据库,然后在网页上显示。 html是不支持写java代码 , jsp里面可以写java代码。

特点:

  • 跨平台,一次编写处处运行
  • 组件跨平台性
  • 健壮性和安全性

JSP文件中的三种注释

JSP的三种注释:

  1. 前端语言注释:会被转译,也会被发送,但是不会被浏览器执行
  2. java语言注释:会被转译,但是不会被Servlet执行
  3. JSP注释:不会被转译

page指令

指令写法:<%@ 指令名字 %>

指令选项:

  • language:表明jsp页面中可以写java代码
  • contentType:其实即使说这个文件是什么类型,告诉浏览器我是什么内容类型,以及使用什么编码
    • contentType="text/html; charset=UTF-8"
  • pageEncoding:jsp内容编码
  • extends:用于指定jsp翻译成java文件后,继承的父类是谁,一般不用改。
  • import:导包使用的,一般不用手写。
  • session:用于控制在这个jsp页面里面,能够直接使用session对象。
  • errorPage:指的是错误的页面, 值需要给错误的页面路径
  • isErrorPage:上面的errorPage 用于指定错误的时候跑到哪一个页面去。 那么这个isErroPage , 就是声明某一个页面到底是不是错误的页面。

include指令

指令写法:<%@ include file="other02.jsp"%>

把另外一个页面的所有内容拿过来一起输出。 所有的标签元素都包含进来。

taglib 指令

指令写法:<%@ taglib prefix="" uri=""%>

uri: 标签库路径
prefix : 标签库的别名  

JSP动作标签

JSP内置对象

四个作用域的区别

EL表达式

JSTL

监听器 Listener

过滤器 Filter

MVC设计模式

数据库连接池

AJAX & JQuery

posted @ 2020-01-14 10:31  wbytts  阅读(341)  评论(0编辑  收藏  举报