JavaWeb
JavaWeb
1. 基本概念
1.1 前言
web
开发:
- web:网页的意思
- 静态web:
html
、css
等。提供给所有人看到的数据始终不会发生改变! - 动态web:
Servlet
、JSP
、ASP
、PHP
等。提供给所有人看到的数据始终会发生改变! JavaWeb
:在Java
中,动态web
资源开发的技术统称为JavaWeb
。
- 静态web:
1.2 web应用程序
web应用程序
:可以提供浏览器访问的程序;
*.html
等多个web
资源,这些web
资源可以被外界访问,对外界访问;- 这些统一的的
web
资源会被放在同一个文件夹下,Java常用的web应用程序
:Tomcat服务器
; - 一个
web
应用由多部分组成(静态web、动态web)html
、css
、js
JSP
、Servlet
Java
程序jar
包- 配置文件(
*.Properties
)
web应用程序
编写完毕后,若想提供给外界访问,则需要一个服务器统一管理;
1.3 静态web
*.htm
、*.html
这些都是网页的后缀,如果服务器上一直存在这些资源,我们就可以直接进行读取;
静态web存在的缺点:
- web页面无法动态更新,所有用户看到的都是同一个页面;
- 伪动态:轮播图、点击特效(
JavaScript
、VBScript
);
- 伪动态:轮播图、点击特效(
- 无法和数据库交互(数据无法持久化,用户无法交互);
1.4 动态web
页面会动态展示:web页面
展示的效果因人而异;
动态web存在的缺点:
- 服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序并重新发布;
动态web存在的优点:
- web页面可以动态更新,所有用户看到的都不是同一个页面
- 可以和数据库交互;
2. web服务器
2.1 技术讲解
ASP
:IIS服务器
- 微软:国内最早流行的就是
ASP
; - 在
HTML
中嵌入了VB脚本,ASP
+COM
; - 在
ASP
开发中,基本一个页面都有几千行的业务代码,页面极其混乱,维护成本高;
PHP
:
- PHP开发速度快,功能很强大,跨平台,代码很简单;
- 无法承载大访问量的情况,有局限性;
JSP/Servlet
:
- sun公司主推的B/S结构
- 基本Java语言(所有大公司或一些开源的组件,都是用Java写的)
- 可以承载三高问题带来的影响;
- 语法像ASP,加强市场强度;
2.2 web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些相应信息;
IIS
:微软公司出品,Windows系统自带;
Tomcat
:
Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,它是最佳的选择。
诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。Tomcat最新版本为10.0.5。
Tomcat 实际上运行JSP 页面和Servlet。Tomcat最新版本为10.0.5。
3. Tomcat
Tomcat官网地址:http://tomcat.apache.org/
3.1 Tomcat重要文件夹的作用
bin
:启动和关闭的脚本文件conf
:配置信息lib
:依赖的jar
包logs
:日志webapps
:网站应用
3.2 Tomcat的启动、关闭与访问测试
-
启动:执行
Tomcat
根目录bin
文件夹下的startup.bat
; -
关闭:执行
Tomcat
根目录bin
文件夹下的shutdown.bat
; -
访问:执行
startup.bat
后,在浏览器地址输入:http://localhost:8080/
3.3 Tomcat配置
核心配置文件:server.xml
-
配置启动的端口号:
Tomcat
默认端口号:8080MySQL
默认端口号:3306Oracle
默认端口号:1521http
默认端口号:80https
默认端口号:443<!-- 变更Connector节点的port属性值 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
-
配置主机的名称:
主机的默认名称:
localhost
网站应用的默认存放位置:
webapps
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
-
高难度面试题:请你谈谈网站是如何进行访问的?
- 输入一个域名;
- 检查本机
C:\Windows\System32\drivers\etc\hosts
配置文件是否存在域名重定向;- 存在重定向:返回对应的
IP
地址,这个地址中存在我们访问的web
程序即可直接访问; - 不存在重定向:去
DNS
服务器上寻找IP
地址,这个地址中存在我们访问的web
程序即可直接访问;
- 存在重定向:返回对应的
3.4 发布一个web网站
-
将自己写的网站放到
Tomcat
中指定的webapps
目录下-webapps:Tomcat服务器的web目录 -ROOT -examples:网站的目录名 -WEB-INF -classes:Java程序 -lib:web应用所依赖的jar包 -web.xml:网站配置文件 -index.html:网站默认首页 -static -css:样式文件夹 -js:JS文件夹 -img:图片文件夹
4. HTTP
4.1 什么是HTTP?
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
- 文本:html,字符串……
- 超文本:图片、音乐、视频、定位、地图……
4.2 两个时代
- http 1.0
- HTTP/1.0:客户端可以与
web服务器
连接后,只能获得一个web资源,断开连接;
- HTTP/1.0:客户端可以与
- http 2.0
- HTTP/1.1:客户端可以与
web服务器
连接后,可以获得多个web资源;
- HTTP/1.1:客户端可以与
4.3 Http请求
-
客户端 --> 发送请求(Request) --> 服务器端
以百度为例:
// General Request URL: https://www.baidu.com/ // 请求地址 Request Method: GET // 请求方法 GET/POST Status Code: 200 OK // 状态码 Remote Address: 14.215.177.39:443 // 远程IP地址
// Request Headers Accept: text/html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 // 语言 Connection: keep-alive // 连接
4.3.1 请求行
- 请求行中的请求方式:GET
- 请求方式:GET、POST、HEAD、DELETE、PUT、TRACT……
- GET:
- 请求能够携带的参数比较少
- 大小有限制
- 会在浏览器的
URL
地址栏显示数据内容 - 不安全但高效
- POST:
- 请求能够携带的参数没有限制
- 大小没有有限制
- 不会在浏览器的
URL
地址栏显示数据内容 - 安全但不高效
- GET:
4.3.2 消息头
Accept
:告诉浏览器,它所支持的数据类型Accept-Encoding
:支持哪种编码格式(GBK、UTF-8、GB2312、ISO8859-1)Accept-Language
:告诉浏览器,它的语言环境Connection
:告诉浏览器,请求完成是断开还是保持连接HOST
:主机
4.4 Http响应
-
服务器端 --> 发送响应 --> 客户端
以百度为例:
// Response Headers Bdpagetype: 1 Bdqid: 0xd33f965d000404bb Cache-Control: private // 缓存控制 Connection: keep-alive // 连接 Content-Encoding: gzip // 编码格式 Content-Type: text/html;charset=utf-8 // 类型
4.4.1 响应体
Accept
:告诉浏览器,它所支持的数据类型Accept-Encoding
:支持哪种编码格式(GBK、UTF-8、GB2312、ISO8859-1)Accept-Language
:告诉浏览器,它的语言环境Connection
:告诉浏览器,请求完成是断开还是保持连接HOST
:主机Refresh
:告诉客户端,多久刷新一次Location
:让网页重新定位
4.4.2 响应状态码
- 200:请求响应成功
- 3xx:请求重定向
- 4xx:找不到资源(404)
- 5xx:服务器代码错误(500、502网关错误)
4.5 常见面试题
当你的浏览器地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
5. Maven项目架构管理工具
Maven的核心思想:约定大于配置
- 有约束,不要违反
Maven会规定好如何编写我们的
Java
代码,必须按照这个规范来实现;
Maven官网地址:https://maven.apache.org/
5.1 Maven的配置
配置环境变量:
M2_HOME
:Maven目录\binMAVEN_HOME
:Maven目录path
:%MAVEN_HOME%\bin
核心配置文件:server.xml
-
LocalRepository
:- 作用:表示构建系统本地仓库的路径。
- 默认值:
~/.m2/repository
-
InteractiveMode
:- 作用:表示maven是否需要和用户交互以获得输入。如果maven需要和用户交互以获得输入,则设置成true,反之则应为false。
- 默认值:
true
-
UsePluginRegistry:
- 作用:maven是否需要使用plugin-registry.xml文件来管理插件版本。如果需要让maven使用文件~/.m2/plugin-registry.xml来管理插件版本,则设为true。
- 默认值:
false
-
Offline:
- 作用:这个属性表示在Maven进行项目编译和部署等操作时是否允许Maven进行联网来下载所需要的信息。如果构建系统需要在离线模式下运行,则为true。(当由于网络设置原因或者安全因素,构建服务器不能连接远程仓库的时候,该配置就十分有用)
- 默认值:
false
-
PluginGroups:
-
作用:在
pluginGroups
元素下面可以定义一系列的pluginGroup
元素。表示当通过plugin
的前缀来解析plugin的时候到哪里寻找。pluginGroup
元素指定的是plugin
的groupId
。默认情况下,Maven会自动把org.apache.maven.plugins
和 org.codehaus.mojo 添加到pluginGroups
下。<pluginGroups> <!--plugin的组织Id(groupId) --> <pluginGroup>org.codehaus.mojo</pluginGroup> </pluginGroups>
-
-
Servers:
-
作用:一般仓库的下载和部署是在pom.xml文件中的
repositories
和distributionManagement
元素中定义的。然而,一般类似用户名、密码(有些仓库访问是需要安全认证的)等信息不应该在pom.xml
文件中配置,这些信息可以配置在settings.xml
中。<!--配置服务端的一些设置。一些设置如安全证书不应该和pom.xml一起分发。这种类型的信息应该存在于构建服务器上的settings.xml文件中。 --> <servers> <!--服务器元素包含配置服务器时需要的信息 --> <server> <!--这是server的id(注意不是用户登陆的id),该id与distributionManagement中repository元素的id相匹配。 --> <id>server001</id> <!--鉴权用户名。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。 --> <username>my_login</username> <!--鉴权密码 。鉴权用户名和鉴权密码表示服务器认证所需要的登录名和密码。密码加密功能已被添加到2.1.0 +。详情请访问密码加密页面 --> <password>my_password</password> <!--鉴权时使用的私钥位置。和前两个元素类似,私钥位置和私钥密码指定了一个私钥的路径(默认是${user.home}/.ssh/id_dsa)以及如果需要的话,一个密语。将来passphrase和password元素可能会被提取到外部,但目前它们必须在settings.xml文件以纯文本的形式声明。 --> <privateKey>${usr.home}/.ssh/id_dsa</privateKey> <!--鉴权时使用的私钥密码。 --> <passphrase>some_passphrase</passphrase> <!--文件被创建时的权限。如果在部署的时候会创建一个仓库文件或者目录,这时候就可以使用权限(permission)。这两个元素合法的值是一个三位数字,其对应了unix文件系统的权限,如664,或者775。 --> <filePermissions>664</filePermissions> <!--目录被创建时的权限。 --> <directoryPermissions>775</directoryPermissions> </server> </servers>
-
-
Mirrors:
-
作用:用于定义一系列的远程仓库的镜像。我们可以在
pom.xml
中定义一个下载工件的时候所使用的远程仓库。但是有时候这个远程仓库会比较忙,所以这个时候人们就想着给它创建镜像以缓解远程仓库的压力,也就是说会把对远程仓库的请求转换到对其镜像地址的请求。每个远程仓库都会有一个id,这样我们就可以创建自己的mirror
来关联到该仓库,那么以后需要从远程仓库下载工件的时候Maven就可以从我们定义好的mirror
站点来下载,这可以很好的缓解我们远程仓库的压力。在我们定义的mirror
中每个远程仓库都只能有一个mirror
与它关联,也就是说你不能同时配置多个mirror
的mirrorOf
指向同一个repositoryId
。<mirrors> <!-- 给定仓库的下载镜像。 --> <mirror> <!-- 该镜像的唯一标识符。id用来区分不同的mirror元素。 --> <id>mirrorId</id> <!-- 镜像名称 --> <name>PlanetMirror Australia</name> <!-- 该镜像的URL。构建系统会优先考虑使用该URL,而非使用默认的服务器URL。 --> <url>http://downloads.planetmirror.com/pub/maven2</url> <!-- 被镜像的服务器的id。例如,如果我们要设置了一个Maven中央仓库(http://repo.maven.apache.org/maven2/)的镜像,就需要将该元素设置成central。这必须和中央仓库的id central完全一致。 --> <mirrorOf>repositoryId</mirrorOf> </mirror> </mirrors>
-
-
Proxies:
-
作用:用来配置不同的代理。
<proxies> <!--代理元素包含配置代理时需要的信息 --> <proxy> <!--代理的唯一定义符,用来区分不同的代理元素。 --> <id>myproxy</id> <!--该代理是否是激活的那个。true则激活代理。当我们声明了一组代理,而某个时候只需要激活一个代理的时候,该元素就可以派上用处。 --> <active>true</active> <!--代理的协议。 协议://主机名:端口,分隔成离散的元素以方便配置。 --> <protocol>http</protocol> <!--代理的主机名。协议://主机名:端口,分隔成离散的元素以方便配置。 --> <host>proxy.somewhere.com</host> <!--代理的端口。协议://主机名:端口,分隔成离散的元素以方便配置。 --> <port>8080</port> <!--代理的用户名,用户名和密码表示代理服务器认证的登录名和密码。 --> <username>proxyuser</username> <!--代理的密码,用户名和密码表示代理服务器认证的登录名和密码。 --> <password>somepassword</password> <!--不该被代理的主机名列表。该列表的分隔符由代理服务器指定;例子中使用了竖线分隔符,使用逗号分隔也很常见。 --> <nonProxyHosts>*.google.com|ibiblio.org</nonProxyHosts> </proxy> </proxies>
-
-
Profiles:
-
作用:根据环境参数来调整构建配置的列表。
settings.xml
中的profile
元素是pom.xml
中profile
元素的裁剪版本。它包含了id
、activation
、repositories
、pluginRepositories
和properties
元素。这里的profile
元素只包含这五个子元素是因为这里只关心构建系统这个整体(这正是settings.xml
文件的角色定位),而非单独的项目对象模型设置。如果一个settings.xml
中的profile
被激活,它的值会覆盖任何其它定义在pom.xml
中带有相同id
的profile
。当所有的约束条件都满足的时候就会激活这个profile
。<profiles> <profile> <!-- profile的唯一标识 --> <id>test</id> <!-- 自动触发profile的条件逻辑 --> <activation> <activeByDefault>false</activeByDefault> <jdk>1.6</jdk> <os> <name>Windows 7</name> <family>Windows</family> <arch>x86</arch> <version>5.1.2600</version> </os> <property> <name>mavenVersion</name> <value>2.0.3</value> </property> <file> <exists>${basedir}/file2.properties</exists> <missing>${basedir}/file1.properties</missing> </file> </activation> <!-- 扩展属性列表 --> <properties /> <!-- 远程仓库列表 --> <repositories /> <!-- 插件仓库列表 --> <pluginRepositories /> ... </profile> </profiles>
-
-
ActiveProfiles:
-
作用:手动激活
profiles
的列表,按照profile
被应用的顺序定义activeProfile
。该元素包含了一组activeProfile
元素,每个activeProfile都含有一个profile id
。任何在activeProfile
中定义的profile id
,不论环境设置如何,其对应的profile
都会被激活。如果没有匹配的profile
,则什么都不会发生。
例如,env-test
是一个activeProfile
,则在pom.xml
(或者profile.xml
)中对应id
的profile
会被激活。如果运行过程中找不到这样一个profile
,Maven则会像往常一样运行。<activeProfiles> <!-- 要激活的profile id --> <activeProfile>env-test</activeProfile> </activeProfiles>
-
5.2 阿里云镜像
-
镜像:
mirrors
- 作用:加速我们的jar包下载
-
国内建议使用阿里云的镜像
<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
5.3 本地仓库
- 本地仓库:
LocalRepository
- 作用:表示构建系统本地仓库的路径。
- 默认值:
~/.m2/repository
<localRepository>D:\DeveloperTools\Java\Maven\localRepository</localRepository>
5.4 在IDEA中使用Maven
5.4.1 创建MavenWeb
模板项目
5.4.2 在Settings
中配置Maven
注意:经常在IDEA
项目自动创建完成后,Maven的配置经常会发生改变。
5.4.3 Project Struture
中配置源代码目录与资源目录
5.4.4 配置Tomcat
注意:Application context
配置叫虚拟路径映射
5.4.5 IDEA
右侧的Maven
工具栏
5.4.6 使用MavenWeb
模板创建的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>
<!-- Maven的GAV -->
<groupId>net.xjbh</groupId>
<artifactId>MavenWebDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 项目打包方式:jar:Java应用;war:JavaWeb应用 -->
<packaging>war</packaging>
<!-- 配置 -->
<properties>
<!-- 项目的默认构建编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 编码版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- 项目依赖 -->
<dependencies>
<!-- 具体依赖的jar包配置信息 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 项目构建配置 -->
<build>
<finalName>MavenWebDemo</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>
5.4.7 Maven
项目的标准目录结构
- src
- main
- java 源文件
- resources 资源文件
- filters 资源过滤文件
- config 配置文件
- scripts 脚本文件
- webapp web应用文件
- test
- java 测试源文件
- resources 测试资源文件
- filters 测试资源过滤文件
- it 集成测试
- assembly assembly descriptors
- site Site
- main
- target
- generated-sources
- classes
- generated-test-sources
- test-classes
- xxx.jar
- pom.xml
- LICENSE.txt
- NOTICE.txt
- README.txt
5.4.8 Maven
资源导出失败的问题
构建Maven项目的时候,如果没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件。
src/main/java
和src/test/java
这两个目录中的所有*.java
文件会分别在comile和test-comiple阶段被编译,编译结果分别放到了target/classes
和targe/test-classes
目录中,但是这两个目录中的其他文件都会被忽略掉。
src/main/resouces和src/test/resources
这两个目录中的文件也会分别被复制到target/classes
和target/test-classes
目录中。
target/classes
打包插件默认会把这个目录中的所有内容打入到jar
包或者war
包中。
5.4.8.1 资源文件的配置
资源文件是Java代码中要使用的文件。代码在执行的时候会到指定位置去查找这些文件。前面已经说了Maven默认的处理方式,但是有时候我们需要进行自定义的配置。
有时候有些配置文件通常与.java文件一起放在src/main/java目录(如mybatis或hibernate的表映射文件)。有的时候还希望把其他目录中的资源也复制到classes目录中。这些情况下就需要在Pom.xml文件中修改配置了。
可以有两种方法:
-
一是在
元素下添加 进行配置。 -
另一种是在
的 子元素中配置maven-resources-plugin等处理资源文件的插件。 -
配置
resouces
节点<!--配置build 防止Maven 资源导出失败--> <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>
-
配置资源处理插件
<plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>copy-xmls</id> <phase>process-sources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
另一个插件也能完成相同的功能
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.8</version> <executions> <execution> <id>add-resource</id> <phase>generate-resources</phase> <goals> <goal>add-resource</goal> </goals> <configuration> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>
-
5.4.8.2 打包时文件相关的配置
打包时target/classes
目录中的资源文件会和class
字节码一起被打进jar
包或war
包中。有时候默认的情况不能完全满足需求,如target/classes
目录中的一些文件不希望打入jar
包中,就需要额外配置maven-jar-plugin
插件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<excludes>
<exclude>*.properties</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>xxxxxx.ConsoleLauncher</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
6. Servlet
6.1 Servlet简介
Servlet
就是sun公司开发动态web
的一门技术- sun公司在这些
API
中提供一个接口叫Servlet
,如果想开发一个Servlet程序,只需要完成两个步骤- 编写一个类,实现
Servlet
接口 - 把开发好的
Java
类部署到web
服务器中
- 编写一个类,实现
把实现了Servlet
接口的Java
程序叫做Servlet
6.2 HelloServlet
6.2.1 配置父子工程
父项目的pom.xml
<modules>
<module>servlet-01</module>
</modules>
子项目的pom.xml
<parent>
<artifactId>JavaWebDemo</artifactId>
<groupId>net.xjbh</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
6.2.2 引入Servlet
和JSP
的依赖
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
6.2.3 Maven
环境优化
- 修改
web.xml
为最新 - 将
Maven
的结构搭建完整java
文件夹resources
文件夹
6.2.4 编写Servlet
实现类
package net.xjbh.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "HelloServlet")
public class HelloServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.print("Hello Servlet");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
6.2.5 配置web.xml
的Servlet
映射
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>net.xjbh.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
6.3 Servlet
原理
Servlet
是由web
服务器调用,web
服务器在收到浏览器请求之后,会
6.4 Mapping
映射问题
-
一个
Servlet
可以指定一个映射路径<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping>
-
一个
Servlet
可以指定多个映射路径<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet2</url-pattern> </servlet-mapping>
-
一个
Servlet
可以指定通用映射路径<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet/*</url-pattern> </servlet-mapping>
注意:尽量不要如下写法,优先级比较高且会覆盖首页
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
一个
Servlet
可以指定一些后缀或者前缀<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
注意:*号前不能添加项目路径
-
优先级:固定值 > 通配符
6.5 ServletContext
web
容器在启动的时候,它会为每个web
程序都创建一个对应的ServletContext
对象,它代表了当前的web
应用;当前web
应用的Servlet
都是由同一个ServletContext
对象管理。
-
共享数据:在
Servlet
A中保存了数据,可以在Servlet
B中获取数据Servlet01
package net.xjbh.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 SetContext extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); servletContext.setAttribute("userName", "李向丞"); servletContext.setAttribute("company", "香江百货"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
servlet02
package net.xjbh.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 GetContext extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); String userName = (String) servletContext.getAttribute("userName"); String company = (String) servletContext.getAttribute("company"); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().println("userName -->" + userName); resp.getWriter().println("company -->" + company); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.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-name>setContext</servlet-name> <servlet-class>net.xjbh.servlet.SetContext</servlet-class> </servlet> <servlet-mapping> <servlet-name>setContext</servlet-name> <url-pattern>/setContext</url-pattern> </servlet-mapping> <servlet> <servlet-name>getContext</servlet-name> <servlet-class>net.xjbh.servlet.GetContext</servlet-class> </servlet> <servlet-mapping> <servlet-name>getContext</servlet-name> <url-pattern>/getContext</url-pattern> </servlet-mapping> </web-app>
首先请求
setContext
,然后请求getContext
即可获取数据userName -->李向丞 company -->香江百货
-
转发(页面路径不会发生改变)
Servlet
:package net.xjbh.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 ServletDispatcher extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); servletContext.getRequestDispatcher("/getContext").forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.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-name>setContext</servlet-name> <servlet-class>net.xjbh.servlet.SetContext</servlet-class> </servlet> <servlet-mapping> <servlet-name>setContext</servlet-name> <url-pattern>/setContext</url-pattern> </servlet-mapping> <servlet> <servlet-name>getContext</servlet-name> <servlet-class>net.xjbh.servlet.GetContext</servlet-class> </servlet> <servlet-mapping> <servlet-name>getContext</servlet-name> <url-pattern>/getContext</url-pattern> </servlet-mapping> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>net.xjbh.servlet.ServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/dispatcher</url-pattern> </servlet-mapping> </web-app>
直接请求
dispatcher
,页面会转发到getContext
但路径不会发生改变 -
获取资源文件配置信息
-
在
src/main/java
文件夹下创建配置文件,例如:xml
文件、properties
文件,需要在pom.xml
文件中配置导出信息,否则该类型的文件无法生成到classes
文件夹下;Maven
约定大于配置pom.xml
:<build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude> </excludes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
servlet
:package net.xjbh.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; import java.io.InputStream; import java.util.Properties; public class GetServletProperties extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/oracle.properties"); Properties prop = new Properties(); prop.load(is); String strURL = prop.getProperty("url"); String strDrivers = prop.getProperty("drivers"); String strUserName = prop.getProperty("userName"); String strPassWord = prop.getProperty("passWord"); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().println("URL:" + strURL); resp.getWriter().println("Drivers:" + strDrivers); resp.getWriter().println("UserName:" + strUserName); resp.getWriter().println("PassWord:" + strPassWord); is.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
-
在
src/main/resources
文件下创建配置文件,例如:xml
文件、properties
文件则不需要做任何配置信息servlet
:package net.xjbh.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; import java.io.InputStream; import java.util.Properties; public class GetServletProperties extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/oracle.properties"); Properties prop = new Properties(); prop.load(is); String strURL = prop.getProperty("url"); String strDrivers = prop.getProperty("drivers"); String strUserName = prop.getProperty("userName"); String strPassWord = prop.getProperty("passWord"); resp.setContentType("text/html; charset=utf-8"); resp.getWriter().println("URL:" + strURL); resp.getWriter().println("Drivers:" + strDrivers); resp.getWriter().println("UserName:" + strUserName); resp.getWriter().println("PassWord:" + strPassWord); is.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
-
6.6 HttpServletResponse
6.6.1 如何下载文件
package net.xjbh.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;
public class ServletFileDown extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1 获取下载文件的路径
String strPath = req.getServletContext().getRealPath("\\WEB-INF\\classes\\img\\head.jpg");
// 2 获取下载的文件名
String strFileName = strPath.substring(strPath.lastIndexOf("\\") + 1);
// 3 设置浏览器支持下载的文件配置信息,此段不需要记忆,直接面向百度编程
resp.setContentType("text/html;charset=UTF-8");
// resp.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(strFileName, "UTF-8"));
resp.setHeader("Content-Disposition","attachment; filename=" + new String(strFileName.getBytes("UTF-8"), "UTF-8"));
// 4 获取下载文件的输入流
FileInputStream fis = new FileInputStream(strPath);
// 5 创建缓冲区
int length = 0;
byte[] buffer = new byte[1024];
// 6 获取OutputStream对象
ServletOutputStream sos = resp.getOutputStream();
// 7 将FileOutputStream流写入到缓冲区,使用OutputStream对象将缓冲区的内容输出到客户端
while ((length = fis.read(buffer)) > 0 ) {
sos.write(buffer, 0, length);
}
fis.close();
sos.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
6.6.2 实现重定向
web
资源B收到A的请求后,B会通知A去访问web
资源C,这个过程就叫做重定向。常见的场景:用户登录
void sendRedirect(String var1) throws IOException;
Servlet
:
package net.xjbh.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 ServletRedirect extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("https://www.baidu.com");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
6.7 HttpServletRequest
HttpServletRequest
代表客户端的请求,用户通过HTTP
协议访问服务器,HTTP
请求中的所有信息会被封装到HttpServletRequest
- 获取参数的方法
// 在接口ServletRequest中获取传递参数的四个方法
String getParameter(String var1); // 重点
String[] getParameterValues(String var1); // 重点
Enumeration<String> getParameterNames();
Map<String, String[]> getParameterMap();
-
简单登录
JSP
:<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登陆</title> </head> <body> <div> <form action="${pageContext.request.contextPath}/login" method="post"> <table> <tr> <td>账号:</td> <td><input type="text" name="userName"></td> </tr> <tr> <td>密码:</td> <td><input type="password" name="passWord"></td> </tr> <tr> <td colspan="2"><input type="submit" name="login" value="登陆"></td> </tr> </table> </form> </div> </body> </html>
Servlet
:package com.xjbh.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 LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决参数中文乱码 req.setCharacterEncoding("UTF-8"); String strUserName = req.getParameter("userName"); String strPassWord = req.getParameter("passWord"); System.out.println("============华丽的分割线=========="); System.out.println("UserName:" + strUserName); System.out.println("PassWord:" + strPassWord); System.out.println("============华丽的分割线=========="); resp.setContentType("text/html;charset=UTF-8"); // 请求转发(URL不发生改变,请求转发用相对路径) // req.getRequestDispatcher("/success.jsp").forward(req, resp); // 页面重定向(URL发生改变,页面重定向用绝对路径) resp.sendRedirect(req.getContextPath() + "/success.jsp"); } }
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>loginServlet</servlet-name> <servlet-class>com.xjbh.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>
7. Cookie
与Session
7.1 HTTP
会话
在计算机术语中,会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一个会话过程。会话较多用于网络上,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话。
7.2 保存会话的两种技术
7.2.1 Cookie
客户端技术(请求与相应)
-
常用方法
// 获取Cookie数组 Cookie[] cookies = request.getCookies(); // 创建一个Cookie Cookie cookieLastTime = new Cookie("lastTime", Long.toString(System.currentTimeMillis())); // 获取Cookie中的Key String key = cookie.getName(); // 获取Cookie中的Value String key = cookie.getValue(); // 设置Cookie的有效期 cookie.setMaxAge(24*60*60); // 相应给客户端Cookie response.addCookie(cookieLastTime);
-
细节问题
- 一个
Cookie
只能保存一个信息 - 一个
web
站点可以给浏览器发送多个Cookie
,最多存放20个Cookie
- 浏览器的
Cookie
上限为300个 Cookie
的大小上限为4KB
- 一个
-
删除
Cookie
- 不设置有效期,则关闭浏览器自动失效
- 设置有效期为0
-
例子
package net.xjbh.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 CookieServlet01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决中文乱码 resp.setContentType("text/html;charset=UTF-8"); req.setCharacterEncoding("UTF-8"); // 获取一个打印输出流 PrintWriter pw = resp.getWriter(); // 从Request中获取Cookie的数组 Cookie[] cookies = req.getCookies(); // 便利Cookie数组中是否存在lastTime的Cookie,如果有则获得并打印它的值 if (cookies.length > 0) { for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; if (cookie.getName().equals("lastTime")) { pw.write("您上一次访问本站的时间:" + new Date(Long.parseLong(cookie.getValue())).toLocaleString()); } } } else { pw.write("这是您第一次访问本站"); } // 创建一个Key Value的Cookie Cookie cookieLastTime = new Cookie("lastTime", Long.toString(System.currentTimeMillis())); // 把创建好的Cookie添加到Response中 resp.addCookie(cookieLastTime); pw.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
-
编码与解码
-
编码
URLEncoder.encode("你好,世界!", "UTF-8");
-
解码
URLDecoder.decode("你好,世界!", "UTF-8");
-
7.2.2 *Session
服务端技术,利用这个技术可以保存用户的会话信息
什么是Session
- 服务器会给每一个用户(浏览器)创建一个
Session
对象 - 一个
Session
独占一个浏览器,只要浏览器没有关闭,则Session
就一直存在 - 用户登录之后,整个网站都可以访问
Session
常用方法
// 获得一个Session
HttpSession session = request.getSession();
// 获取Session的ID
String strSessionId = session.getId();
// Session中存入对象
Person setPerson = new Person("迪丽热巴", 18);
session.setAttribute("Person", setPerson);
// 获取Session中的对象
Person getPerson = (Person) session.getAttribute("Person");
// 判断Session是否为新创建
boolean isNew = session.isNew();
// 注销Session
session.invalidate();
Session
自动失效在web.xml
文件中配置
<session-config>
<!-- 以分钟为单位自动失效 -->
<session-timeout>15</session-timeout>
</session-config>
8. JSP
8.1 什么是JSP
JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP
部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML
、XML
或其他格式文档的Web
网页,然后返回给请求者。JSP
技术以Java
语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java
程序共同处理复杂的业务需求。
8.2 JSP
工作原理
-
代码层面没有任何问题
-
服务器内部工作
Tomcat
中有一个work
目录IDEA
中使用Tomcat
的会在IDEA
的Tomcat
中生产一个work
目录 -
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问
Servlet
-
JSP
在运行时会转换为Java
类继承了HttpServlet
,所以JSP
本质就是Servlet
-
JSP
的几个内置对象final javax.servlet.jsp.PageContext pageContext; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null;
8.3 JSP
基础语法
8.3.1 JSP
表达式
语法
<%= 变量或者表达式 %>
举例
<%= new java.util.Date() %>
8.3.2 JSP
脚本片段
语法
<% 脚本片段 %>
举例
<%
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i;
}
out.println(sum);
%>
8.3.3 JSP
申明
语法
<%! 申明片段 %>
举例
<%!
static {
System.out.println("Hello, World!");
}
public void methodInit() {
System.out.println("method Init!");
}
%>
注意:JSP
申明片段生成在Java
类中,而其它则生成在_JspServices
方法中!
8.3.4 JSP
注释
语法
<%-- 注释 --%>
注意:JSP
的注释不会在客户端显示,而HTML
的注释则会在客户端显示!
8.4 九大内置对象及作用域
[PageContext] pageContext
:存储数据[HttpServletRequest] Request
:存储数据[HttpServletResponse] Response
:[HttpSession] Session
:存储数据[ServletContext] Application
:存储数据[ServletConfig] config
:[JspWriter] out
:[Object] page
:几乎不使用,可以不了解[ServletException] exception
:
/*
* 储存的数据只在一个页面中有效
**/
pageContext.setAttribute("Name1", "ArtherLee1");
/*
* 储存的数据只在一个请求中有效,请求转发会携带此数据
* 产生的数据,用户使用完后就没有作用,例如:新闻
**/
Request.setAttribute("Name2", "ArtherLee2");
/*
* 储存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
* 产生的数据,用户使用完后还需要继续使用,例如:购物车
**/
Session.setAttribute("Name3", "ArtherLee3");
/*
* 储存的数据只在服务器中有效,从打开服务器到关闭服务器
* 产生的数据,一个用户使用完后,其它用户还能继续使用,例如:聊天数据
**/
Application.setAttribute("Name4", "ArtherLee4");
8.5 JSP
标签、JSTL
标签、EL
表达式
8.5.1 Maven
项目依赖:
<!-- JSTL 表达式依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard 标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
8.5.2 EL
表达式:
语法如下:
${ }
- 获取数据
- 执行运算
- 获取
web
开发的常用对象 - 调用
Java
方法
8.5.3 JSP
标签
JSP
页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:forward page="jspTag02.jsp">
<jsp:param name="name" value="ArtherLee"/>
<jsp:param name="age" value="18"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
name:<%=request.getParameter("name")%>
<br/>
age:<%=request.getParameter("age")%>
</body>
</html>
8.5.4 JSTL
标签
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
根据JSTL标签所提供的功能,可以将其分为5个类别
-
JSTL
库安装Apache Tomcat
安装JSTL
库步骤如下:从
Apache
的标准标签库中下载的二进包(jakarta-taglibs-standard-current.zip)。- 官方下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
- 本站下载地址:jakarta-taglibs-standard-1.1.2.zip
下载 jakarta-taglibs-standard-1.1.2.zip 包并解压,将 jakarta-taglibs-standard-1.1.2/lib/ 下的两个 jar 文件:
standard.jar
和jstl.jar
文件拷贝到/WEB-INF/lib/
下。将 tld 下的需要引入的 tld 文件复制到
WEB-INF
目录下。接下来我们在
web.xml 文件
中添加以下配置:<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri> <taglib-location>/WEB-INF/fmt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/fmt-rt</taglib-uri> <taglib-location>/WEB-INF/fmt-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri> <taglib-location>/WEB-INF/c.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/core-rt</taglib-uri> <taglib-location>/WEB-INF/c-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/sql</taglib-uri> <taglib-location>/WEB-INF/sql.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/sql-rt</taglib-uri> <taglib-location>/WEB-INF/sql-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/x</taglib-uri> <taglib-location>/WEB-INF/x.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/x-rt</taglib-uri> <taglib-location>/WEB-INF/x-rt.tld</taglib-location> </taglib> </jsp-config> </web-app>
-
核心标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
格式化标签
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
-
SQL 标签
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
-
XML 标签
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
-
JSTL 函数
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
9. JavaBean
9.1 JavaBean
有特定的写法:一般用来和数据库的字段做映射
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的
GET
/SET
方法
9.2 ORM(Object Relational Mapping)
对象关系映射
- 数据库表名 --> 类名
- 表字段 --> 类属性
- 表行记录 --> 对象
假设在数据库中有一张Person表,表结构如下:
id | name | age |
---|---|---|
1 | 迪丽热巴 | 18 |
2 | 古力娜扎 | 20 |
3 | 马尔扎哈 | 1000 |
生成的对应JavaBean
public class Person {
private int id;
private String name;
private int age;
public Person() {
}
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
10. MVC
三层架构
10.1 MVC
三层架构介绍:
-
Model
模型:为用户提供使用界面,与用户直接进行交互- 数据承载
Bean
:实体类,专门用户承载业务数据的,如Student
、User
等 - 业务处理
Bean
:指Service
或Dao
对象,专门用于处理用户提交请求
- 数据承载
-
View
视图:承载数据,并对用户提交请求进行计算的模块 -
Controller
控制器:用于将用户请求转发给相应的Model
进行处理,并根据Model
的计算结果向用户提供相应响应
10.2 MVC
架构程序的工作流程
10.2.1 用户通过View
页面向服务端提出请求,可以是表单请求、超链接请求、AJAX
请求等
10.2.2 服务端Controller
控制器接收到请求后对请求进行解析,找到相应的Model
对用户请求进行处理
10.2.3 Model
处理后,将处理结果再交给Controller
10.2.4 Controller
在接到处理结果后,根据处理结果找到要作为向客户端发回的响应View
页面。页面经渲染(数据填充)后,再发送给客户端
10.3 MVC
与三层架构的关系
11. Filter
过滤器
Filter
:过滤器能够对目标资源的请求和响应进行截取。
11.1 Filter
过滤器开发步骤
11.1.1 导包
<dependencies>
<!-- JSTL 表达式依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard 标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- JSP 依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<!-- Servlet 依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
11.1.2 编写过滤器
编写一个Java
类实现javax.servlet.Filter
接口
package com.artherlee.filter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CharcterEncodingFilter implements Filter {
/**
* 销毁,web服务器在停止的时候会做销毁处理
*/
public void destroy() {
System.out.println("CharcterEncodingFilter销毁...");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 让我们的请求继续往下执行,如果不写,程序到这里就将被拦截停止
chain.doFilter(req, resp);
}
/**
* 初始化,web服务器在启动的时候会做初始化
* @param config
* @throws ServletException
*/
public void init(FilterConfig config) throws ServletException {
System.out.println("CharcterEncodingFilter初始化...");
}
}
11.1.3 配置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">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.artherlee.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlets/HelloServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharcterEncodingFilter</filter-name>
<filter-class>com.artherlee.filter.CharcterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharcterEncodingFilter</filter-name>
<url-pattern>/servlets/*</url-pattern>
</filter-mapping>
</web-app>
11.1.4 编写servlet
package com.artherlee.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 HelloServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("你好,世界!");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
11.2 Filter
权限拦截实例
要求:用户登录之后才能访问主页,用户注销后则不能访问;
用
JSP
+Servlet
+Filter
实现;
-
JSP
页面Login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登陆</title> </head> <body> <form action="/servlet/LoginServlet" method="POST"> 用户名:<input type="text" name="userName"> <br/> <input type="radio" name="vip" value="VIP1" checked="checked">VIP1 <input type="radio" name="vip" value="VIP2">VIP2 <input type="radio" name="vip" VALUE="VIP3">VIP3 <br/> <input type="submit" value="登陆"> </form> </body> </html>
/system/Index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>主页</title> </head> <body> <h1>${sessionScope.SESSION_USER.userName},欢迎来到主页,您当前的VIP级别为:${sessionScope.SESSION_USER.vipLevel}</h1> <h3><a href="/servlet/LogoutServlet">注销用户</a></h3> </body> </html>
/error/ErrorPage500.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>错误500</title> </head> <body> <h1>当前用户不存在或者没有权限访问</h1> <h3><a href="/servlet/LogoutServlet">返回登陆页面</a></h3> </body> </html>
-
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"> <!-- 配置Servlet以及映射 --> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.artherlee.servlet.login.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/servlet/LoginServlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>LogoutServlet</servlet-name> <servlet-class>com.artherlee.servlet.login.LogoutServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LogoutServlet</servlet-name> <url-pattern>/servlet/LogoutServlet</url-pattern> </servlet-mapping> <!-- 配置Filter以及映射 --> <filter> <filter-name>CharcterEncodingFilter</filter-name> <filter-class>com.artherlee.filter.CharcterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharcterEncodingFilter</filter-name> <url-pattern>/</url-pattern> </filter-mapping> <filter> <filter-name>LoginFilter</filter-name> <filter-class>com.artherlee.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/system/*</url-pattern> </filter-mapping> </web-app>
-
pom.xml
页面<?xml version="1.0" encoding="UTF-8"?> <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> <groupId>org.example</groupId> <artifactId>RuleFilterTest</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- JSTL 表达式依赖 --> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <!-- standard 标签库 --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!-- JSP 依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> </dependency> <!-- Servlet 依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> </dependencies> </project>
-
Java
类User
实体类package com.artherlee.entity; public class User { private String userName; private VipLevel vipLevel; public User() { } public User(String userName, VipLevel vipLevel) { this.userName = userName; this.vipLevel = vipLevel; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public VipLevel getVipLevel() { return vipLevel; } public void setVipLevel(VipLevel vipLevel) { this.vipLevel = vipLevel; } @Override public String toString() { return "Users{" + "userName='" + userName + '\'' + ", vipLevel=" + vipLevel + '}'; } }
VipLevel
枚举类package com.artherlee.entity; public enum VipLevel { VIP1, VIP2, VIP3 }
util
工具类package com.artherlee.util; public class Constant { public static final String SESSION_USER = "SESSION_USER"; }
-
Servlet
类LoginServlet
登陆package com.artherlee.servlet.login; import com.artherlee.entity.User; import com.artherlee.entity.VipLevel; import com.artherlee.util.Constant; 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 LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String userName = req.getParameter("userName"); String vip = req.getParameter("vip"); if (userName.equals("admin")) { User user = new User(); user.setUserName(userName); if (vip.equals("VIP1")) { user.setVipLevel(VipLevel.VIP1); } else if (vip.equals("VIP2")) { user.setVipLevel(VipLevel.VIP2); } else if (vip.equals("VIP3")) { user.setVipLevel(VipLevel.VIP3); } req.getSession().setAttribute(Constant.SESSION_USER, user); resp.sendRedirect("/system/Index.jsp"); } else { resp.sendRedirect("/error/ErrorPage500.jsp"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
LogoutServlet
登出package com.artherlee.servlet.login; import com.artherlee.entity.User; import com.artherlee.util.Constant; 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 LogoutServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { User user = (User) req.getSession().getAttribute(Constant.SESSION_USER); if (user == null) { resp.sendRedirect("/error/ErrorPage500.jsp"); } else { req.getSession().removeAttribute(Constant.SESSION_USER); resp.sendRedirect("/Login.jsp"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
-
Filter
过滤器类CharcterEncodingFilter
字符编码过滤器package com.artherlee.filter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; public class CharcterEncodingFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("UTF-8"); servletResponse.setContentType("text/html;charset=UTF-8"); filterChain.doFilter(servletRequest, servletResponse); } public void destroy() { } }
LoginFilter
登陆过滤器package com.artherlee.filter; import com.artherlee.util.Constant; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class LoginFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; if (req.getSession().getAttribute(Constant.SESSION_USER) == null) { resp.sendRedirect("/error/ErrorPage500.jsp"); } filterChain.doFilter(req, resp); } public void destroy() { } }
本文来自博客园,作者:爱Ni说不出口,转载请注明原文链接:https://www.cnblogs.com/ArtherLee/p/15538652.html