传送门==>B站遇见狂神说—JavaWeb入门到实战
最近开始复习web部分;笔记和练习只是跟着视频整理的;但是有的知识点并没有整理进来(比如一些基础概念,安装步骤)
ml
1.web基本; Tomcat安装使用
web应用程序,就是提供浏览器访问的程序;
html, css,js,jsp,servlet,java程序,jar包,配置文件(properties)
提供给外界访问,需要服务器统一管理.
静态web
.htm,.html…服务器上存在就能访问
静态web,所有用户看到的是同一个页面,无法动态更新;
可添加一些伪动态(javascript,VBstript)轮播图;点击特效;
数据无法持久化
动态web
页面会动态变化;
缺点:
若服务器上的动态web出问题,要重新编写后台程序
asp:在HTML语言中加入VB脚本;维护成本高.
php:开发速度快,功能强大,跨平台,代码简单,无法承载大访问量.
jsp:本质是servlet;基于java语言;可承载(高可用,高并发,高性能)的影响;语法像ASP.
服务器:处理用户请求,为用户响应信息.
Tomcat实际运行jsp,servlet.
官网下载==>http://tomcat.apache.org/
之前已安装,且已配置 ==> 下载安装配置Tomcat
bin
: 存放启动和关闭Tomcat的脚本文件
conf
: 存放Tomcat服务器的各种配置文件
lib
: 存放Tomcat 服务器的资源 jar包
logs
: 存放日志文件
temp
: 存放运行时临时产生的临时文件
webapps
: Web应用所在目录;即提供外界访问的web资源存放目录
work
: Tomcat工作目录
在server.xml文件中可可进行配置文件修改;
此处可修改端口;端口默认8080,
此处可修改主机名称;但是修改 name 后要在系统文件修改主机名映射.
网站是如何进行访问的
1.客户端输入域名后,先查看浏览器缓存;
2.检查本机host文件;是否有域名映射;
若有,就返回对应的IP地址;可直接访问web程序;
若没有,在DNS服务器(全球域名管理)寻找;
web网站发布
将网页放到Tomcat的安装目录webapps文件中.
里面的默认首页的页面路径名为index.html.
2.http详细讲解
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。
HTTP;默认80;
HTTPS:默认443
HTTP1.0 ==>客户端与服务器连接后,只能获得一个web资源,会断开连接.
HTTP2.0 ==>客户端连接后可获得多个web资源.
例如;在百度网页打开F12,选择NetWork
;crtl+R
调出网络进程信息.
HTTP请求;
请求行
请求方式,有get,post,head,delete,put…
- get:请求携带的参数较少,大小有限制,会在浏览器的url地址显示数据,不安全,但是高效
- post与之相反.
消息头
Accept
: 面向浏览器,支持的数据类型.
Accept-Encoding
:向浏览器发送,支持的编码格式,常用的有gbk,utf8,gb2312.
Accept-Language
: 语言环境
Cache-Control
: 缓存控制
Connection
: 请求完成是否断开或者保持连接
Host
: 主机
HTTP响应
服务器=->响应 -=>客户端
响应头,
响应体,类似于消息头
refresh: 响应给客户端,多久刷新一次.
location: 让网页重新定位
响应状态码
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
404-->资源不存在
5** 服务器错误,服务器在处理请求的过程中发生了错误
500-->服务器代码错误
;502-->网关错误
当浏览器地址输入地址后,回车,到页面展示;这个实际过程=>
解析 URL --> 浏览器封装 HTTP 请求报文 --> DNS 域名解析获取 IP 地址 --> 建立 TCP 连接 --> 浏览器发送请求 --> 负责传输的 IP 协议 --> 使用 ARP 协议凭借 MAC 地址通信 --> 服务器响应请求 --> 断开 TCP 连接 --> 浏览器显示界面
3.maven
使用Maven 可以自动导入,配置jar包.
核心思想:约定大于配置.
官网下载==>https://maven.apache.org/
已安装,环境配置,本地仓库,远程仓库::Maven安装配置
3.1IDEA中使用Maven
3.1.1创建固定模板的maven项目
(1)创建项目时,选择Maven
,查看java的安装目录;勾选Create from archetype(采用maven的模板)
;注意选择的是maven—webapp;
(2)组名-项目名;
(3)填写maven安装地址,maven的setting文件地址;本地仓库配置
(4)新建完成
(5)在设置中查看maven设置
;防止有时自动切换到别的版本;
(6)可以选择自动下载源码;
(7)这里默认是使用项目jdk
3.1.2创建普通的maven项目
在创建时不勾选模板,直接下一步
这里生成的目录中;Java 放置Java源代码;resources 中放置配置文件; 在test下的java中可进行测试使用
3.1.3标准的web
关闭普通的项目;打开之前用maven模板创建的项目;要创建,java,resources,…文件夹Directory
.
有时可能由于版本问题,IDEA没有提示要创建这两个文件夹,就要手动去标注文件夹了;
(1)创建一个命名好的
Directory
后;
(2)右键点击文件夹,可看到Mark Directory as (标记文件夹这个选项)
;出现了一列文件系列.
(3)Sources Root ==>表示存放源码文件夹
;===Test Sources Root ==>表示测试源码的文件夹
;===
Resources Root ==>表示资源配置文件夹
;===test Resources Root ==>表示测试资源文件夹
;
注意;这里excluded==>表示废弃排除的文件夹,一般不要设置错了
除了上面这种快捷方式可以标记文件的,还可以在 project structure (项目结构)
中的Modules (模块)
中进行配置;还有就是如果标记点错了,可以在右边找到对应文件点击 X
取消掉标记就行了
3.2为项目部署Tomcat服务器
之前有用到过Tomcat的部署==>部署Tomcat
有点区别的是这里添加构架Artifact
会跳出两个;选择第一个即可
这里的虚拟路径映射可以为空;
比如,这里我写了
/xiaozhi
;那么访问路径就是127.0.0.1:8080/xiaozhi
;8080端口可以改的
启动服务器,默认加载的是index.jsp文件
查看maven
关于POM.XML
POM.XML
是核心文件;
<?xml version="1.0" encoding="UTF-8"?>
<!--maven的版本与头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 刚才配置的GVA -->
<groupId>com.xiaozhi</groupId>
<artifactId>javaweb01_2121825</artifactId>
<version>1.0-SNAPSHOT</version>
<!--Package:项目的打包方式
jar包:Java应用;
war: JavaWeb应用;
-->
<packaging>war</packaging>
<!--配置-->
<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>
<finalName>javaweb01_2121825</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>
为防止资源导出失败;在build中需要配置resources
<!--为防止资源导出失败;在build中需要配置resources-->
<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>
目录树
在maven的管理栏中有这个图标;可自动生成jar包的关系图
部分问题
若出现需要重复配置maven问题;则在默认设置中配置;
即新项目的设置
这是默认maven默认生成的web.xml
文件;可以更改;
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
要改成Tomcat的安装目录下的webapps
的ROOT
下的WEB-INF
的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">
</web-app>
需要使用的资源出现错误;alt+enter 在maven中寻找
若找不到需要的资源可以在maven仓库寻找,找到依赖配置代码;然后在pom文件中使用依赖下载导入;
Maven仓库地址https://mvnrepository.com/
搜索找到需要的文件;
进入后,出现多个版本的,一般用人数使用多的;
选择版本后;下面会有maven对应的依赖代码,复制,粘贴到pom.xml
文件即可
<scope>是作用域,这里可以删掉
练习
写个servlet类
package com.xiaozhi.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 MyServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应的类型;
response.setContentType("text/html");
//设置字符编码;
response.setCharacterEncoding("utf-8");
//响应的输出流;
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>servlet好耶</h1>");
out.println("</body>");
out.println("</html>");
}
}
在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文件中需要配置servlet-->
<servlet>
<!--servlet名字-->
<servlet-name>MyServlet01</servlet-name>
<!--在项目中的地址-->
<servlet-class>com.xiaozhi.servlet.MyServlet01</servlet-class>
</servlet>
<!--servlet映射配置-->
<servlet-mapping>
<!--对应的servlet名-->
<servlet-name>MyServlet01</servlet-name>
<!--请求的url配置-->
<url-pattern>/MyServlet01</url-pattern>
</servlet-mapping>
</web-app>
启动,输入请求头对应的地址;
4. Servlet
4.1搭建父级下的子级项目
新建一个普通的maven项目,在POM.xml
配置文件导入javax.servlet-api
依赖;删掉src
模块;作为空的父级工程
.
<!--导入依赖-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
创建一个Module
模块,作为子工程
;
创建后,可发现父级项目的pom文件自动生成了
父级项目的pom配置出现;
<modules>
<module>servletStudy-01</module>
</modules>
子项目pom出现
<parent>
<artifactId>javaweb03-servlet01</artifactId>
<groupId>com.xiaozhi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
且发现子项目继承了父项目的jar包;
创建好java,resources两个Directory目录;且进行标记;在java下新建servlet包;
写个类继承Httpservlet;用CTRL+H 查看类关系
初步理解;get和post只是请求方式不同,由于业务逻辑需要,可以相互调用.
编写Servlet的映射
在后端写的是Java程序,但是浏览器访问时需要连接web服务器,那么为了可访问到信息;就得指明访问路径以及注册servlet
4.2 Servlet运行原理
关于mapping映射;
可以让一个servlet一个映射路径,或者多个映射路径.
- 一个映射路径.
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址-->
<url-pattern>/ServletBy01</url-pattern>
</servlet-mapping>
- 多个映射路径;
<!--一个servlet可以映射一个,或者多个路径-->
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址-->
<url-pattern>/ServletBy01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址-->
<url-pattern>/ServletBy02</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址-->
<url-pattern>/ServletBy03</url-pattern>
</servlet-mapping>
- 也可以通配符* 解决通用请求路径.
<!--也可以通配符* 解决通用请求路径-->
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址-->
<url-pattern>/ServletBy01/*</url-pattern>
</servlet-mapping>
- 默认请求路径 /*
<url-pattern>/*</url-pattern>
- 使用自定义路径 (*.XXX);
注意在这里*.前面不能再加路径
<servlet-mapping>
<servlet-name>ServletBy01</servlet-name>
<!--请求头地址;注意在这里*.前面不能再加路径-->
<url-pattern>*.xiaoZhi</url-pattern>
</servlet-mapping>
还有就是有时会出现404资源访问不到的问题,这个页面也是可以使用servlet进行响应的,配置对应的映射即可.
优先级问题;
映射的路径描述越精确,优先级越高,默认的路径(/*)比较低
在涉及到多个子集的web时,部署Tomcat可以先把其他的取消掉;
4.3 ServletContext对象
web容器启动时,会为每个web程序创建一个对应的servletContext对象,代表当前的web应用;
可共享数据,在其中一个servlet中设置保存的数据,在另一个servlet中可获取.
练习;
编写一个servlet类,在servletContext中存储数据;
public class ServletBy02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String myname="啊杰杰杰";
//获取servletcontext对象;
ServletContext servletContext = this.getServletContext();
//设置数据;
servletContext.setAttribute("myname",myname);
}
}
编写另一个servlet获取上一个servlet中保存的数据;
public class GetServletBy02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletStudy02中保存的数据;
ServletContext servletContext = this.getServletContext();
String myname = (String) servletContext.getAttribute("myname");
//设置响应的内容格式,与编码格式;
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
//响应数据;
PrintWriter writer = resp.getWriter();
writer.print("<h1>"+"获取数据=>"+myname+"</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
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">
<!--配置servlet-->
<servlet>
<servlet-name>ServletBy02</servlet-name>
<servlet-class>com.xiaozhi.servlet.ServletBy02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletBy02</servlet-name>
<url-pattern>/ServletBy02</url-pattern>
</servlet-mapping>
<!--获取 ServletBy02数据的servlet-->
<servlet>
<servlet-name>GetServletBy02</servlet-name>
<servlet-class>com.xiaozhi.servlet.GetServletBy02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetServletBy02</servlet-name>
<url-pattern>/ServletBy02/getS2</url-pattern>
</servlet-mapping>
</web-app>
启动服务器,先访问获取servlet数据的那个路径;由于并没有数据,故返回的是null值;
再访问/ServletBy02;即保存了数据的servlet;后;然后再访问获取servlet的路径;获取到数据了
4.4获取指定的参数值;
练习;
在web.xml中设置参数键值对;
<!--获取参数的演示练习-->
<context-param>
<param-name>mypass</param-name>
<param-value>qwertuiop</param-value>
</context-param>
在一个servlet类中获取servletcontext对象;去获取web.xml中设置的指定参数值;
public class ServletBy03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取servletcontext对象;
ServletContext servletContext = this.getServletContext();
//获取指定的参数值;
String mypass = servletContext.getInitParameter("mypass");
//控制台输出参数值;
System.out.println(mypass);
}
}
在web,xml中配置ServletBy03及映射路径;启动服务器后,访问该路径,控制台输出了指定参数值;
4.5请求转发
请求转发
例如 A 向 B 借钱; B 悄悄地借了 C 的钱,把这个钱借给了 A ;但是 A 并不知道这是 B 借来的;
整个过程是属于一次请求
重定向
例如 A 向 B 借钱,这一次 B直接回复A;你去找 C 借钱吧; 然后 A 跑去找 C 借钱;借到了钱;
整个过程是有两次请求
练习;
使用request请求对象的方法getRequestDispatcher
设置请求转发的路径;
然后调用forward方法实现请求转发;
public class ServletBy04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求转发的路径;
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/requestFor03");
//调用forward方法实现请求转发;
requestDispatcher.forward(req,resp);
}
}
4.6 读取资源文件
properties文件
在java和resources目录下各自新建properties文件后,运行项目时;
这两个文件都被打包到了同一个路径下==>classes
;即路径classpath
获取properties文件练习
public class ServletBy05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用文件流;获取打包的文件路径;
InputStream inputStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
//读取Java的配置文件
Properties properties = new Properties();
properties.load(inputStream);
//用指定的键在此属性列表中搜索属性;
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//输出文件;
PrintWriter writer = resp.getWriter();
writer.print(user+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.7 Response下载文件
web服务器接收到客户端的http请求后,
创建代表请求的HttpServletRequest
;代表响应的HttpServletResponse
关于响应;
(1)负责向浏览器发送数据的方法
- ServletOutputStream getOutputStream() throws IOException;
- PrintWriter getWriter() throws IOException;
(2)发送响应头
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long 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);
void addIntHeader(String var1, int var2);
(3)设置的状态码
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
下载文件
(1)获取下载文件的路径;
(2)设置下载文件名;
(3)设置浏览器支持下载;
(4)获取下载文件的输入流;
(5)创建缓冲区;
(6)获取OutputStream对象;
(7)将FileOutPutStream流写入到buffer缓冲区;
(8)使用OutputStream将缓冲区的数据输出到客户端
练习
public class ServletToDownloadFile extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//1.获取下载文件的路径;
String filePath="F:\\idea使用\\B站狂神说java\\Web复习狂神说系列\\8月26日Servlet复习\\javaweb03-servlet01\\servletStudy-02\\target\\classes\\com\\xiaozhi\\鱼头.jpg";
//控制台看看下载文件路径;
System.out.println("要下载的文件路径=>"+filePath);
//2.获取要下载的文件的文件名;使用截取字符串的方法;
String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
//3.设置浏览器可支持下载文件;
resp.setHeader("Content-disposition","attachment;filename"+ URLEncoder.encode(fileName,"UTF-8"));
//4.获取下载文件的输入流;
FileInputStream fileInputStream = new FileInputStream(filePath);
//5.创建缓冲区;
byte[] buffer=new byte[1024];
int len =0;
//6.获取OutputStream对象;
ServletOutputStream outputStream = resp.getOutputStream();
//7.将FileOutPutStream流写入到buffer缓冲区;
while ((len=fileInputStream.read(buffer))>0){
//8.使用OutputStream将缓冲区的数据输出到客户端;
outputStream.write(buffer,0,len);
}
//关闭流;
outputStream.close();
fileInputStream.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.8 Response 返回随机数实现
关于验证实现;
对于后端验证来说,就得用到图片类.
练习
public class ServletForAuthCode extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//定时刷新页面;
resp.setHeader("Refresh","5");
//在内存中创建一个图片;(图片宽度,高度,三原色)
BufferedImage image = new BufferedImage(80,80,BufferedImage.TYPE_3BYTE_BGR);
//获取图片; 使用画笔;
Graphics2D graphics = (Graphics2D)image.getGraphics();
//设置图片背景颜色;
graphics.setColor(Color.WHITE);
//填充颜色;设置位置;
graphics.setClip(0,0,80,80);
//为图片存数据;
//设置画笔颜色;
graphics.setColor(Color.green);
//设置字体;
graphics.setFont(new Font(null,Font.BOLD,20));
//调用随机数;绘制指定的文本字符串;
graphics.drawString(randomNum(),0,20);
//通知浏览器,此次请求用图片方式打开;
resp.setContentType("image/jpg");
//由于网站存在缓存;不让它缓存;
resp.setDateHeader("expires",-1);
resp.setHeader("cache-control","no-cache");
resp.setHeader("Pragma","no-cache");
//将图片写给浏览器;
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数的方法;
public String randomNum(){
Random random=new Random();
//随机数,转为字符串;
String str=random.nextInt(9999999)+"";
StringBuffer sb=new StringBuffer();
//生成随机数时,前面的0会被省略;这时需要保证返回的数是7位数;那么就给他追加数字,保证为7位数;
for (int i = 0; i < 7-str.length(); i++) {
sb.append("0");
}
//最终返回的字符串为7位数;
str=sb.toString()+str;
return str;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml的映射
4.9 重定向
当一个web资源收到客户端请求,通知客户端去访问另一个web资源;即重定向;
发生了两次请求
.
response.sendRedirect("/路径");
实际上就是
response.setHeader("Location","/路径");
response.setStatus(302);
请求转发与重定向的区别
相同点==>页面都会实现跳转;
不同点==>请求转发时,只发生一次请求,url不会产生变化;
重定向时,发生两次请求,url地址栏会发生变化;
4.10 Request应用
HttpServletRequest 表示客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过方法,获取客户端的信息.
String getParameter(String s) 获取指定的参数;
String[] getParameterValues(String s) 获取一组参数;
练习
模拟登陆;
默认的index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<body>
<h2>欢迎</h2>
<%--${pageContext.request.contextPath}为本项目的路径--%>
<dis style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
账户:<input type="text" name="account"><br/>
密码:<input type="password" name="password"><br/>
课程:
<input type="checkbox" name="course" value="Java">Java
<input type="checkbox" name="course" value="C#">C#
<input type="checkbox" name="course" value="C++">C++
<input type="checkbox" name="course" value="Python">Python<br/>
<input type="submit" value="提交">
</form>
</dis>
</body>
</html>
成功页面;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>成功</title>
</head>
<body>
成功进入
</body>
</html>
处理登陆信息,并将之转发的Servlet
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求字符编码;
req.setCharacterEncoding("utf-8");
//获取参数;
String account = req.getParameter("account");
String password = req.getParameter("password");
String[] courses = req.getParameterValues("course");
System.out.println(Arrays.toString(courses));
//转发页面,这里的"/"表示当前项目;
req.getRequestDispatcher("/success.jsp").forward(req,resp);
//设置响应编码;
resp.setCharacterEncoding("utf-8");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(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>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.xiaozhi.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
5. Cookie ,Session
首先对于会话的理解:当用户打开浏览器,点击链接;访问了多个web资源;关闭浏览器,此过程为会话.
有状态会话:服务器记录客户端来过,下次客户端访问时,服务器是有记录的.
cookie理解: 服务端给客户端提供一个信件,那么客户端下次就可以凭借这个信件去找服务器.
保留会话的两种技术
cookie
客户端技术(响应和请求)
session
服务器端技术(保存用户会话信息,可以把信息数据放到session中)
cookie一般保存在本地目录的 appdate中
- 一个cookie只能保存一个信息;
- 一个web站点可以向浏览器发送多个cookie;最多存放20个;且cookie的大小有限制(4kb).
- 浏览器cookie上限300;
对于删除cookie:
- 不设置cookie的有效期,关闭浏览器,就删除了.
- 设置cookie的有效期为0.
练习
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//请求编码设置;
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//获取输出流;
PrintWriter out = resp.getWriter();
//服务器在客户端获取;
//Cookie可能存在多个;
Cookie[] cookies = req.getCookies();
if(cookies!=null){
out.print("你上次访问的时间=>");
//若存在就获取;
for (int i = 0; i < cookies.length; i++) {
Cookie cookie=cookies[i];
if (cookie.getName().equals("LastTime")) {
//取到cookie中的值;且转为时间戳类型;
long lastTime=Long.parseLong(cookie.getValue());
//转为日期类型;
Date date=new Date(lastTime);
out.write(date.toLocaleString());
}
}
}else {
out.write("您的第一次访问");
}
//服务器向客户端响应cookie;
Cookie cookie = new Cookie("LastTime",System.currentTimeMillis()+"");
//设置cookie的有效期;以秒为单位;
cookie.setMaxAge(365*24*3600);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp);
}
}
Session
- 服务器为每个用户创建一个session对象;
- 一个session对象独立占用一个浏览器;只要浏览器不关闭,它就一直存在.
- 例如用户登录网站后,即可访问网站的所有信息.
销毁session
- 手动强制销毁session; ----->调用方法session. invalidate();
- 设置session的有效时间,以分钟为单位;
<!--设置session有效时间 以分钟为单位;-->
<session-config>
<session-timeout>10</session-timeout>
</session-config>
cookie保存会话
session保存会话;
Session和Cookie的区别
- Session是把用户的数据写到独属于用户的session中,在服务器端保存,一般用来保存重要信息.
- Cookie将用户的数据写给用户的浏览器,让浏览器保存,可保存多个;
练习
观察session的创建;(这里创建实体类对象作为session指定属性的值)
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//设置字符编码;
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
//获取session;
HttpSession session = req.getSession();
//向session赋值;
session.setAttribute("person",new Person("杰哥",20));
//获取session的Id;
String id = session.getId();
//判断是否为新的session;
if(session.isNew()){
resp.getWriter().write("创建了session=>Id为=>"+id);
}else {
resp.getWriter().write("已经存在了session=>Id为=>"+id);
}
//将session的Id存入cookie;
/* Cookie cookie = new Cookie("JSESSIONID", id);
resp.addCookie(cookie);*/
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml中配置servlet;
第一次启动服务器,访问时;
再次访问,还是原来的session,因为它没被销毁或者失效,就一直存在着
编写一个类,获取session中设置的指定属性的值;
public class GetSession01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置字符编码;
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
//获取session;
HttpSession session = req.getSession();
//获取指定属性的session值;
Person person = (Person) session.getAttribute("person");
resp.getWriter().write(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
先访问之前的设置session,然后再获取,可获取到指定属性person的数据.
6. JSP
6.1 JSP原理剖析
Java Server Pages :Java服务器端页面,与Servlet一样,用于动态Web技术
JSP就像是HTML但是有区别.
- HTML只是提供静态数据.
- JSP页面可写Java代码,提供动态数据.
先看看Tomcat的work目录.
访问隐藏的IDEA工作目录;IDEA下也是存在Tomcat工作目录;jsp转为了Java程序
服务器的内部工作
- Tomcat的work目录
- IDEA中部署了Tomcat的项目,在idea的Tomcat中存在work目录
浏览器向服务器发出请求,对于访问资源,都是在访问servlet
jsp也会被编译为Java程序(在被访问之后),而他实质上就是servlet
可以看看之前写过的jsp被编译后的样子;
底层编译后就像servlet的流那样的输出方式.
得到一个请求时,首先会判断请求
看看这些部分内置对象:
final javax.servlet.jsp.PageContext pageContext;//pageContext 页面上下文
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContext application;//servletContext
final javax.servlet.ServletConfig config;//config 配置
javax.servlet.jsp.JspWriter out = null; //out; 输出
final java.lang.Object page = this; //page; 当前页面
还有request 请求,
reponse 响应
输出页面时之前的代码;自动添加的.
response.setContentType("text/html;charset=UTF-8");//设置响应页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
6.2 JSP 基本语法与指令
JSP表达式
用于将程序的输出–>客户端
<%=变量或者表达式%>
用el表达式可直接写为${ 变量或表达式 }
;这样对于那些不存在的数,就不会输出为null
<%=new Date()%>
JSP脚本片段
<% JSP脚本%>
<%
int num=0;
for (int i = 0; i < 5; i++) {
num+=i;
}
out.print("<h1>"+num+"</h1>");
%>
可在代码中放入HTML元素
<%
for (int i = 0; i < 10; i++) {
%>
<p>这是一个段落</p>
<%
}
%>
JSP声明,(全局变量,代码块,方法)
<%! 声明.....%>
<%!
static {
System.out.println("我是静态代码块");
}
private int axc=100;
public void test(){
System.out.println("我是方法");
}
%>
而声明被编译后,位置和之前定义的不一样.
JSP声明会被编译到类中;而其他的是被编译到类的_jspService方法中
JSP的注释,不会被编译,安全性高
<%--注释--%>
指令
page指令设置字符编码;语言类型,不忽略EL表达式
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
page指令中导包
<%@ page import="java.util.Date" %>
在page指令中跳转错误页面
<%@ page errorPage="error/500.jsp" %>
当然,错误跳转也可以在web.xml中配置
<!--配置错误页面-->
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
page指令中可以显示地标出错误页面
<%@ page isErrorPage="true" %>
在include指令中;提取公共页面的信息
静态包含指的是在编译期间,把包含的页面也编译到当前页面的Java文件中,也就是编译时就将2个jsp文件合2为1;
<%@ include file="/common/header.jsp"%>
动态包含:在jsp页面中动态包含另一个资源;在运行期间;访问被包含的页面,并将响应结果同包含页面的响应结果合并,生成最终响应。
<jsp:include page=“被包含页面()” flush=“true或者false”/>
6.3 内置对象及作用域
之前学过的内置对象概念 =>JSP内置对象
setAttribute()实现类的方法
若没有指定的获取的是哪个域对象,则先后顺序为pageScope、requestScope、sessionScope和applicationScope。(尤其是几个域对象有同名属性时.)
pageContex 保存的数据只在一个页面中有效;
request 仅在一次请求中有效,请求转发会携带数据;
session 仅在一次会话中有效,(会话生命周期);
application 仅在服务器中有效, 服务器打开–>关闭;
在页面请求转发;
- 直接使用pageContext对象调用forward方法
<%
pageContext.forward("/demo0.jsp");
%>
- 使用request的方式
<%
request.getRequestDispatcher("/demo0.jsp").forward(request,response);
%>
练习:
设置几个属性
<%@ page import="jdk.nashorn.internal.runtime.Scope" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--内置对象的作用域--%>
<%
pageContext.setAttribute("name","page设置的");//保存的数据只在一个页面中有效;
request.setAttribute("name","request设置的");//仅在一次请求中有效,请求转发会携带数据;
session.setAttribute("name","session设置的");//仅在一次会话中有效,(会话生命周期);
application.setAttribute("name","application设置的");//仅在服务器中有效, 服务器打开-->关闭;
%>
<%--获取 设置的属性--%>
<%
out.print(pageContext.getAttribute("name"));
%><br/>
<%
out.print(request.getAttribute("name"));
%><br/>
<%
out.print(session.getAttribute("name"));
%><br/>
<%
out.print(application.getAttribute("name"));
%><br/>
</body>
</html>
在此页面范围可全部获取;
在另一个请求中获取
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--获取 inlayDemo01.jsp设置的属性--%>
<%
out.print(pageContext.getAttribute("name"));
%><br/>
<%
out.print(request.getAttribute("name"));
%><br/>
<%
out.print(session.getAttribute("name"));
%><br/>
<%
out.print(application.getAttribute("name"));
%><br/>
</body>
</html>
6.4 EL表达式;JSTL标签
EL表达式,可用于获取数据,执行运算,获取web开发的常用对象
使用JSTL需要在pom文件中导入依赖
<!--jstl表达式依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--标签库-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
先来看看 JSP标签
(1)动态包含:在jsp页面中动态包含另一个资源;在运行期间;访问被包含的页面,并将响应结果同包含页面的响应结果合并,生成最终响应。
<jsp:include page=“被包含页面()” flush=“true或者false”/>
(2)转发页面,可携带数据信息;
例如:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--(2)请求转发,可携带数据--%>
<jsp:forward page="/demoforward.jsp">
<jsp:param name="name" value="tom"/>
<jsp:param name="age" value="21"/>
</jsp:forward>
</body>
</html>
转发到的位置
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>转发来了</title>
</head>
<body>
你被转发过来了!!!<br/>
<%= request.getParameter("name")%>+<%= request.getParameter("age")%>
</body>
</html>
JSTL标签
之前记过的JSTL部分标签使用==>JSTL标签
练习:
使用if标签判断
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--数据返回给自己--%>
<form action="jstlIfDemo.jsp"method="get">
<%--可获取填写的数据;${param.参数名}--%>
<input name="name" value="${param.name}"><br/>
<input type="password" name="password" value="${param.password}"><br/>
<input type="submit" value="点击提交">
</form>
<%--处理提交的数据--%>
<c:if test="${param.name=='tom'}" var="ifok">
<c:out value="欢迎用户"/>
</c:if>
<c:out value="${ifok}"/>
</body>
</html>
当时启动时遇到了解析导包错误问题;在Tomcat的lib包下放入jstl的jar包;
练习
多重选择
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--定义变量;var:变量名;value:值--%>
<c:set var="num" value="88"/>
<%--选择标签--%>
<c:choose>
<c:when test="${num>100}">
好耶
</c:when>
<c:when test="${num>90}">
还行
</c:when>
<c:when test="${num>=80}">
不太行
</c:when>
</c:choose>
</body>
</html>
练习,
循环
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
ArrayList<String> dog=new ArrayList<>();
dog.add(0,"旺财1号");
dog.add(1,"旺财2号");
dog.add(2,"旺财3号");
dog.add(3,"旺财4号");
request.setAttribute("dog",dog);
%>
<%--遍历得到数组中的元素--%>
<%--items:需要遍历的目标; var:每次遍历得到的变量;
varStatus:状态信息,可用的参数有索引,序号....;
begin:从第几个索引开始;
end:从第几个索引结束;
step:循环的步长;(隔几个元素循环一次);
--%>
<c:forEach items="${dog}" var="d">
${d}
</c:forEach>
</body>
</html>
6.5 JavaBean
就是实体类.
必须要有一个无参构造;且属性全部是私有的;属性要有对应的get,set方法;
ORM:对象关系的映射;
- 表 对应 类
- 字段 对应 属性
- 行记录 对应 对象
练习;
创建实体类后;使用jsp标签,设置以及获取对象中的属性.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--使用jsp标签--%>
<jsp:useBean id="character" class="com.lzq.bean.Character" scope="page">
<jsp:setProperty name="character" property="id" value="30"/>
<jsp:setProperty name="character" property="name" value="杰哥"/>
<jsp:setProperty name="character" property="age" value="18"/>
<jsp:setProperty name="character" property="sex" value="男"/>
</jsp:useBean>
<jsp:getProperty name="character" property="name"/>
<jsp:getProperty name="character" property="sex"/>
<jsp:getProperty name="character" property="id"/>
</body>
</html>
7. MVC三层架构
M即model模型是指模型表示业务规则。
V即View视图是指用户看到并与之交互的界面。
C即controller控制器是指控制器;接受用户的输入并调用模型和视图去完成用户的需求.
之前的架构就仅仅用控制层与视图层;
用户可直接访问控制层;而控制层就去交互数据库;
弊端;不利于维护,程序冗余
使用MVC后
Model:
业务逻辑处理–>(Service)
数据持久层–>(Dao)
View:
展示数据
提供链接发起Servlet请求
Controller:
接收用户的请求;调用业务层处理对应需求;控制视图跳转
8.过滤器Filter
对于用户发出的请求,进行部分处理;例如字符编码统一设置;屏蔽词汇,拦截未登录的请求…
注意自定义过滤器时,实现的Filter接口是servlet包里面的;
练习
编写字符过滤器;
package com.lzq.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* 自定义的字符编码过滤器;
*/
public class CharacterEncodingFilter implements Filter {
//服务器启动时,就初始化了,等待过滤对象出现;
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("字符编码过滤器初始化=>");
}
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
//设置请求与相应的编码;
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html");
System.out.println("处理字符编码之前====>");
//作为交接,把请求响应交给下一个(可能是过滤器,可能是servlet);
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("处理字符编码之后====>");
}
//服务器关闭,就销毁过滤器;
public void destroy() {
System.out.println("字符编码过滤器销毁=>");
}
}
在web.xml中进行配置
<!--配置字符编码过滤器-->
<filter>
<filter-name>characterEncoding</filter-name>
<filter-class>com.lzq.filter.CharacterEncodingFilter</filter-clas
</filter>
<filter-mapping>
<filter-name>characterEncoding</filter-name>
<!--一般不建议设为全部路径-->
<url-pattern>/*</url-pattern>
</filter-mapping>
9.监听器
练习
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 练习监听器;监听在线人数;
*/
public class DemoListener implements HttpSessionListener {
//监听器创建;
public void sessionCreated(HttpSessionEvent se) {
ServletContext servletContext = se.getSession().getServletContext();
//获取sessionId;
System.out.println(se.getSession().getId());
//获取在线人数;
Integer num = (Integer) servletContext.getAttribute("OnlineCount");
if(num==null){
num= new Integer(1);
}else {
int count=num.intValue();
num=new Integer(count+1);
}
servletContext.setAttribute("OnlineCount",num);
}
//监听器销毁;
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext servletContext = se.getSession().getServletContext();
//获取在线人数;
Integer num = (Integer) servletContext.getAttribute("OnlineCount");
//销毁时,清空统计的数量;
if(num==null){
num= new Integer(0);
}else {
int count=num.intValue();
num=new Integer(count-1);
}
servletContext.setAttribute("OnlineCount",num);
}
}
web.xml配置监听器
<listener>
<listener-class>com.lzq.listener.DemoListener</listener-class>
</listener>
在index页面查看
<h1>当前在线人数==>
<%=
this.getServletConfig().getServletContext().getAttribute("OnlineCount")
%></h1>
10.Filter权限拦截
登录的Servlet
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取到参数;
String name = req.getParameter("name");
if(name.equals("tom")){
req.getSession().setAttribute("NAME_SESSION",req.getSession().getId());
resp.sendRedirect("/success.jsp");
}else {
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
退出登录的servlet
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//先获取session;
Object name_session = req.getSession().getAttribute("NAME_SESSION");
if(name_session!=null){
req.getSession().removeAttribute("NAME_SESSION");
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml文件…
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
用户:<input name="name">
<input type="submit" value="提交">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object name_session = request.getSession().getAttribute("NAME_SESSION");
if(name_session==null){
response.sendRedirect("/login.jsp");
}
%>
成功进入<br/>
<a href="/logout">注销</a>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>错误</title>
</head>
<body>
<h1>错误页面</h1>
</body>
</html>
可达到不登录就无法访问成功页面,但是登录过,再注销;回退可访问到成功页面.
添加过滤器的方式;
创建判断是否登录过滤器
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class IsLoginFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Object name_session = request.getSession().getAttribute("NAME_SESSION");
if(name_session==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(request,response);
}
}