JavaWeb自学笔记(一)
学习视频:BV12J411M7Sj
1、基本概念
静态web:①html、css。②提供所有人看的数据始终不会发生变化。
动态web:页面会发生变化。(如:论坛点赞、论坛恢复等)。②Serviet/JSP、ASP、PHP。java程序、jar包、配置文件(property)
在java中,动态web资源开发的技术统称为Javaweb
1.1 web应用程序
web应用程序:可以提供浏览器访问的程序
- html等web资源可以为外界所访问
- 页面的资源一定存储在至少一台计算机上
- 通过URL唯一标识页面
- 统一的web资源会被放在用一个文件夹下,web应用程序–>Tomcat:服务器
web应用程序编写完毕后,若要提供外界访问,则需要一个服务器来管理页面
1.2 静态web
缺点:web页面无法实时更新。无法和数据库交互(无法持久化),用户无法交互。
1.3 动态web
web的页面的展示效果会动态变化。解决了静态web会出现的大部分问题。
缺点:
- 假如服务器的动态web资源出现了错误,就要重写后台程序并重新发布。
2、web服务器
ASP:微软发布。在html中嵌入了vb脚本,ASP+COM。用C#开发
php:开发速度快、功能强大、跨平台、代码简单(70%国内网页用php开发)。但是无法承载大访问量的情况。
JSP/Serviet:
B/S:浏览器和服务器。
C/S:客户端和服务器。
- B/S架构
- 基于java语言
- 可以承载三高问题
- 语法像ASP
2.1 web服务器
目的:处理用户的一些请求和一些相应信息
IIS:微软发布的有ASP
Tomcat:轻量级开源web服务器项目。 主要用于中小型系统和并发访问用户不多的场合。可用于开发和调试JSP。Tomcat实际上运行的是JSP和Serviet。
3、Tomcat
官网:tomcat.apache.org
3.1 安装和启动
去官网下载源码包
启动/关闭tomcat
3.2 配置
可以配置启动的端口号
/conf/server.xml部分内容
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主机的名称
- 默认主机名为:localhost–>127.0.0.1
- 默认网站应用存放的位置为:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
问:网站是如何进行访问的?
答:①输入域名。
②检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射。若有,就返回域名的ip地址。若没有,要通过网络查询DNS服务器。
host文件
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
127.0.0.1 activate.navicat.com
3.3 发布一个web网站
- 将自己写的网站,放到tomcat的/webapps目录下。启动tomcat后,通过localhost:端口/文件名进行访问
一个网页的大致结构
--webapps: tomcat服务器的web目录
--ROOT
--kuangstudy:网站的目录名
-- WEB-INF
-classes:java程序
-lib:web应用程序所依赖的jar包
- index.html 网站首页
- static
-css
-style.css
-js
-img
-......
4、http
定义:超文本传输协议(Hyper Text Transfer Protocol,HTTP)
是一个简单的请求-响应协议,它通常运行在TCP
之上。 它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII
形式给出;而消息内容则具有一个类似MIME
的格式。这个简单模型是早期Web
成功的有功之臣,因为它使开发和部署非常地直截了当。
- 文本:html、字符串等
- 超文本:图片、音频、视频、定位、地图等
- 80端口
https:安全的http
- 端口:443
4.1 两个版本
- http1.0:HTTP/1.0:客户端可以与web服务器连接后,智能获得一个web资源。
- http2.0: HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
4.2 http请求
客户端发送请求(Request)–>服务器
Request URL:HTTPS://www.baidu.com/ 请求地址
Request Method:GET get方法/post方法
Status Code:200 OK 状态码:200
Remote Address:14.215.177.39:443
请求头
GET /index.php?tn=monline_3_dg HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 语言
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BIDUPSID=8022CBA3216D6D96628E6C6F0F82F113; PSTM=1612750909; BD_UPN=13314752; BDUSS=ZTbkJUcVdsaXhVR2pCVUo1Zkh6UExzVXpzdjhTdzdOTi12TnBGcmgxaWR0RlZnSVFBQUFBJCQAAAAAAAAAAAEAAAACp5eVYTk2OTU1NzAyOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ0nLmCdJy5geH; __yjs_duid=1_673e643bebb04bca73844bbf4d4975c01618059107005; MCITY=-%3A; BAIDUID=FFAA59ED6D84908468A6BD1F1488BCB1:FG=1; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=35105_31254_34813_34584_35872_35949_35315_26350_35884_35867_22159; COOKIE_SESSION=600208_0_9_3_25_12_1_0_9_6_2_1_600324_0_119_0_1646804810_0_1646804691%7C9%230_0_1646804691%7C1; RT="z=1&dm=baidu.com&si=4em762b54de&ss=l0kbyh0j&sl=2&tt=3le&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=41v"; BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; BD_HOME=1; delPer=0; BD_CK_SAM=1; PSINO=5; BA_HECTOR=858ga58ka4ak0185fe1h2imkp0r; H_PS_645EC=9406WInbhpf4PPftvoO7q9JR5sHanQ2bhghkLXmoQlz%2FQEZl5LFIGO8i7zUD9QOdrlza; sug=3; sugstore=0; ORIGIN=0; bdime=1
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Cache-Control: max-age=0 缓冲
4.2.1 请求行
- 请求行中的请求方式:GET
- 请求方式:Get、Post、HEAD、DELETE、PUT、TRACT…
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但是高效
- post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
4.2.2 消息头
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
HOST: 主机
4.3 http响应
服务器相应–>客户端
百度服务器相应
HTTP/1.1 200 OK
Bdpagetype: 2
Bdqid: 0xa5cf90100005b48d
Cache-Control: private //缓存控制
Connection: keep-alive //连接
Content-Encoding: gzip //编码
Content-Type: text/html;charset=utf-8 //类型
Date: Thu, 10 Mar 2022 01:55:41 GMT
Expires: Thu, 10 Mar 2022 01:55:41 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
Set-Cookie: BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=340; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=35105_31254_34813_34584_35872_35949_35315_26350_35884_35867_22159; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1646877341038415924211947926734831465613
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
4.3.1相应体
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
HOST: 主机
Reflush: 好俗客户端,多久刷新一次
Location:让网页重定位
4.3.2相应状态码
常见的 HTTP 状态码:
- 200 - 请求成功
- 301 - 资源(网页等)被永久转移到其它URL
- 404 - 请求的资源(网页等)不存在
- 500 - 内部服务器错误
分类 | 分类描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
更多状态码:https://www.runoob.com/http/http-status-codes.html
问:当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示出来,经历了什么?
5、Maven
在javaweb开发中,需要使用大量的jar包,需要手动导入。
Maven可以用于自动导包
5.1 Maven项目架构管理工具
Maven核心思想:约定大于配置。
Maven会规定好如何去编写java代码,而且这个规定必须遵守
5.2 下载和安装
https://maven.apache.org/download.cgi 下载源码后解压即可
5.3配置环境变量
添加如下配置:
- M2_HOME maven的bin目录
- MAVEN_HOME maven的目录
- 在系统的PATH中配置%MAVEN_HOME%\bin
管理员模式运行
5.4 阿里云镜像
mirrors:加速下载
进入maven的conf/settings.xml文件,添加以下代码以配置阿里云镜像
<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 本地仓库
在本地的仓库、远程仓库
建立一个本地仓库
例:在maven目录下创建一个maven-repo
目录,将路径通过localReponsitoty标签写入setting.xml
<localRepository>"路径"</localRepository>
5.6 IDEA中使用Maven
- 启动IDEA,创建一个Maven项目
2.等待项目初始化完毕
4.观察maven仓库中多了什么
5.IDEA中的maven设置
IDEA项目创建成功后,多留意一下maven配置
5.7 Maven创建一个普通项目
一开始不勾选Create from archetype
选择maven-archetype-webapp模板
5.8 标记文件夹
还可以通过File–>Project Structure–>Module修改目录类型
5.9 在IDEA中配置tomcat
注:tomcat10可能会报错,可以用tomcat9进行配置。
5.10 pom文件
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文件-->
<groupId>com.infinite</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 项目jar包-->
<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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 项目构建-->
<build>
<finalName>javaweb-01-maven</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
通过dependency标签自动下载依赖,maven还会自动下载级联的依赖
maven仓库:https://mvnrepository.com/
maven由于约定大于配置,可能会遇到自己写的配置文件无法导出或失效的问题。解决方式为在build标签中配置resources
https://www.cnblogs.com/yuqiliu/p/12059614.html
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
IDEA中可以生成项目中包的依赖关系
5.11 可能遇到的问题
修改maven默认配置:关闭当前项目–>Customize–>Allsettings
servlet官方入门资源
Source Code for HelloWorld Example
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
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>");
}
}
HttpServlet类若项目中不存在,可以利用maven仓库网站(https://mvnrepository.com/)导入
使用servlet类生成网页
项目目录:
helloServlet继承HttpServlet类
package com.infinite.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//相应的类型:html
response.setContentType("text/html");
//设置编码格式
response.setCharacterEncoding("UTF-8");
//获取相应的输出流
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>INFINITE</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>1234564189461xxxx</h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
然后再web.xml中配置servlet映射
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<!-- web.xml用于配置web的核心应用-->
<!-- 注册Servlet-->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.infinite.servlet.helloServlet</servlet-class>
</servlet>
<!-- 一个servlet对应一个mapping映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!-- 映射的请求路径-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
6、Servlet
Servlet时sun公司开发动态web的一门技术
Sun再这些API中提供一个接口叫做:Servlet,若要开发一个Servlet程序,需要两步:
- 编写一个类,实现Servlet接口
- 把开发好的java类部署到web服务器中
实现了Servlet接口的java程序又称Servlet
6.1 HelloServlet
Sun公司对Servlet接口有两个默认的实现类:HttpServlet
Servlet–>GenerateServlet–>HttpServlet–>自己实现的Servlet类
Servlet接口如下
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
-
构建一个maven项目、删除其中的src目录。可以在该项目中创建Moudel。这个空工程就是maven的主工程
-
在maven父项目中添加一个moudle。(如果创建moudle后卡死,可以留意一下maven路径配置)
父项目的pom.xml中会出现
<modules> <module>servlet-01</module> </modules>
子项目的pom.xml中会出现
<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.infinite</groupId> <version>1.0-SNAPSHOT</version> </parent>
父项目中的java子项目可以直接使用
-
maven环境优化:①修改web.xml的内容。可以复制tomcat的webapp目录下的样例。②将maven的结构搭建完整
-
编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口,也可以直接继承HttpServlet(它也实现了这个接口)。
public class HelloServlet extends HttpServlet {
//get和post知识请求实现的不同方式,可以相互调用,业务逻辑相同
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer=resp.getWriter();
writer.print("Hello,xxxxyyyy");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
-
编写Servlet的映射。 我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册自己写的Servlet,并提供一个浏览器可以访问的路径。
<!-- web.xml--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.infinite.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>hello</url-pattern> </servlet-mapping>
-
配置tomcat
-
启动测试
6.2 Servlet运行原理
Servlet有web服务器调用,web服务器在收到浏览器请求之后,会发生如下事件
6.3 Mapping
6.3.1 映射方式
一个Servlet指定一个映射路径
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.infinite.servlet.HelloServlet</servlet-class>
</servlet>
<!-- localhost:8080/s1/hello-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
一个Servlet指定多个映射路径
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.infinite.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<!-- localhost:8080/s1/hello 或hello1、hello2、hello3,访问的都是一个路径-->
默认请求路径
<!--主页会替换成hello相关的映射页面-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
一个Servlet指定通用映射路径
<!--主页会替换成hello相关的映射页面-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.infinite</url-pattern>
</servlet-mapping>
上面的映射表示任意以.infinite
为后缀的路径都会映射到hello上,如主页名/(任意符号).infinite
。*
号为通配符,这里*
号前不能使用路径符号/
。
6.3.2 自定义error页面
优先级
指定了固有的映射路径优先级最高,如果找不到就会走默认的路径请求
自定义error页面的过程和写一个HelloServlet程序相同。只不过为了将非法输入路径映射到自定义error页面,会在web.xml中将自定义error的servlet映射路径写为/*
等通配符形式。这个路径优先级最低。
ErrorServlet
package com.infinite.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 ErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer=resp.getWriter();
writer.println("<h1>!404 nout found!<h1>");
writer.println("<img src='https://cdn.jsdelivr.net/gh/infinite-war/Study_note/diary/2022/bc863bdb9a97e105a820c672998db9ce1609981983032.png'" +
" alt='nullImg'>");
}
@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"
metadata-complete="true">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.infinite.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- 自定义404页面 -->
<servlet>
<servlet-name>notFoundError</servlet-name>
<servlet-class>com.infinite.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>notFoundError</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
实现效果
6.4 ServletContext
web容器再启动的时候,它会为每个web程序都创建一个对于的ServletContext对象,该对象代表了当前的web应用
6.4.1共享数据
HelloServlet
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter(); 初始化参数
//this.getServletConfig(); Servlet配置
//this.getServletContext(); Servlet上下文
ServletContext servletContext=this.getServletContext();
String username="bob";
//将一个数据保存在ServletContext对象中,名字为username,值为bob
servletContext.setAttribute("username",username); //左侧为属性名
}
}
GetServlet
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
String username=(String)servletContext.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("用户名:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.infinite.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.infinite.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
</web-app>
测试
6.4.2 获取初始化参数
web.xml
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
ServletDemo03
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
String url=servletContext.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
6.4.3 请求转发
ServletDemo04
package com.infinite.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
//转发的请求路径
//RequestDispatcher requestDispatcher=servletContext.getRequestDispatcher("/gp");
//调用forward实现转发
//requestDispatcher.forward(req,resp);
servletContext.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
/sd4
向/gp
转发请求,响应结果仍在/sd4
页面中
6.4.4 读取资源文件
在java或resources目录下新建的properties文件,打包后在同一个路径下:targer/classes,该路径又称classpath
properties
username=root
password=asfew4334t
ServletDemo05
package com.infinite.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.InputStream;
import java.util.Properties;
public class ServletDemo05 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 username = properties.getProperty("username");
String pwd = properties.getProperty("password");
resp.getWriter().print("user:"+username+"\n"+"password:"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
测试效果
6.5 HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServietRequest对象,代表响应一个HttpServletResponse
- 如果要获取客户端请求过来的参数:用HttpServletRequest
- 如果要给客户端响应信息:用HttpServletResponse
6.5.1 分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void etHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
//......
状态码常量
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;
//......
6.5.1 常见用法
- 向浏览器输出消息
- 下载文件
- 获取下载文件的路径
- 下载文件的文件名
- 设置想办法让浏览器能够支持需要下载的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输出到客户端
6.5.2 下载文件
目录结构
FileServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.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 = "C:\\Users\\96955\\Desktop\\openSourceItems\\JAVAWEB_TEST\\javaweb-02-servlet\\response\\target\\classes\\11.png";
System.out.println("下载文件的路径:"+realPath);
// 2. 下载文件的文件名
//截取最后一个/符号,通过+1获取11.png这一文件名
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
// 3. 设置想办法让浏览器能够支持(Content-Disposition)需要下载的东西
// URLEncoder用于中文名编码
resp.setHeader("Content-Disposition","attachment;filename"+ URLEncoder.encode(fileName,"UTF-8"));
// 4. 获取下载文件的输入流
FileInputStream fileInputStream = new FileInputStream(realPath);
// 5. 创建缓冲区
int len=0;
byte[] bytes = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream outputStream = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区
while((len=fileInputStream.read(bytes))>0){
outputStream.write(bytes,0,len);
}
fileInputStream.close();
outputStream.close();
// 8. 使用OutputStream将缓冲区中的数据输出到客户端
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
web.xml
<servlet>
<servlet-name>fileDownload</servlet-name>
<servlet-class>com.infinite.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileDownload</servlet-name>
<url-pattern>/downloadPNG</url-pattern>
</servlet-mapping>
测试效果
6.5.3验证码功能
注:了解即可
ImageServlet
package com.infinite.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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);
//得到图片
Graphics g = (Graphics2D) bufferedImage.getGraphics();
//设置背景颜色
g.setColor(Color.CYAN);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.magenta);
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(bufferedImage,"jpg",resp.getOutputStream());
}
//生成随机数方法
private String makeNum(){
Random random=new Random();
String num = random.nextInt(99999999) + "";
StringBuffer stringBuffer = new StringBuffer();
for(int i=0;i<7-num.length();i++){
stringBuffer.append("0");
}
String s=stringBuffer.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.infinite.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/ImageServlet</url-pattern>
</servlet-mapping>
测试效果
6.5.4 重定向功能(重要)
B的一个web资源收到客户端A的请求后,B会通知客户端去访问另外一个web资源C,这个过程叫重定向。
常见场景:
- 用户登录
void sendRedirect(String var1) throws IOException
RedirectServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("location","/response_war/ImageServlet");
// resp.setStatus(302);
resp.sendRedirect("/response_war/ImageServlet"); //项目名要先写上
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.infinite.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/ImageServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RedirectServlet</servlet-name>
<servlet-class>com.infinite.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RedirectServlet</servlet-name>
<url-pattern>/rds</url-pattern>
</servlet-mapping>
测试效果
请求报文
面试:请你聊聊重定向和转发的区别
答:
相同点:
- 页面都会实现跳转
不同点:
- 请求转发的时候,url不会发生变化 307
- 重定向的时候,url地址栏会发生变化 302
用户登录
RequestTest
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.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);
//重定向要注意路径问题,否则会出现404
resp.sendRedirect("/response_war/success.jsp");
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%--提交的类路径,需要寻找项目的路径--%>
<%--${pageContext.request.contextPath}/login 代表当前的项目路径--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>log in successfully!</h1>
</body>
</html>
web.xml
<servlet>
<servlet-name>RequestTest</servlet-name>
<servlet-class>com.infinite.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestTest</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
测试效果
6.6 HttpServletRequest
HttpServletRequest
代表客户端的请求,用户通过Http协议访问服务端,HTTP请求中的所有信息会被封装到HttpServletRequest
中,通过HttpServletRequest
的方法,获得客户端的所有信息。
获取前端传递的参数
String getParameter(String s);
String[] getParameterValues(String s);
下面实现一个前后端用户登录数据传输的DEMO
目录
LoginServlet
package com.infinite.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.util.Arrays;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username=req.getParameter("username");
String password = req.getParameter("password");
String[] foods=req.getParameterValues("foods");
System.out.println("==============================");
System.out.println("username:"+username);
System.out.println("password:"+password);
System.out.println(Arrays.toString(foods));
System.out.println("==============================");
//通过请求转发
//此处的 ’/‘ 代表当前的web应用,不需要添加项目路径
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>登录界面</h1>
<div style="text-align: center">
<%-- 以post的方式提交表单,提交到login请求路径--%>
<form action="${pageContext.request.contextPath}/login" method="post">
用户名:<input type="text" name="username" required><br>
密码: <input type="password" name="password" required><br>
food:
<input type="checkbox" name="foods" value="披萨">披萨
<input type="checkbox" name="foods" value="汉堡">汉堡
<input type="checkbox" name="foods" value="薯条">薯条
<input type="checkbox" name="foods" value="芝士">芝士
<br>
<input type="submit">
</form>
</div>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>log in successfully!!!</h1>
</body>
</html>
web.xml
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.infinite.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
测试效果

7、Cookie、Session
7.1 会话
会话的定义:用户打开一个浏览器–>点击了很多超链接–>访问多个web资源–>关闭浏览器,这个过程称一次会话。
有状态会话: 一个网站如何证明你来过?
客户端 服务端
- 服务端给客户端一个
信件
,客户端下次访问服务端带上这个信件就好了;该信件又称cookie
- 服务器登记你来过了,下次你来的时候我来匹配你;
session
7.2 保存会话的两种技术
cookie:
- 客户端技术(响应,请求)
session
- 服务器技术,用来保存用户的会话信息。可以把消息或者数据放在session中
常见例子:网站第一次登录后,除非刻意清空记录,下次访问就能直接登录
cookie使用例
CookieDemo01
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.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 {
//服务器:告诉你,你当前访问的时间,把这个时间封装成cookie,下次访问以cookie作证
//中文编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=utf-8");
PrintWriter out = resp.getWriter();
//Cookie:服务端从客户端获取
Cookie[] cookies = req.getCookies(); //可能存在多个cookie
//判断cookie是否存在
if(cookies!=null) {
out.write("上次访问的时间是:");
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()+"");
//cookir有效期设置
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>CookieDemo01</servlet-name>
<servlet-class>com.infinite.servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo01</servlet-name>
<url-pattern>/c1</url-pattern>
</servlet-mapping>
测试效果
7.3 Cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //获取Cookie
cookie.getName(); //获取cookie中的key
cookie.getValue(); //获取cookie中的value
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一般为浏览器的上限
删除cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0
编码解码
URLEncoder.encode("张三","utf-8");
URLDecoder.decode(cookie.getValue(),"utf-8");
7.4 Session(重点)
关于Session:
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器未关闭,这个Session就存在
- 用户登录后,整个网站都可以访问。–>保存用户信息,保存购物车信息
session和cookie的区别:
- cookie是把用户的数据写给用户的浏览器,浏览器保存(可保存多个)
- session把用户的数据写到用户独占的session中,由服务端保存(保存重要信息,减少服务器资源的浪费)
- session对象由服务端创建
session使用常见:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,这类数据会保存在session中
7.4.1 session使用例
SessionDemo01
package com.infinite.servlet;
import com.infinite.pugo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("张三",1));
//设置Session的IO
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);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
SessionDemo02
package com.infinite.servlet;
import com.infinite.pugo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo02 extends HttpServlet {
@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();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
SessionDemo03
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
//注销后浏览器又会产生新的session
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
通过web.xml设置session过期时间
<!-- 设置session默认的失效时间-->
<session-config>
<!-- 15分钟后session自动失效-->
<session-timeout>15</session-timeout>
</session-config>