学习视频:BV12J411M7Sj
静态web:①html、css。②提供所有人看的数据始终不会发生变化。
动态web:页面会发生变化。(如:论坛点赞、论坛恢复等)。②Serviet/JSP、ASP、PHP。java程序、jar包、配置文件(property)
在java中,动态web资源开发的技术统称为Javaweb
web应用程序:可以提供浏览器访问的程序
web应用程序编写完毕后,若要提供外界访问,则需要一个服务器来管理页面
缺点:web页面无法实时更新。无法和数据库交互(无法持久化),用户无法交互。
web的页面的展示效果会动态变化。解决了静态web会出现的大部分问题。
缺点:
ASP:微软发布。在html中嵌入了vb脚本,ASP+COM。用C#开发
php:开发速度快、功能强大、跨平台、代码简单(70%国内网页用php开发)。但是无法承载大访问量的情况。
JSP/Serviet:
B/S:浏览器和服务器。
C/S:客户端和服务器。
目的:处理用户的一些请求和一些相应信息
IIS:微软发布的有ASP
Tomcat:轻量级开源web服务器项目。 主要用于中小型系统和并发访问用户不多的场合。可用于开发和调试JSP。Tomcat实际上运行的是JSP和Serviet。
官网:tomcat.apache.org
去官网下载源码包
启动/关闭tomcat
可以配置启动的端口号
/conf/server.xml部分内容
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主机的名称
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
问:网站是如何进行访问的?
答:①输入域名。
②检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射。若有,就返回域名的ip地址。若没有,要通过网络查询DNS服务器。
host文件
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
127.0.0.1 activate.navicat.com
一个网页的大致结构
--webapps: tomcat服务器的web目录
--ROOT
--kuangstudy:网站的目录名
-- WEB-INF
-classes:java程序
-lib:web应用程序所依赖的jar包
- index.html 网站首页
- static
-css
-style.css
-js
-img
-......
定义:超文本传输协议(Hyper Text Transfer Protocol,HTTP)
是一个简单的请求-响应协议,它通常运行在TCP
之上。 它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII
形式给出;而消息内容则具有一个类似MIME
的格式。这个简单模型是早期Web
成功的有功之臣,因为它使开发和部署非常地直截了当。
https:安全的http
客户端发送请求(Request)–>服务器
Request URL:HTTPS://www.baidu.com/ 请求地址
Request Method:GET get方法/post方法
Status Code:200 OK 状态码:200
Remote Address:14.215.177.39:443
请求头
GET /index.php?tn=monline_3_dg HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 语言
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BIDUPSID=8022CBA3216D6D96628E6C6F0F82F113; PSTM=1612750909; BD_UPN=13314752; BDUSS=ZTbkJUcVdsaXhVR2pCVUo1Zkh6UExzVXpzdjhTdzdOTi12TnBGcmgxaWR0RlZnSVFBQUFBJCQAAAAAAAAAAAEAAAACp5eVYTk2OTU1NzAyOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ0nLmCdJy5geH; __yjs_duid=1_673e643bebb04bca73844bbf4d4975c01618059107005; MCITY=-%3A; BAIDUID=FFAA59ED6D84908468A6BD1F1488BCB1:FG=1; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; H_PS_PSSID=35105_31254_34813_34584_35872_35949_35315_26350_35884_35867_22159; COOKIE_SESSION=600208_0_9_3_25_12_1_0_9_6_2_1_600324_0_119_0_1646804810_0_1646804691%7C9%230_0_1646804691%7C1; RT="z=1&dm=baidu.com&si=4em762b54de&ss=l0kbyh0j&sl=2&tt=3le&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=41v"; BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; BD_HOME=1; delPer=0; BD_CK_SAM=1; PSINO=5; BA_HECTOR=858ga58ka4ak0185fe1h2imkp0r; H_PS_645EC=9406WInbhpf4PPftvoO7q9JR5sHanQ2bhghkLXmoQlz%2FQEZl5LFIGO8i7zUD9QOdrlza; sug=3; sugstore=0; ORIGIN=0; bdime=1
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Cache-Control: max-age=0 缓冲
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
HOST: 主机
服务器相应–>客户端
百度服务器相应
HTTP/1.1 200 OK
Bdpagetype: 2
Bdqid: 0xa5cf90100005b48d
Cache-Control: private //缓存控制
Connection: keep-alive //连接
Content-Encoding: gzip //编码
Content-Type: text/html;charset=utf-8 //类型
Date: Thu, 10 Mar 2022 01:55:41 GMT
Expires: Thu, 10 Mar 2022 01:55:41 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Server: BWS/1.1
Set-Cookie: BDRCVFR[Fc9oatPmwxn]=aeXf-1x8UdYcs; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=340; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=35105_31254_34813_34584_35872_35949_35315_26350_35884_35867_22159; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1646877341038415924211947926734831465613
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持那种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器,请求完成是断开还是保持连接
HOST: 主机
Reflush: 好俗客户端,多久刷新一次
Location:让网页重定位
常见的 HTTP 状态码:
分类 | 分类描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
更多状态码:https://www.runoob.com/http/http-status-codes.html
问:当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示出来,经历了什么?
在javaweb开发中,需要使用大量的jar包,需要手动导入。
Maven可以用于自动导包
Maven核心思想:约定大于配置。
Maven会规定好如何去编写java代码,而且这个规定必须遵守
https://maven.apache.org/download.cgi 下载源码后解压即可
添加如下配置:
管理员模式运行
mirrors:加速下载
进入maven的conf/settings.xml文件,添加以下代码以配置阿里云镜像
<mirror>
<id>nexus-aliyunid>
<mirrorOf>*,!jeecg,!jeecg-snapshotsmirrorOf>
<name>Nexus aliyunname>
<url>http://maven.aliyun.com/nexus/content/groups/public/url>
mirror>
在本地的仓库、远程仓库
建立一个本地仓库
例:在maven目录下创建一个maven-repo
目录,将路径通过localReponsitoty标签写入setting.xml
<localRepository>"路径"localRepository>
2.等待项目初始化完毕
4.观察maven仓库中多了什么
5.IDEA中的maven设置
IDEA项目创建成功后,多留意一下maven配置
一开始不勾选Create from archetype
选择maven-archetype-webapp模板
还可以通过File–>Project Structure–>Module修改目录类型
注:tomcat10可能会报错,可以用tomcat9进行配置。
pom.xml: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.0modelVersion>
<groupId>com.infinitegroupId>
<artifactId>javaweb-01-mavenartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<name>javaweb-01-maven Maven Webappname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.7maven.compiler.source>
<maven.compiler.target>1.7maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
dependencies>
<build>
<finalName>javaweb-01-mavenfinalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-pluginartifactId>
<version>3.1.0version>
plugin>
<plugin>
<artifactId>maven-resources-pluginartifactId>
<version>3.0.2version>
plugin>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.0version>
plugin>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.1version>
plugin>
<plugin>
<artifactId>maven-war-pluginartifactId>
<version>3.2.2version>
plugin>
<plugin>
<artifactId>maven-install-pluginartifactId>
<version>2.5.2version>
plugin>
<plugin>
<artifactId>maven-deploy-pluginartifactId>
<version>2.8.2version>
plugin>
plugins>
pluginManagement>
build>
project>
通过dependency标签自动下载依赖,maven还会自动下载级联的依赖
maven仓库:https://mvnrepository.com/
maven由于约定大于配置,可能会遇到自己写的配置文件无法导出或失效的问题。解决方式为在build标签中配置resources
https://www.cnblogs.com/yuqiliu/p/12059614.html
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
IDEA中可以生成项目中包的依赖关系
修改maven默认配置:关闭当前项目–>Customize–>Allsettings
servlet官方入门资源
Source Code for HelloWorld Example
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println("Hello World! ");
out.println("");
out.println("");
out.println("Hello World!
");
out.println("");
out.println("");
}
}
HttpServlet类若项目中不存在,可以利用maven仓库网站(https://mvnrepository.com/)导入
使用servlet类生成网页
项目目录:
helloServlet继承HttpServlet类
package com.infinite.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//相应的类型:html
response.setContentType("text/html");
//设置编码格式
response.setCharacterEncoding("UTF-8");
//获取相应的输出流
PrintWriter out = response.getWriter();
out.println("");
out.println("");
out.println("INFINITE ");
out.println("");
out.println("");
out.println("1234564189461xxxx
");
out.println("");
out.println("");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
然后再web.xml中配置servlet映射
<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>helloServletservlet-name>
<servlet-class>com.infinite.servlet.helloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
web-app>
Servlet时sun公司开发动态web的一门技术
Sun再这些API中提供一个接口叫做:Servlet,若要开发一个Servlet程序,需要两步:
实现了Servlet接口的java程序又称Servlet
Sun公司对Servlet接口有两个默认的实现类:HttpServlet
Servlet–>GenerateServlet–>HttpServlet–>自己实现的Servlet类
Servlet接口如下
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
构建一个maven项目、删除其中的src目录。可以在该项目中创建Moudel。这个空工程就是maven的主工程
在maven父项目中添加一个moudle。(如果创建moudle后卡死,可以留意一下maven路径配置)
父项目的pom.xml中会出现
<modules>
<module>servlet-01module>
modules>
子项目的pom.xml中会出现
<parent>
<artifactId>javaweb-02-servletartifactId>
<groupId>com.infinitegroupId>
<version>1.0-SNAPSHOTversion>
parent>
父项目中的java子项目可以直接使用
maven环境优化:①修改web.xml的内容。可以复制tomcat的webapp目录下的样例。②将maven的结构搭建完整
编写一个Servlet程序
public class HelloServlet extends HttpServlet {
//get和post知识请求实现的不同方式,可以相互调用,业务逻辑相同
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer=resp.getWriter();
writer.print("Hello,xxxxyyyy");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
编写Servlet的映射。 我们写的是java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册自己写的Servlet,并提供一个浏览器可以访问的路径。
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.infinite.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>hellourl-pattern>
servlet-mapping>
配置tomcat
启动测试
Servlet有web服务器调用,web服务器在收到浏览器请求之后,会发生如下事件
一个Servlet指定一个映射路径
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.infinite.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
一个Servlet指定多个映射路径
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.infinite.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello1url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello3url-pattern>
servlet-mapping>
默认请求路径
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
一个Servlet指定通用映射路径
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>*.infiniteurl-pattern>
servlet-mapping>
上面的映射表示任意以.infinite
为后缀的路径都会映射到hello上,如主页名/(任意符号).infinite
。*
号为通配符,这里*
号前不能使用路径符号/
。
指定了固有的映射路径优先级最高,如果找不到就会走默认的路径请求
自定义error页面的过程和写一个HelloServlet程序相同。只不过为了将非法输入路径映射到自定义error页面,会在web.xml中将自定义error的servlet映射路径写为/*
等通配符形式。这个路径优先级最低。
ErrorServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer=resp.getWriter();
writer.println("!404 nout found!"
);
writer.println(" +
" alt='nullImg'>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
web.xml
<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>helloservlet-name>
<servlet-class>com.infinite.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>notFoundErrorservlet-name>
<servlet-class>com.infinite.servlet.ErrorServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>notFoundErrorservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
web-app>
实现效果
web容器再启动的时候,它会为每个web程序都创建一个对于的ServletContext对象,该对象代表了当前的web应用
HelloServlet
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter(); 初始化参数
//this.getServletConfig(); Servlet配置
//this.getServletContext(); Servlet上下文
ServletContext servletContext=this.getServletContext();
String username="bob";
//将一个数据保存在ServletContext对象中,名字为username,值为bob
servletContext.setAttribute("username",username); //左侧为属性名
}
}
GetServlet
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
String username=(String)servletContext.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("用户名:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<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>helloservlet-name>
<servlet-class>com.infinite.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>getcservlet-name>
<servlet-class>com.infinite.servlet.GetServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>getcservlet-name>
<url-pattern>/getcurl-pattern>
servlet-mapping>
web-app>
测试
web.xml
<context-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
context-param>
<servlet>
<servlet-name>gpservlet-name>
<servlet-class>com.infinite.servlet.ServletDemo03servlet-class>
servlet>
<servlet-mapping>
<servlet-name>gpservlet-name>
<url-pattern>/gpurl-pattern>
servlet-mapping>
ServletDemo03
package com.infinite.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
String url=servletContext.getInitParameter("url");
resp.getWriter().print(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
ServletDemo04
package com.infinite.servlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext=this.getServletContext();
//转发的请求路径
//RequestDispatcher requestDispatcher=servletContext.getRequestDispatcher("/gp");
//调用forward实现转发
//requestDispatcher.forward(req,resp);
servletContext.getRequestDispatcher("/gp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<context-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
context-param>
<servlet>
<servlet-name>gpservlet-name>
<servlet-class>com.infinite.servlet.ServletDemo03servlet-class>
servlet>
<servlet-mapping>
<servlet-name>gpservlet-name>
<url-pattern>/gpurl-pattern>
servlet-mapping>
<servlet>
<servlet-name>sd4servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo04servlet-class>
servlet>
<servlet-mapping>
<servlet-name>sd4servlet-name>
<url-pattern>/sd4url-pattern>
servlet-mapping>
/sd4
向/gp
转发请求,响应结果仍在/sd4
页面中
在java或resources目录下新建的properties文件,打包后在同一个路径下:targer/classes,该路径又称classpath
properties
username=root
password=asfew4334t
ServletDemo05
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("username");
String pwd = properties.getProperty("password");
resp.getWriter().print("user:"+username+"\n"+"password:"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>sd5servlet-name>
<servlet-class>com.infinite.servlet.ServletDemo05servlet-class>
servlet>
<servlet-mapping>
<servlet-name>sd5servlet-name>
<url-pattern>/sd5url-pattern>
servlet-mapping>
测试效果
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServietRequest对象,代表响应一个HttpServletResponse
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void etHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
//......
状态码常量
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
//......
目录结构
FileServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取下载文件的路径
String realPath = "C:\\Users\\96955\\Desktop\\openSourceItems\\JAVAWEB_TEST\\javaweb-02-servlet\\response\\target\\classes\\11.png";
System.out.println("下载文件的路径:"+realPath);
// 2. 下载文件的文件名
//截取最后一个/符号,通过+1获取11.png这一文件名
String fileName=realPath.substring(realPath.lastIndexOf("\\")+1);
// 3. 设置想办法让浏览器能够支持(Content-Disposition)需要下载的东西
// URLEncoder用于中文名编码
resp.setHeader("Content-Disposition","attachment;filename"+ URLEncoder.encode(fileName,"UTF-8"));
// 4. 获取下载文件的输入流
FileInputStream fileInputStream = new FileInputStream(realPath);
// 5. 创建缓冲区
int len=0;
byte[] bytes = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream outputStream = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区
while((len=fileInputStream.read(bytes))>0){
outputStream.write(bytes,0,len);
}
fileInputStream.close();
outputStream.close();
// 8. 使用OutputStream将缓冲区中的数据输出到客户端
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
web.xml
![23.1、文件下载](images/23.1%E3%80%81%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD.png)<servlet>
<servlet-name>fileDownloadservlet-name>
<servlet-class>com.infinite.servlet.FileServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>fileDownloadservlet-name>
<url-pattern>/downloadPNGurl-pattern>
servlet-mapping>
测试效果
注:了解即可
ImageServlet
package com.infinite.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器3秒刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics g = (Graphics2D) bufferedImage.getGraphics();
//设置背景颜色
g.setColor(Color.CYAN);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.magenta);
g.setFont(new Font(null,Font.ITALIC,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());
}
//生成随机数方法
private String makeNum(){
Random random=new Random();
String num = random.nextInt(99999999) + "";
StringBuffer stringBuffer = new StringBuffer();
for(int i=0;i<7-num.length();i++){
stringBuffer.append("0");
}
String s=stringBuffer.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>ImageServletservlet-name>
<servlet-class>com.infinite.servlet.ImageServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ImageServletservlet-name>
<url-pattern>/ImageServleturl-pattern>
servlet-mapping>
测试效果
B的一个web资源收到客户端A的请求后,B会通知客户端去访问另外一个web资源C,这个过程叫重定向。
常见场景:
void sendRedirect(String var1) throws IOException
RedirectServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("location","/response_war/ImageServlet");
// resp.setStatus(302);
resp.sendRedirect("/response_war/ImageServlet"); //项目名要先写上
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>ImageServletservlet-name>
<servlet-class>com.infinite.servlet.ImageServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ImageServletservlet-name>
<url-pattern>/ImageServleturl-pattern>
servlet-mapping>
<servlet>
<servlet-name>RedirectServletservlet-name>
<servlet-class>com.infinite.servlet.RedirectServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>RedirectServletservlet-name>
<url-pattern>/rdsurl-pattern>
servlet-mapping>
测试效果
请求报文
面试:请你聊聊重定向和转发的区别
答:
相同点:
不同点:
RequestTest
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向要注意路径问题,否则会出现404
resp.sendRedirect("/response_war/success.jsp");
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--提交的类路径,需要寻找项目的路径--%>
<%--${pageContext.request.contextPath}/login 代表当前的项目路径--%>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
log in successfully!
web.xml
<servlet>
<servlet-name>RequestTestservlet-name>
<servlet-class>com.infinite.servlet.RequestTestservlet-class>
servlet>
<servlet-mapping>
<servlet-name>RequestTestservlet-name>
<url-pattern>/loginurl-pattern>
servlet-mapping>
测试效果
HttpServletRequest
代表客户端的请求,用户通过Http协议访问服务端,HTTP请求中的所有信息会被封装到HttpServletRequest
中,通过HttpServletRequest
的方法,获得客户端的所有信息。
String getParameter(String s);
String[] getParameterValues(String s);
下面实现一个前后端用户登录数据传输的DEMO
目录
LoginServlet
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username=req.getParameter("username");
String password = req.getParameter("password");
String[] foods=req.getParameterValues("foods");
System.out.println("==============================");
System.out.println("username:"+username);
System.out.println("password:"+password);
System.out.println(Arrays.toString(foods));
System.out.println("==============================");
//通过请求转发
//此处的 ’/‘ 代表当前的web应用,不需要添加项目路径
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
登录
登录界面
<%-- 以post的方式提交表单,提交到login请求路径--%>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
log in successfully!!!
web.xml
<servlet>
<servlet-name>loginServletservlet-name>
<servlet-class>com.infinite.servlet.LoginServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>loginServletservlet-name>
<url-pattern>/loginurl-pattern>
servlet-mapping>
测试效果
会话的定义:用户打开一个浏览器–>点击了很多超链接–>访问多个web资源–>关闭浏览器,这个过程称一次会话。
有状态会话: 一个网站如何证明你来过?
客户端 服务端
信件
,客户端下次访问服务端带上这个信件就好了;该信件又称cookie
session
cookie:
session
常见例子:网站第一次登录后,除非刻意清空记录,下次访问就能直接登录
CookieDemo01
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器:告诉你,你当前访问的时间,把这个时间封装成cookie,下次访问以cookie作证
//中文编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=utf-8");
PrintWriter out = resp.getWriter();
//Cookie:服务端从客户端获取
Cookie[] cookies = req.getCookies(); //可能存在多个cookie
//判断cookie是否存在
if(cookies!=null) {
out.write("上次访问的时间是:");
for (Cookie cookie : cookies) {
//获取cookie的名字
if(cookie.getName().equals("lastLoginTime")){
//获取cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}
else {
out.write("首次访问");
}
//服务器给客户端发cookie
Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
//cookir有效期设置
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<servlet>
<servlet-name>CookieDemo01servlet-name>
<servlet-class>com.infinite.servlet.CookieDemo01servlet-class>
servlet>
<servlet-mapping>
<servlet-name>CookieDemo01servlet-name>
<url-pattern>/c1url-pattern>
servlet-mapping>
测试效果
Cookie[] cookies = req.getCookies(); //获取Cookie
cookie.getName(); //获取cookie中的key
cookie.getValue(); //获取cookie中的value
new Cookie("lastLoginTime",System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //给客户端发送一个cookie
cookie:一般会保存在本地用户目录下的/appData中
一个网站cookie是否存在上限?
删除cookie:
编码解码
URLEncoder.encode("张三","utf-8");
URLDecoder.decode(cookie.getValue(),"utf-8");
关于Session:
session和cookie的区别:
session使用常见:
SessionDemo01
package com.infinite.servlet;
import com.infinite.pugo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("张三",1));
//设置Session的IO
String sessionId=session.getId();
//判断Session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功,ID:"+sessionId);
}
else{
resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
}
//Session的创建过程
// Cookie cookie=new Cookie("JSESSIONID",sessionId);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
SessionDemo02
package com.infinite.servlet;
import com.infinite.pugo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=utf-8");
//得到Session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
SessionDemo03
package com.infinite.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
//注销后浏览器又会产生新的session
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
通过web.xml设置session过期时间
<session-config>
<session-timeout>15session-timeout>
session-config>