JavaWeb
JavaWeb
Java Web
1.基本概念
1.1 前言
web开发:
-
web,网页的意思
-
静态web
- html,css
- 提供给所有人看的数据始终不会发生变化
-
动态web
-
淘宝等,几乎是所有的网站
-
提供给所有人看的数据会发生变化,每个人在不同的事件,不同的地点看到的信息各不相同
-
技术栈:Servlet/JSP,ASP,PHP
-
在Java中,动态web资源开发的技术统称为JavaWeb
1.2 web应用程序
web应用程序:可以提供浏览器访问的程序
- a.html、b.html.....多个web资源,这些web资源可以被外界访问,对外界提供服务;
- 能访问到的任何一个页面或者资源,都存在于某个计算机上
- URL
- 这个统一的web资源会被放在同一个文件夹下,web应用程序->Tomcat:服务器
- 一个web应用由多部分组成(静态web、动态web)
- HTML,CSS,JavaScript
- JSP,Servlet
- Java程序
- jar包
- 配置文件(Properties)
Web应用程序编写完毕后,若想提供给外界访问,需要一个服务器来统一管理;
1.3 静态web
- *.htm, *.html这些都是网页的后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取(需要网络);

静态web存在的缺点:
-
web页面无法更新,所有用户看到的都是同一个页面
-
轮播图,点击特效:伪动态
-
JavaScript(实际开发中,用得最多)
-
VBScript
-
-
无法和数据库交互(数据无法持久化,用户无法交互)
-
1.4 动态Web
页面会动态展示,web页面的展示效果因人而异

缺点:
- 假如服务器的动态web资源出现了错误,需要重新编写后台程序,重新发布;
- 停机维护
优点:
- web页面可以动态更新,所有用户看到的都不是同一个页面
- 可以与数据库交互(数据持久化:注册,商品信息,用户信息......)

2.web服务器
2.1 技术讲解
ASP:
- 微软:国内最早流行的就是ASP
- 在HTML中嵌入了VB的脚本,ASP+COM
- 在ASP开发中,基本一个页面有几千行业务代码,页面极其混乱
- 维护成本高
- 在ASP中主要用到C#语言
- 控制面板卸载程序中启用或者关闭Windows功能中IIS:Internet Information Service可承载的Web核心,勾选之后可进行IIS开发
PHP:
- PHP开发速度很快,功能很强大,跨平台,代码很简单(70%网站都是中小型,WP)
- 无法承载大访问量的情况(局限性)
JSP/Servlet:
B/S:浏览器/服务器 C/S:客户端/服务器
- sun公司主推的B/S架构
- 基于Java语言的(所有的大公司或者一些开源的组件都是用Java写的)
- 可以承载三高问题带来的影响:高并发、高可用、高性能
- 语法像ASP,ASP->JSP,加强市场强度
2.2 web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息;
IIS:微软的;运行一些ASP程序,Windows中自带
Tomcat:
Tomcat是Apache 软件基金会(Apache Software Foundation)的jakarta项目中的一个核心项目,最新的Servlet 和JSP 规范总是能在Tomcat中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受lava爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。对于一个Java初学web的人来说,它是最佳的选择
Tomcat 实际上运行JSP页面和Serlet。
工作3-5年之后,可以尝试手写Tomcat服务器;
下载tomcat:
1.安装or解压
2.了解配置文件及目录结构
3.这个东西的作用
3.Tomcat
3.1 安装tomcat

下载后解压
3.2 Tomcat启动和配置
文件夹作用:

启动和关闭Tomcat:
启动:进入bin文件夹->点击startup.bat
关闭:进入bin文件夹->点击shutdown.bat

可能遇到的问题:
- Java环境变量没有配置
- 闪退问题:需要配置兼容性
- 乱码问题:配置文件中设置
可以修改 conf/logging.properties 中的 java.util.logging.ConsoleHandler.encoding = GBK 解决乱码问题
3.3 配置

tomcat->server.xml文件中:
- 可以配置启动的端口号:port="8081"
- tomcat的默认端口号为:8080
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
- mysql默认端口号:3306
- http默认端口号:80
- https默认端口号:443
- 可以配置主机的名称:name="www.lin.com"
默认的主机名为localhost
磨人的网站应用存放位置为:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
修改名称后需要修改C:\Windows\System32\drivers\etc\hosts配置文件中的域名映射
127.0.0.1 www.lin.com才可以访问
其中appBase参数对应放网站的目录
高难度面试题:
请你谈谈网站是如何进行访问的?
-
输入一个域名;回车
-
检查本机的C:\Windows\System32\drivers\etc\hosts配置文件中有没有这个域名映射;
- 有:直接返回对应的ip地址,可以直接访问
- 没有:去DNS服务器找,找到就返回,找不到就返回找不到

可以为tomcat配置一个环境变量,方便随时启动
3.4 发布一个web网站
http://localhost:8080/docs/:文档
http://localhost:8080/examples/:示例
将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了 ——例:将自己的index.html放入webapps下的javastudy文件夹中,这样输入http://localhost:8080/javastudy/就可以访问到自己的页面
网站文件夹结构
webapps:Tomcat服务器的web目录
javastudy:网站的目录名
WEB-INF:
classes:java程序
lib:web应用所依赖的jar包
web.xml:网站配置文件
index.html(jsp):默认的首页
static:
css
style.css
js
img
.....
4.Http
4.1 什么是http
(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上
https:s代表安全的
4.2 http的两个时代
- HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
- HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源
4.3 http请求
客户端向服务器发起请求
以访问百度为例
General
Request URL:https://www.baidu.com/ -- 请求地址
Request Method:GET -- get方法/post方法
Status Code:200 OK -- 状态码 200 3 5 4
Remote Address:182.61.200.7:443 -- 远程地址:端口
请求标头:Request Headers
Accept: text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
- 请求行General
请求行中的请求方式:GET
请求方式:GET,POST,HEAD,DELETE,PUT,TRACT.....
-
GET:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但是高效
-
POST:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效
- 消息头Request Headers
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK/UTF-8/GB2312/ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机
....
4.4 http响应
服务器给客户端响应
以访问百度为例
Cache-Control:private 缓存控制
Connection: keep-alive 连接:保持连接
Content-Encoding: gzip 编码:
Content-Type: text/html; charset=utf-8 类型
- 响应体Response Hesders
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式 GBK/UTF-8/GB2312/ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位
响应状态码
200:请求响应成功200
3xx:请求重定向>>>重定向的意思:你重新到我给你的新位置去;
4xx:找不到资源>>>404:资源不存在;
5xx:服务器代码错误 >>>500:服务器内部错误,无法完成请求;502:网关错误
5.Maven
为什么要学习Maven?
- 在Javaweb开发中,需要使用大量的jar包,需要手动导入;
- 如何能够使用工具自动导入和配置jar包?
因此,Maven诞生了!
5.1 Maven项目架构管理工具
我们目前用来方便导入jar包
Maven的核心思想:约定大于配置
意思就是有约束,不要去违反
Maven会规定如何去编写java代码(目录结构),必须要按照规范
5.2 下载安装Maven
https://archive.apache.org/dist/maven/maven-3/
下载后解压即可
- 在环境变量中添加MAVEN_HOME:maven目录

- 在Path中配置MAVEN_HOME:

测试maven是否安装配置成功

- 配置maven本地仓库
进入conf文件夹,打开settings.xml配置文件
找到节点localRepository,在注释外添加<localRepository>标签
在<localRepository>标签中设置本地仓库地址
<!-- 配置Maven本地仓库 -->
<localRepository>D:\maven\apache-maven-3.9.1\maven-repo</localRepository>
- maven配置阿里云镜像仓库地址
进入maven文件夹下的conf文件夹,打开settings.xml配置文件
在<mirrors> </mirrors>标签中添加阿里云镜像:
<!-- mirror 阿里云加速仓库镜像-->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
- 修改maven默认的JDK版本
在·<profiles>标签下添加一个<profile>标签,修改maven默认的JDK版本。
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
整个settings.xml文件内容为
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
| This is the configuration file for Maven. It can be specified at two levels:
|
| 1. User Level. This settings.xml file provides configuration for a single user,
| and is normally provided in ${user.home}/.m2/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -s /path/to/user/settings.xml
|
| 2. Global Level. This settings.xml file provides configuration for all Maven
| users on a machine (assuming they're all using the same Maven
| installation). It's normally provided in
| ${maven.conf}/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -gs /path/to/global/settings.xml
|
| The sections in this sample file are intended to give you a running start at
| getting the most out of your Maven installation. Where appropriate, the default
| values (values used when the setting is not specified) are provided.
|
|-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<!-- 配置Maven本地仓库 -->
<localRepository>D:\maven\apache-maven-3.6.1\maven-repo</localRepository>
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If set to false,
| maven will use a sensible default value, perhaps based on some other setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
<!-- offline
| Determines whether maven should attempt to connect to the network when executing a build.
| This will have an effect on artifact downloads, artifact deployment, and others.
|
| Default: false
<offline>false</offline>
-->
<!-- pluginGroups
| This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
| when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
| "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
|-->
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
</pluginGroups>
<!-- proxies
| This is a list of proxies which can be used on this machine to connect to the network.
| Unless otherwise specified (by system property or command-line switch), the first proxy
| specification in this list marked as active will be used.
|-->
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
<!-- servers
| This is a list of authentication profiles, keyed by the server-id used within the system.
| Authentication profiles can be used whenever maven must make a connection to a remote server.
|-->
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving certain artifacts.
| However, this repository may have problems with heavy traffic at times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a mirror reference for that
| repository, to be used as an alternate download site. The mirror site will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<!-- mirror 阿里云加速仓库镜像-->
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>https://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
<!-- profiles
| This is a list of profiles which can be activated in a variety of ways, and which can modify
| the build process. Profiles provided in the settings.xml are intended to provide local machine-
| specific paths and repository locations which allow the build to work in the local environment.
|
| For example, if you have an integration testing plugin - like cactus - that needs to know where
| your Tomcat instance is installed, you can provide a variable here such that the variable is
| dereferenced during the build process to configure the cactus plugin.
|
| As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
| section of this document (settings.xml) - will be discussed later. Another way essentially
| relies on the detection of a system property, either matching a particular value for the property,
| or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
| value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
| Finally, the list of active profiles can be specified directly from the command line.
|
| NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
| repositories, plugin repositories, and free-form properties to be used as configuration
| variables for plugins in the POM.
|
|-->
<profiles>
<!-- profile
| Specifies a set of introductions to the build process, to be activated using one or more of the
| mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
| or the command line, profiles have to have an ID that is unique.
|
| An encouraged best practice for profile identification is to use a consistent naming convention
| for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
| This will make it more intuitive to understand what the set of introduced profiles is attempting
| to accomplish, particularly when you only have a list of profile id's for debug.
|
| This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
-->
<!--
| Here is another profile, activated by the system property 'target-env' with a value of 'dev',
| which provides a specific path to the Tomcat instance. To use this, your plugin configuration
| might hypothetically look like:
|
| ...
| <plugin>
| <groupId>org.myco.myplugins</groupId>
| <artifactId>myplugin</artifactId>
|
| <configuration>
| <tomcatLocation>${tomcatPath}</tomcatLocation>
| </configuration>
| </plugin>
| ...
|
| NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
| anything, you could just leave off the <value/> inside the activation-property.
|
<profile>
<id>env-dev</id>
<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>
<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>
-->
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
<!-- activeProfiles
| List of profiles that are active for all builds.
|
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
</settings>
5.3 在IDEA中使用Maven
1.创建mavenweb项目(使用模板)




3.等待项目初始化完毕,自动导入包

maven设置的本地仓库文件夹会自动导入一些jar包
4.IDEA中的Maven设置
IDEA项目创建成功后,看一眼maven的配置
file->setting打开设置窗口


IDEA创建maven项目时报错 Dependency 'junit:junit:4.12' not found

5.到这里,Maven 在 IDEA 中的配置和使用就 OK 了!
5.4 创建普通的Maven项目



这个文件夹只有在web应用下才会有

5.5 在IDEA中标记文件夹功能

其他方法


5.6 在IDEA中配置Tomcat
点击add configuration按钮

打开Run/Debug Configurations窗口

选择本地tomcat下local选项



点击启动tomcat


解决tomcat配置中的警告Warning: No artifacts configured
一:点击fix

选择war

二:点击 File ,弹出框里选择Project Structure… ,打开窗口左侧选择Artifacts,点击左上角的+,打开框里选择Web Application :Exploded点击Empty



点击ok即可
5.7 pom文件
pom.xml是maven的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--Maaven的版本和头文件-->
<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.lin</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!--Packet:项目的打包方式
jar:java应用
war:Javaweb应用
-->
<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.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>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>

Maven 由于约定大于配置特性,之后可会能遇到我们写的配置文件无法被导出或者生效的问题,解决方案:
<!--在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>
5.8 IDEA查看依赖树

maven中jar包的联系关联图

5.9 解决遇到的问题
1.IDEA中每次都要重复配置Maven
在IDEA中的全局默认配置中去配置


2.Maven 默认 Web 项目中的 web.xml 版本问题

替换为webapp4.0版本(与tomcat一致)
<?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>
3.Maven仓库的使用
地址:https://mvnrepository.com/tags/maven
在tomcat下的lib目录中有很多jar包--->可以大致查找jar包名字
搜索后用使用最多的版本
6.Servlet
6.1 Servlet简介
- Servlet就是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做:Servlet,如果想开发一个Servlet程序,只需要完成两个小步骤:
- 编写一个类,实现Servlet接口
- 把开发好java类部署到web服务器中。
把实现了Servlet接口的Java程序叫做,Servlet
6.2、HelloServlet
Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet
1.构建一个普通的maven项目,删掉里面的src目录,以后我们的学习就在这里建立Module,这个空的工程就是maven的主工程
2.在主工程下新建一个module
右击项目,点击new->Module



关于Maven中父工程和子工程的理解
- 父项目中会多出Module标签
<modules>
<module>servlet-01</module>
</modules>
- 子项目中会出现parent标签
<parent>
<artifactId>javaweb-02-servlet</artifactId>
<groupId>com.lin</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的jar包子项目可以直接使用(类似于java中的继承)
- 将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>
在main文件夹下新建java和resources文件夹,并设置为相应标记
4.编写一个Servlet程序
新建一个java普通类,实现Servlet接口(可以直接继承HttpServlet)


package com.lin.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
//由于GET或者POST只是实现请求的不同方式,可以相互调用,因为业务逻辑都一样;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
5.编写Servlet的映射
为什么需要映射?写的JAVA程序需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册自己写的Servlet,还需要给她一个浏览器能够访问的路径
在web.xml文件中加上一下映射
<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.lin.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
6.配置tomcat
7.启动测试
6.3 Servlet原理
Servlet 是由 Web 服务器调用,Web 服务器在收到浏览器请求之后,会

6.4 Mapping问题
一个Servlet请求可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
一个Servlet请求可以指定多个映射请求
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</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>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
一个Servlet请求可以制定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
默认请求路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
指定一些后缀或者前缀等等.......
<!--*前面不能加项目映射路径/-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.dosmt</url-pattern><!--后缀为.dosmt-->
</servlet-mapping>
注意:优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.lin.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
6.5 ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext,它代表了当前的web应用
6.5.1 共享数据
在一个Servlet中保存的数据,可以在另外一个Servlet中拿到
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 context = this.getServletContext();
String username = "秦疆";//数据
context.setAttribute("username",username);//将一个数据保存在了ServletContext中,名字为:username,值:username
System.out.println("Hello");
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username =(String) context.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 {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.lin.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.lin.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
测试访问结果
6.5.2 获取初始化参数
web.xml中
<!--配置一些web应用的初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
6.5.3 请求转发
转发过程中路径不会改变
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
requestDispatcher.forward(req,resp);//调用forward方法实现请求转发
System.out.println("进入sd4");
}
6.5.4 读取资源文件
Properties
- 在 java 目录下新建 properties
- 在 resources 目录下新建 properties
发现:都被打包到了target同一个路径下:classes,我们俗称这个路径为classpath。
思路:需要一个文件流;
db.properties文件
username=root
password=123456
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
6.6 HttpServletResponse
Web 服务器接收到客户端的 http 请求,针对这个请求创建一个代表请求的 HttpServletRequest 对象,和代表响应的一个 HttpServletResponse;
- 如果想要获取客户端请求过来的参数:找 HttpServletRequest
- 如果要获取服务器给客户端响应的信息:找 HttpServletResponse
1.简单分类
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;//写中文
负责向浏览器发送响应头的方法
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);
响应的状态码
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;
2.下载文件
1.向浏览器输出消息(getWriter、getOutputStream)
2.下载文件
1.获取下载文件的路径
2.下载的文件名
3.设置浏览器能够支持下载需要的东西
4.获取下载文件的输入流
5.创建缓冲区
6.获取OutputStream对象
7.将FileOutputStream流写入到缓冲区
8.使用OutputStream将缓冲区的数据输出到客户端
package com.lin.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 = "D:\\Javaworkspace\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg";
System.out.println("下载文件的路径:"+realPath);
//2.下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3.设置浏览器能够支持(Content-Disposition)下载需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//4.获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5.创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//6.获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7.将FileOutputStream流写入到缓冲区,使用OutputStream将缓冲区的数据输出到客户端
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.验证码功能
验证码怎么来的?
- 前端实现
- 后端实现。需要用到java的图片类,生成一个图片
package com.lin.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 {
//如何让浏览器5s自动刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D)image.getGraphics();//笔
//设置图片的背景颜色
g.setColor(Color.PINK);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999)+"";
StringBuffer stringBuffer = new StringBuffer();
//保证生成随机数是七位,<7位用0填充
for (int i = 0; i < 7-num.length(); i++) {
stringBuffer.append("0");
}
num = stringBuffer.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.实现重定向

Web 资源 B 收到客户端 A 请求后,通知 A 访问另一个 Web 资源 C ,这个过程叫做重定向
常见场景:用户登录
void sendRedirect(String var1) throws IOException;//重定向方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/resp/image");
}
简单实现登录重定向
index.jsp
<html>
<body>
<h2>Hello World!</h2>
<%@ page contentType="text/html;charset=UTF-8"%>
<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<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>
RequestTest.java
package com.lin.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("/resp/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
重定向页面success.jsp(放在webapp文件夹下)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
web.xml配置
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.lin.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
pom.xml中依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</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>
</dependencies>
6.7 HttpServletRequest
HttpServletRequest 代表客户端的请求,用户通过 HTTP 协议访问服务器,HTTP 请求中的所有信息会被封装到 HttpServletRequest ,通过这个HttpServletRequest 的方法,获得客户端的所有信息;


获取参数,请求转发

package com.lin.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 {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//后台接收中文乱码问题
req.setCharacterEncoding("utf-8");
String user = req.getParameter("user");
String pwd = req.getParameter("pwd");
String[] hobbies = req.getParameterValues("hobbies");
System.out.println(user);
System.out.println(pwd);
System.out.println(Arrays.toString(hobbies));
//resp.sendRedirect("/req/success.jsp");//重定向
//通过请求转发
//转发是在服务器内部,不需要写项目路径
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
7.Cookie、Session
7.1 会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,称之为有状态会话。
一个网站,怎么证明你来过?
客户端 服务端
1.服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie
2.服务器登记你来过了,下次你来的时候我来匹配你; seesion
7.2 保存会话的两种技术
-
cookie:客户端技术(响应、请求)
-
session:服务器技术,利用这个技术可以保存用户的会话信息;我们可以把会话的信息放在session中
常见场景:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!
7.3 Cookie

使用cookie案例
package com.lin.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 {
//服务器告诉你,你来的时间,把这个时间封装成为一个信件,你下次带来,我就知道你来了
//解决中文乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
//cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies!=null){
//如果存在怎么办
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取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()+"");
//cookie有效期为1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 从请求中拿到 cookie 信息
- 服务器响应给客户端 cookie
Cookie[] cookies = req.getCookies();//获得Cookie
cookie.getName();//获得Cookie中的key
cookie.getValue();//获得Cookie中的value
Cookie cookie = 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实例
package com.lin.servlet;
import com.lin.pojo.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");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("张三",18));
//获取Session的ID
String sessionId = session.getId();
//判断session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功,session的ID为:"+sessionId);
}else{
resp.getWriter().write("session已经在服务器中存在了,session的ID为:"+sessionId);
}
//Session创建的时候做了什么事情:
//Cookie cookie = new Cookie("JSESSIONID", sessionId);
//resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//得到Session
HttpSession session = req.getSession();
//得到session中的属性
Person person = (Person)session.getAttribute("name");
System.out.println(person.toString());
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
在web.xml中设置session自动过期
<!--设置session默认的失效时间-->
<session-config>
<!--15分钟后session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>

8.JSP
8.1 什么是JSP
Java Server Pages:Java服务器端页面,和Servlet一样用于动态Web技术!
最大的特点:写JSP就像在写HTML
区别:
- HTML只给用户提供静态的数据
- JSP 页面中可以嵌入Java 代码,为用户提供动态数据;
8.2 JSP原理
代码中target目录下的生成index.jsp和main的jsp没有区别
服务器内部工作:
tomcat中有一个work目录,在IDEA中使用Tomcat会在IDEA的tomcat中生成一个work目录

电脑地址
C:\Users\dell\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat\e2f26b44-9e71-4675-8728-a826beeda95f\work\Catalina\localhost\cookiedemo\org\apache\jsp
加粗部分为一个项目的临时文件夹,每个项目不同
idea中tomcat工作空间下页面转变成了java程序!

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终会被转换成为一个Java类!
导入jasper-runtime的jar包才会有HttpJspDase
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
1.判断请求
2.创建内置对象
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null;//session
final javax.servlet.ServletContext application;//applicationContext
final javax.servlet.ServletConfig config;//config
javax.servlet.jsp.JspWriter out = null;//out
final java.lang.Object page = this;//page:当前页
HttpServletRequest request//请求
HttpServletResponse response//响应
3.输出页面前增加的代码
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;
4.以上的这些对象,可以在JSP页面中直接使用
}

在JSP页面中;
只要是 JAVA代码就会原封不动的输出;
如果是HTML代码,就会被转换为:
out.write("<html>\r\n");
8.3 JSP基础语法
pom.xml导入依赖
<dependencies>
<!--Servlet依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--JSP依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!--JSTL表达式依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard标签库-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
任何语言都有自己的语法,java中有,JSP作为java技术的一种应用,拥有一些自己扩充的语法(了解,知道)
Java所有语法都支持
JSP表达式
<%--JSP表达式
作用:将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
JSP脚本片段
<%--jsp脚本片段--%>
<%
int sum=0;
for (int i = 1; i < 100; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
%>
脚本片段的再实现
<%
int x=10;
out.println(x);
%>
<p>这是一个JSP文档</p>
<%
int y=20;
out.println(y);
%>
<hr>
<%--在代码中嵌入html元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>hello,world <%= i%> </h1>
<%
}
%>
JSP声明
<%!
static{
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void hello(){
System.out.println("进入了方法Hello!");
}
%>
JSP声明:会被编译到JSP生成Java的类中!其他jsp代码,就会被生成到_jspService方法中!
在JSP,嵌入Java代码即可!
<%= %>可以用${}表示,后者叫做EL表达式
<%= %>表达式
<% %>片段
<%! %>声明
<%--注释--%>
<!-- -->html注释形式
JSP的注释,不会在客户端显示,HTML就会!
8.4 JSP指令
可能会遇到图片没有被导出,导致图片无法显示的问题,需要在pom.xml文件中加入如下内容:
<!--在build中配置resources,来防止资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>web/image</directory>
<includes>
<include>**/*.png</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<%--在想要配置错误页面的jsp中加上page errorPage--%>
<%--定制错误页面--%>
<%@ 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>
<%--显式地声明jsp为错误页面--%>
<%@ page isErrorPage="true" %>
指令语法
<%@page args.... %>
<%@include file=""%>
<%--@include会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
<hr>
<%--jSP标签
jsp:include:拼接页面,本质还是三个
--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>
8.5 九大内置对象
- HttpServletRequest request //存东西
- HttpServletResponse response
- PageContext pageContext //存东西
- HttpSession session //存东西
- ServletContext application //存东西
- ServletConfig config
- JspWriter out
- page
- exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
pageContext.setAttribute("name1","一号");//保存的数据只在一个页面中有效
request.setAttribute("name2","二号");//保存的数据只在一次请求中有效,请求转发会携带数据
session.setAttribute("name3","三号");//保存的数据在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","四号");//保存的数据在服务器中有效,从打开服务器到关闭服务器
pageContext.setAttribute("hello","hello",PageContext.SESSION_SCOPE);
session.setAttribute("hello","hello");
%>
<%--通过pageContext取出保存的值,通过寻找的方式--%>
<%
//从底层到高层寻找(作用域):pageContext->request->session->application
//类似于JVM:双亲委派机制
String name1 = (String)pageContext.findAttribute("name1");
String name2 = (String)pageContext.findAttribute("name2");
String name3 = (String)pageContext.findAttribute("name3");
String name4 = (String)pageContext.findAttribute("name4");
String name5 = (String)pageContext.findAttribute("name5");//不存在
%>
<%--使用EL表达式输出,${}--%>
<h1>取出的值为</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<h3><%=name5%></h3>
</body>
</html>
pageContext中setAttribute(三个参数)源码分析:
//scope作用域
public void setAttribute(String name, Object attribute, int scope) {
switch(scope) {
case 1:
this.mPage.put(name, attribute);
break;
case 2:
this.mRequest.put(name, attribute);
break;
case 3:
this.mSession.put(name, attribute);
break;
case 4:
this.mApp.put(name, attribute);
break;
default:
throw new IllegalArgumentException("Bad scope " + scope);
}
}
PageContext类中有四大作用域:
public static final int PAGE_SCOPE = 1;
public static final int REQUEST_SCOPE = 2;
public static final int SESSION_SCOPE = 3;
public static final int APPLICATION_SCOPE = 4;
<%--这两句话等效,可以用PageContext指定作用域--%>
<%
pageContext.setAttribute("hello","hello",PageContext.SESSION_SCOPE);
session.setAttribute("hello","hello");
%>
<%--jsp中转发写法--%>
<%
pageContext.forward("/index.jsp");
%>
//Servlet中转发写法
requset.getRequestDispatcher().forward(request,response);
一般应用场景:
-
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
-
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;
-
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;
8.6 JSP标签、JSTL标签、EL表达式
使用之前需要在pom.xml中导入JSTL和standard依赖
EL表达式:Expression Language形式为${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
- 调用Java方法(一般不用)
JSP标签
<%--jsp:include--%>
<%--jsp:param转发的时候携带的参数--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="name1" value="value1"/>
<jsp:param name="name2" value="value2"/>
</jsp:forward>
JSTL标签库
JSTL标签库的使用就是为了弥补HTML标签的不足;JSTL自定义了许多标签,可以供我们使用,标签的功能和Java代码一样!
分类:
- 核心标签(掌握)
引入核心标签库的语法如下:
<%--引入核心标签库,才能使用核心标签core--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

-
格式化标签
-
SQL标签
-
XML标签
JSTL标签库使用步骤
- 引入对应的 taglib
- 使用其中的方法
- 在 Tomcat 文件夹的lib中也需要引入 JSTL 的jar包,否则会报错:JSTL 解析错误
<c: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>
<h4>if测试</h4>
<hr>
<form action="coreif.jsp" method="get">
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--判断如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin" >
<c:out value="管理员欢迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>
</body>
</html>
判断登录部分:与上面等价,上面使用JSTL标签实现
<%
if(request.getParameter("username").equals("admin")){
out.print("登陆成功");
}
%>
<c:choose><c:when>
<%--定义一个变量score 值为85--%>
<c:set var="score" value="95"></c:set>
<%--相当于switch--%>
<c:choose>
<c:when test="${score>=90}">
成绩优秀
</c:when>
<c:when test="${score>=80}">
成绩良好
</c:when>
<c:when test="${score>=60}">
成绩及格
</c:when>
</c:choose>
<c:forEach>
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
people.add(4,"孙七");
request.setAttribute("listPeople",people);
%>
<%--var:每次遍历出来的变量
item:要遍历的对象
begin:从哪里开始
end:从哪里结束(左闭右闭区间)
step:步长
--%>
<c:forEach var="human" items="${listPeople}">
<c:out value="${human}"></c:out><br>
</c:forEach>
<hr>
<c:forEach var="human" items="${listPeople}" begin="1" end="3" step="1">
<c:out value="${human}"></c:out><br>
</c:forEach>
9.JavaBean
实体类
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法;
一般用来和数据库的字段做映射 ORM;
ORM :对象关系映射
- 表—>类
- 字段–>属性
- 行记录---->对象
people表
| id | name | age | address |
|---|---|---|---|
| 1 | 1号 | 16 | 北京 |
| 2 | 2号 | 25 | 沈阳 |
| 3 | 3号 | 28 | 杭州 |
class People{
private int id;
private String name;
private int age;
private String address;
}
class A{
new People(1,"1号",16,"北京");
new People(2,"2号",25,"沈阳");
new People(3,"3号",28,"杭州");
}
<jsp:useBean><jsp:setProperty><jsp:getProperty
<%
// People people = new People();
// people.setAddress();
// people.setAge();
// people.setId();
// people.setName();
%>
<jsp:useBean id="people" class="com.lin.pojo.People" scope="page"></jsp:useBean>
<jsp:setProperty name="people" property="address" value="上海"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="张三"/>
<jsp:setProperty name="people" property="age" value="23"/>
姓名:<jsp:getProperty name="people" property="name"/>
id:<jsp:getProperty name="people" property="id"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
10.MVC三层架构
什么是MVC?Model View Controller 模型/视图/控制器
10.1 以前的架构

用户直接访问控制层,控制层可以直接操作数据库
servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
经典加一层例子:
程序猿调用
↑
JDBC (实现该接口)
↑
Mysql Oracle SqlServer ....(不同厂商)
10.2 MVC三层架构

Model
- 业务处理 :业务逻辑(Service)
- 数据持久层:CRUD (Dao - 数据持久化对象)
View
- 展示数据
- 提供链接发起Servlet请求 (a,form,img…)
Controller (Servlet)
-
接收用户的请求 :(req:请求参数、Session信息….)
-
交给业务层处理对应的代码
-
控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库
11.Filter(重点)
Shiro
Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登录验证

Filter开发步骤:
-
导包
-
编写过滤器
- 导包不要导错
![]()
实现Filter接口,重写对应方法即可
package com.lin.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter{
//初始化:web服务器启动就已经初始化,随时等待过滤对象出现
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//过滤器中的所有代码,在过滤特定请求的时候都会执行
//必须要让过滤器继续通行filterChain.doFilter(servletRequest,servletResponse);
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("CharacterEncodingFilter执行前....");
filterChain.doFilter(servletRequest,servletResponse);//让请求继续走,如果不写,程序到这里就被拦截停止了
System.out.println("CharacterEncodingFilter执行后....");
}
//销毁
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
- 在web.xml中配置Filter
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.lin.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!--只要是/servlet的任何请求,都会经过这个过滤器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
12.监听器
实现一个监听器的接口;(有n种监听器)
- 编写一个监听器
实现监听器的接口…
package com.lin.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数:统计session
public class OnlineCountListener implements HttpSessionListener {
//创建session监听,看你的一举一动
//一旦创建Session就会触发一次这个事件
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer)ctx.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount = new Integer(1);
}else{
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁session监听
//一旦销毁session就会触发一次这个事件
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer)ctx.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount = new Integer(0);
}else{
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
/*
Session销毁:
1. 手动销毁 getSession().invalidate();
2. 自动销毁
*/
}
- 在web.xml中注册监听器
<!--注册监听器-->
<listener>
<listener-class>com.lin.listener.OnlineCountListener</listener-class>
</listener>
- 看情况是否使用
jsp中
<h1>当前有 <span><%=request.getServletContext().getAttribute("OnlineCount")%></span> 人在线</h1>
13.过滤器、监听器常见应用
监听器在GUI中的使用:
package com.lin.listener;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame("中秋节快乐"); //新建一个窗体
Panel panel = new Panel(null); //面板
frame.setLayout(null); //设置窗体的布局
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(0,0,255)); //设置背景颜色
panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,0)); //设置背景颜色
frame.add(panel);
frame.setVisible(true);
//监听事件,监听关闭事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
}
});
}
}
用户登陆之后才能进入主页!用户注销之后就不能进入主页了!
- 用户登录之后,向Sesison中放入用户的数据
- 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!
Login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<form action="${pageContext.request.contextPath}/servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
/sys/success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>主页</h1>
<p><a href="${pageContext.request.contextPath}/servlet/logout">注销</a></p>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>错误</h1>
<h3>用户名或者密码错误</h3>
</body>
</html>
LoginServlet.java
package com.lin.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 {
//获取前端请求的参数
String username = req.getParameter("username");
if(username.equals("admin")){//登陆成功
req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
resp.sendRedirect("/filter/sys/success.jsp");
}else{//登陆失败
//使用/filter是在tomcat配置deployment中设置的Appliaction Context
resp.sendRedirect("/filter/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
LogoutServlet.java
package com.lin.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 LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute("USER_SESSION");
if(user_session!=null){
req.getSession().removeAttribute("USER_SESSION");
resp.sendRedirect("/filter/Login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
过滤器文件SysFilter
package com.lin.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if(request.getSession().getAttribute("USER_SESSION")==null){
response.sendRedirect("/filter/error.jsp");
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
web.xml
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.lin.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>com.lin.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.lin.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<!--只要是/sys的任何请求,都会经过这个过滤器-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
14.JDBC复习
需要jar包的支持:
- java.sql
- javax.sql
- mysql-connetor-java… 连接驱动(必须要导入)
实验环境搭建
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','zs@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(2,'李四','123456','ls@qq.com','2000-01-01');
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(3,'王五','123456','ww@qq.com','2000-01-01');
SELECT * FROM users;
导入数据库依赖(pom.xml)
<!--mysql驱动-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
IDEA中连接数据库:

JDBC 固定步骤:
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement : CRUD
- 编写SQL (根据业务,不同的SQL)
- 执行SQL
- 关闭连接(先开的后关)
package com.lin.test;
import java.sql.*;
public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf-8&useSSL=false";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.向数据库发送SQL的对象Statement,PreparedStatement : CRUD
Statement statement = connection.createStatement();
//4.编写SQL
String sql = "select * from users";
//受影响的行数,增删改都是用executeUpdate即可
//int i = statement.executeUpdate(sql);
//5.执行查询SQL,返回一个 ResultSet : 结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
//6.关闭连接,释放资源(一定要做) 先开后关
rs.close();
statement.close();
connection.close();
}
}
预编译SQL
package com.lin.test;
import java.sql.*;
public class TestJdbc2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf-8&useSSL=false";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.编写SQL
String sql = "insert into users(id, name, password, email, birthday) values (?,?,?,?,?);";
//4.预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,4);//给第一个占位符? 的值赋值为1;
preparedStatement.setString(2,"狂神说Java");//给第二个占位符? 的值赋值为狂神说Java;
preparedStatement.setString(3,"123456");//给第三个占位符? 的值赋值为123456;
preparedStatement.setString(4,"24736743@qq.com");//给第四个占位符? 的值赋值为1;
preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));//给第五个占位符? 的值赋值为new Date(new java.util.Date().getTime());
//5.执行SQL
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功@");
}
//6.关闭连接,释放资源(一定要做) 先开后关
preparedStatement.close();
connection.close();
}
}
Junit单元测试:
pom.xml依赖
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
简单使用:@Test注解只有在方法上有效,只要加了这个注解的方法,就可以直接运行

浙公网安备 33010602011771号