JavaWeb---Tomcat---Servlet
JavaWeb
1、基本概念
静态网页无法与人工交互
动态网页可以人工交互
技术栈:Servlet、JSP、PHP
简介:在Java中,动态web资源开发的技术统称为JavaWeb.
2、web应用
web应用程序“可以提供浏览器访问的程序。
注意:网上可以访问的资源,都是储存在摸个计算机(服务器)上。通过URL(地址)去访问这个地址。
这个统一的web资源会被放置在同一个文件夹上,web应用程序–>Tomcat(服务器),将web应用部署在服务器上。
web应用程序编写完毕后,若想提供给外界访问:需要一个服务器来同意管理。
3、组成部分
包括(静态web,动态web):
- 网页前端:html javaScript CSS
- 技术栈:JSP Servlet
- java程序
- jar包
- 配置文件
3.1、静态web
静态网页存在的缺点:
1.web页面无法动态更新,所有用户看到的都是同一个页面
2.无法和数据库交互(数据无法持久化,用户无法交互)
3.伪动态(轮播图,点击特效)
Javascript[实际开发用的最多]
VBScript
3.2、动态web
- 客户端发送请求到服务端
- 服务端经过webServer 插件过滤请求
- webServer Plugin分别处理动态资源与静态资源
- 其中静态资源由webServer来处理请求
- 动态资源则由Servlet/JSP来处理,再发送给webServer,WebServer再处理请求,病发送响应给客户端
缺点:
1.加入服务器的动态web资源出现错误时,后台就需要修改,重新发布。----停机维护
优点:
1.动态更新,所有用户看到的不是同一个
2.人工交互
3.数据库交互
4、Web服务器
4.1、技术讲解
ASP:
微软:国内最早流行的是ASP
在HTML中嵌套VB脚本,ASP+COM
在ASP开发中,页面比较乱,维护成本高
在ASP中使用是C#
IIS
PHP
- PHP开发速度快,功能强大,跨平台,代码简单(WP,中国70%网站使用)
- 无法承载大访问量的情况(局限性)
JSP/Servlet
B/S:浏览器和服务器
C/S:客户端和服务器
- sun公司主推的B/S架构
- 基于Java语言的
- 可以承载三高问题(高并发,高可用,高高性能)
- 语法像ASP,ASP–>JSP,加强市场强度
4.2、Web服务器
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息。
4.2.1、IIS(暂时了解)
微软的:windows中自带的
4.2.2、Tomcat
对初学者来说,不错的选择;
可用尝试手写Tomcat;
下载Tomcat
1.解压或者安装
2.了解配置文件及目录结构
3.了解这个东西的作用
注意:同样适用于其他软件(包括Java以及其他)
rt.jar是Java的核心jar包
Tomcat
1、启动Tomcat
- 选择Tomcat文件夹中bin目录下的startup.bat启动
- 选择Tomcat文件夹中bin目录下的shutdown.bat启动
访问测试:http://localhost:8080/
可能遇到的问题:
1.Java环境变量没有配置
2.闪退问题:需要配置兼容性
3.乱码问题:配置文件中设置
2、配置Tomcat
Tomcat—>conf—>server.xml(服务器核心配置文件)
server.xml用处:
1.可以配置启动的端口号
Tomcat的默认端口号:8080
MySQL:3306
HTTP:80
https:443
<Connector port="8081" redirectPort="8443" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="utf-8"/>
2.可以配置主机的名称
默认主机名为:localhost->127.0.0.1
默认网站应用存放的位置为:webapps
<Host name="localhost" unpackWARs="true" autoDeploy="true" appBase="webapps">
3、发布一个网站
3.1、猴版
将自己写的网站,放置到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了。
步骤一、准备启动Tomcat
步骤二、打开服务器
步骤三、测试是否打开服务器
步骤四、成功打开服务器
步骤五、进入webapps准备建立猴版网站
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DYxjbgPy-1614861455676)(https://img.imgdb.cn/item/6040d0d8360785be54699746.png)]
步骤六、复制一份项目
步骤七、建立项目
步骤八、删除不必要文件
步骤九、配置文件
步骤十、配置成功
步骤十一、测试新建项目
步骤十二、意外惊喜
步骤十三、关闭服务器
3.2、网站应该有的结构
--webapps:Tomcat服务器的web目录-zhangtaoStudy:网站的目录名(项目的名称)- WEB-INF:放置网站程序的-classes:java程序-lib:web应用所依赖的jar包-web.xml- index.html:默认的首页- static:其他文件夹-css-js-img........
4、HTTP
4.1、什么是HTTP
HTTP(超文本传输协议)是一个简单的请求-响应协议,他通常运行在TCP上。
- 文本:html,字符串,、、、
- 超文本:图片,音乐,视频,定位,地图…
- 默认端口:80
- HTTPS默认端口:443
4.2、两个时代
http1.0
HTTP/1.0:客户端可以与服务端连接后,只能获得一个web资源,断开后无法再连接
http2.0
HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
4.3、HTTP请求
客户端—>发送请求(request)—>服务器
eg:baidu
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET get方法/post方法
Status Code: 200 OK 状态码:200
Remote Address: 36.152.44.95:443
Referrer Policy: strict-origin-when-cross-origin
Accept:text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;
Cache-Control:max-age=0
Connection: keep-alive
1.请求行
- 请求行中的请求方式:GET
- 请求方式:GET,POST(重点),head,delete,put,tract…
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据,不安全。但是比较高效率、
- post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据,安全。但是不高效
2.消息头
Accept 告诉浏览器,它所支持的数据类型
Accept-Encoding 支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language 告诉浏览器,它的语言环境
Cache-Control 缓存控制
Connection 告诉浏览器,请求完成是断开还是保持连接
HOST:主机......
4.4、HTTP响应
服务器—>发送响应(response)—>客户端
baidu 响应
Cache-Control: private 缓存控制
Connection: keep-alive 连接:保持连接
Content-Encoding: gzip 编码
Content-Type: text/html;类型
charset=utf-8
1.响应体
Accept 告诉浏览器,它所支持的数据类型
Accept-Encoding 支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language 告诉浏览器,它的语言环境
Cache-Control 缓存控制
Connection 告诉浏览器,请求完成是断开还是保持连接
HOST:主机......
Refresh:告诉客户端,多久刷新一次
Location:让网页重新定位
2.响应状态码
200:表示响应请求成功
3**:请求重定向(重新到新的位置上)
404:表示网页不存在,找不到资源
5**:服务器代码错误 500 502:网关错误
5、Maven
5.1、为什么需要学习Maven
1.在Javaweb开发中,需要使用大量的jar包,我们手动导入。
2.如何能够让一个东西自动帮我导入和配置这个jar包。
目前用来就是方便导入jar包
3.Maven 的高级之处在于,他会帮你导入这个jar包所依赖的其他jar包
5.2、Maven项目架构管理工具
Maven的核心思想:约定大于配置
有约束,不要去违反。
Maven会规定如何去编写Java代码,必须按照这个规范来。
5.3、maven配置
5.4、maven阿里云镜像
镜像作用:加速我们的下载
国内建议使用阿里云镜像:
<mirror><!--This sends everything else to /public --><id>nexus-aliyun</id><mirrorOf>*</mirrorOf><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
5.5、本地仓库
https://blog.csdn.net/CDW2328/article/details/90113194
建立一个本地仓库:localRepository
<localRepository>F:\Maven\apache-maven-3.6.3-bin\apache-maven-3.6.3\maven-repo</localRepository>
5.6、在IDEA中创建Maven项目
虚拟路径映射
5.7、pom.xml文件
pom.xml文件是Maven的核心配置文件。
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>
项目打包方式:
jar:java 应用
war:Javaweb应用
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>MavenDemo1</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>MavenDemo1 Maven Webapp</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies><build><finalName>MavenDemo1</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build> </project>
5.8、Maven配置时候可能遇到的问题:
1.Maven由于约定大于配置,所以我们之后可能遇到我们写的配置文件无法被导出或生效的问题:
解决方案: Maven资源导出配出
2.Tomcat闪退问题
3.IDEA中每次都重复配置Maven
解决方案:在IDEA的全局配置中进行配置,设置中找到Maven进行默认配置
4.Maven项目中Tomcat无法配置
5.9、Maven使用过程中可能遇到的问题:
1、无法导入
(兼容性问题)—unable to import Maven
大概原因:Maven版本问题和JDK的兼容性
目前解决方法:将版本降低一个版本
2、Tomcat闪退问题
jdk以及jre问题
3、IDEA中每次都重复配置Maven
全局配置以及项目配置
在全局配置中,以后就不用再修改
https://blog.csdn.net/weixin_44494373/article/details/108932403?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160925339716780261984035%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160925339716780261984035&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-5-108932403.pc_search_result_cache&utm_term=IDEA%E4%B8%ADMaven%E9%BB%98%E8%AE%A4%E9%85%8D%E7%BD%AE%E5%9C%A8%E5%93%AA%E9%87%8C
4、Maven项目中Tomcat无法配置
没有artifact文件
https://blog.csdn.net/weixin_44494373/article/details/108932403?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160925339716780261984035%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160925339716780261984035&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-5-108932403.pc_search_result_cache&utm_term=IDEA%E4%B8%ADMaven%E9%BB%98%E8%AE%A4%E9%85%8D%E7%BD%AE%E5%9C%A8%E5%93%AA%E9%87%8C
个人建议:多刷新几次
5、Maven默认web项目中web.xml版本过老
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name>
</web-app>
<!--版本过老-->
使用Tomcat的头文件版本:
<?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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true"></web-app>
个人建议:直接在文件中附加一个note.md在这个笔记里面添加所需要的文件(包括web.xml等等)
6、新建文件夹
- 在src–>main的目录下面新建Java文件夹以及resource文件夹。
- IDEA会自动配置文件夹类型,直接新建即可。
7、Maven仓库的使用
https://mvnrepository.com/
官方的Maven的jar包仓库
eg:搜索Servlet的jar
其中标签代表的是作用域的意思,删除掉。代表在任何地方都可以使用。
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><!--作用域--><scope>test</scope></dependency></dependencies>
Servlet
Sun在API中提供了一个接口叫做Servlet,如果想要开发一个Servlet程序,只需要完成两个小步骤:
1.编写一个类,实现Servlet接口
2.把开发好的Java类部署到web服务器上
把实现Servlet接口的Java程序叫做Servlet
1、HelloServlet
Servlet接口SUN公司有两个默认的实现类:HttpServlet/GenericServlet
1.1、创建一个普通的Maven项目
删除SRC目录,之后直接建立模块。这个空的工程就是主工程Maven。
在这个Maven的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/javax.servlet.jsp-api --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.3</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/taglibs/standard --><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><!-- 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></dependencies>
1.2、关于Maven父子工程的理解:
父项目中会有
<modules><module>Servlet01</module></modules>
子项目中会有
<parent><artifactId>JavaWeb-Servlet</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent>
父项目中的Java子项目可以直接使用:
son extends father
1.3、Maven环境优化
- 修改web.xml为最新的
- 将Maven的结构 搭建完整
子模块的web.xml最好配置一下,保证最新(从Tomcat的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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"metadata-complete="true">
</web-app>
1.4、编写一个Servlet程序
- 编写一个普通类
- 实现Servlet接口,继承HttpServlet
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {PrintWriter writer =resp.getWriter();//响应流}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}
//由于get或者post只是请求实现的不同方式,可以相互调用,业务逻辑都一样。
1.5、编写Servlet的映射(未知)
为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要实现服务器进行访问,所以我们需要再web服务器中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径
<!-- 注册Servlet --><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>com.zhangtao.Servlet.HelloServlet</servlet-class><!--注意,servlet-class只能在servlet-name的下面,不能在上面,具体未知--></servlet><!-- Servlet的请求路径 --><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern><!--同理,url-pattern也是只能放置在servlet-name的后面--></servlet-mapping>
1.6、配置Tomcat
注意:配置项目发布的路径即可。
1.7、启动测试
(注意:idea部署Tomcat时没有war文件,可能时Maven导入了,但是Idea还没有导入,刷新几次 )
https://blog.csdn.net/chpllp/article/details/105123042?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160913617116780302934424%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160913617116780302934424&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-2-105123042.pc_search_result_no_baidu_js&utm_term=idea%E9%85%8D%E7%BD%AEtomcat%20deployment%E6%B2%A1%E6%9C%89artifact%E9%80%89%E9%A1%B9
2、Mapping
<!--servlet请求路径-->
<servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
问题:
一个Servlet可以指定一个映射路径
<url-pattern>/hello</url-pattern>
那么一个Servlet可以指定多个映射路径?
<url-pattern>/hello1</url-pattern> <url-pattern>/hello2</url-pattern> <url-pattern>/hello3</url-pattern> <url-pattern>/hello4</url-pattern> <url-pattern>/*</url-pattern>
直接使用通配符,那么使用任何字符都是可以的。
其中“/*”就是默认请求路径
一个Servlet可以指定通用映射路径
指定一些后缀或者前缀的等等。。。。
<url-pattern>*.zhangtao</url-pattern> <url-pattern>zhangtao.*</url-pattern>
可以使用前缀和后缀,这些都是可以使用的。
不过“*”前面不能加映射路径。
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
(实践测试)
4、ServletContext
web容器在启动的时候,他为每个web程序都创建一个对应的ServletContext对象,他代表了当前的web应用
4.1、作用:
4.1.1、共享数据:
在这个Servlet中保存的数据,可以在另外一个Servlet中可以看到。
注意
先存后取,先保存数据,再读取数据;
搭配web.xml使用
//ContextDemo保存数据
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//打桩测试System.out.println("hello");//获取当前ServletContext对象ServletContext context =this.getServletContext();String username ="zhangtao";//数据//将一个键值对保存在ServletContext中,键:username;值:usernamecontext.setAttribute("username",username);}//GetServlet读取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context =this.getServletContext();//获得保存在ServletContext中的username,其中由于不知道类型,需要强制转换一下String username = (String) context.getAttribute("username");/*防止出现中文乱码现象,要设置格式以及字符集不过要先保存ServletContext,否则取不到信息*/resp.setContentType("text/html");resp.setCharacterEncoding("utf-8");resp.getWriter().print("姓名:"+username);}
ContextDemo<!--注册Servlet--><servlet><servlet-name>ContextDemo</servlet-name><servlet-class>com.zhangtao.context.ContextDemo</servlet-class></servlet><!--Servlet请求路径--><servlet-mapping><servlet-name>ContextDemo</servlet-name><url-pattern>/context</url-pattern></servlet-mapping>
GetServlet<servlet><servlet-name>GetServlet</servlet-name><servlet-class>com.zhangtao.context.GetServlet</servlet-class></servlet><servlet-mapping><servlet-name>GetServlet</servlet-name><url-pattern>/get</url-pattern></servlet-mapping>
测试访问结果:姓名:zhangtao
4.1.2、获取初始化参数
1.设置初始化参数
<!--配置一些web应用初始化参数--><context-param><param-name>URL</param-name><param-value>jdbc:mysql://localhost:3306/mybaits</param-value></context-param>
2.提取参数
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取当前ServletContext对象ServletContext context =this.getServletContext();//获取初始化参数String url = context.getInitParameter("URL");resp.getWriter().print(url);}
4.1.3、请求转发
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取当前ServletContext对象ServletContext context =this.getServletContext();/*请求转发,转发的请求路径”/contextdemo2“*/RequestDispatcher requestDispatcher = context.getRequestDispatcher("/contextdemo2");/*转发调用forward()实现请求转发,两者可以合并*/requestDispatcher.forward(req,resp);//RequestDispatcher requestDispatcher = context.getRequestDispatcher("/contextdemo2").forward(req,resp);}
/*
其中,getRequestDispatcher()代表的意思是请求转发的意思。
而forward()是转发的方法。
*/
<servlet><servlet-name>ContextDemo2</servlet-name><servlet-class>com.zhangtao.context.ContextDemo2</servlet-class></servlet><servlet-mapping><servlet-name>ContextDemo2</servlet-name><url-pattern>/contextdemo2</url-pattern></servlet-mapping><!--配置一些web应用初始化参数--><context-param><param-name>URL</param-name><param-value>jdbc:mysql://localhost:3306/mybaits</param-value></context-param><!--请求转发--><servlet><servlet-name>ContextDemo3</servlet-name><servlet-class>com.zhangtao.context.ContextDemo3</servlet-class></servlet><servlet-mapping><servlet-name>ContextDemo3</servlet-name><url-pattern>/contextdemo3</url-pattern></servlet-mapping>
<!--ContextDemo2在获取初始化参数-->
请求转发与重定向区别:(重点)
4.1.4、读取资源文件
读取properties文件
username=zhangtao
password=123456
- 在java 目录下新建properties
- 在resources目录下新建properties
发现:都被打包到同一个路径下:classes。我们称这个路径为classpath;
建议:其中db.properties文件必须在main文件夹下面的sources文件夹下面main–>sources
思路:需要一个文件流去读取存放在properties文件中的信息
也可以在maven的pom.xml文件中,在build中配置resources,来防止资源导出失败的问题
<!-- 在build中配置resources,来防止我们资源导出失败的问题--><build><resources><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>true</filtering></resource></resources></build>
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取当前ServletContext对象ServletContext context =this.getServletContext();//读取properties文件InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");//其中“/”代表的是当前web应用,//新建properties文件Properties prop = new Properties();//加载文件prop.load(is);//设置信息//由于不知道类型,所以强转类型,如果换成String也是可以,不过考虑其他因素(内存)Object age = prop.setProperty("age", "23");String information =(String) prop.setProperty("information", "电信1701");//读取信息String username = prop.getProperty("username");String password = prop.getProperty("password");String age1 = prop.getProperty("age");String information1 = prop.getProperty("information");//转到网页前端//设置格式resp.setContentType("text/html");resp.setCharacterEncoding("utf-8");resp.getWriter().println(username);resp.getWriter().println(password);resp.getWriter().println(age1); resp.getWriter().println(information1);}
注意:
properties的文件路径是运行过的文件之后储存的位置。
其中,Context-1.0-SNAPSHOT是打包之后的项目,路径就储存在这个里面。
其中“/WEB-INF”,前面的“/”代表的意思是当前的web应用
这些都是底层的一些运用。
5、HttpServletResponse
web 服务器接收到客户端发送过来的请求,针对这个请求,分别创建了:
- 代表请求的HttpServletRequest;
- 代表响应的HttpServletResponse。
- 如果要获取客户端请求过来的参数:找HttpServletRequest。
- 如果要给客户端响应一些信息:找HttpServletResponse。
5.1、简单分类
5.1.1、负责向浏览器发送数据的方法
getWriter()
getOutputStream()
5.1.2、负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
5.1.3、响应的状态码
int SC_CONTINUE = 100;int SC_SWITCHING_PROTOCOLS = 101;int SC_OK = 200;int SC_CREATED = 201;int SC_ACCEPTED = 202;int SC_NON_AUTHORITATIVE_INFORMATION = 203;int SC_NO_CONTENT = 204;int SC_RESET_CONTENT = 205;int SC_PARTIAL_CONTENT = 206;int SC_MULTIPLE_CHOICES = 300;int SC_MOVED_PERMANENTLY = 301;int SC_MOVED_TEMPORARILY = 302;int SC_FOUND = 302;int SC_SEE_OTHER = 303;int SC_NOT_MODIFIED = 304;int SC_USE_PROXY = 305;int SC_TEMPORARY_REDIRECT = 307;int SC_BAD_REQUEST = 400;int SC_UNAUTHORIZED = 401;int SC_PAYMENT_REQUIRED = 402;int SC_FORBIDDEN = 403;int SC_NOT_FOUND = 404;int SC_METHOD_NOT_ALLOWED = 405;int SC_NOT_ACCEPTABLE = 406;int SC_PROXY_AUTHENTICATION_REQUIRED = 407;int SC_REQUEST_TIMEOUT = 408;int SC_CONFLICT = 409;int SC_GONE = 410;int SC_LENGTH_REQUIRED = 411;int SC_PRECONDITION_FAILED = 412;int SC_REQUEST_ENTITY_TOO_LARGE = 413;int SC_REQUEST_URI_TOO_LONG = 414;int SC_UNSUPPORTED_MEDIA_TYPE = 415;int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;int SC_EXPECTATION_FAILED = 417;int SC_INTERNAL_SERVER_ERROR = 500;int SC_NOT_IMPLEMENTED = 501;int SC_BAD_GATEWAY = 502;int SC_SERVICE_UNAVAILABLE = 503;int SC_GATEWAY_TIMEOUT = 504;int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
200:请求响应成功
5.2、HttpServletResponse常见应用
5.2.1、向浏览器输出信息
5.2.2、下载文件
- 要获取下载文件的路径
- 下载的文件名是啥?
- 想办法让浏览器能够支持(Content-Disposition)下载我们所需要的东西
- 获取下载文件的输入流
- 创建缓冲器
- 获取OutputStream对象
- 将FileOutputStream流写入到buffer缓冲区
- 使用OutputStream将缓冲区中的数据输入到客户端
package com.zhangtao;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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//要获取下载文件的路径//String realPath = this.getServletContext().getRealPath("/1.png");String realPath ="F:\\IDEA\\JavaWeb-Servlet2\\HttpResponse\\target\\classes\\1.png";System.out.println(realPath);//下载的文件名是啥?String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);/*** 1.截取字符串substring()* 2.截取“/”后面的字符,其中lastIndexOf()是截取最后一个*///想办法让浏览器能够支持(Content-Disposition)下载我们所需要的东西//resp.setHeader("Content-Disposition","attachment;filename="+fileName);resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));//其中URLEncoder.encode(fileName,"UTF-8")就是转码/*** 如果是中文的话,那么URLEncoder.encode()就使用,否则有可能乱码*///获取下载文件的输入流FileInputStream in = new FileInputStream(realPath);//创建缓冲器int len =0;byte[] buffer = new byte[1024];//获取OutputStream对象ServletOutputStream out = resp.getOutputStream();//将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输入到客户端while((len=in.read(buffer))>0){out.write(buffer,0,len);}in.close();out.close();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
5.2.3、验证码功能
验证码怎么来的?后端实现,需要用到Java的图片类,生产一个图片。
package com.zhangtao;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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//如何让浏览器5秒自动刷新一次resp.setHeader("refresh","5");//在内存中创建一个图片BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);//得到图片Graphics2D graphics = (Graphics2D) image.getGraphics();//设置图片的背景颜色graphics.setColor(Color.white);graphics.fillRect(0,0,80,30);//给图片写数据graphics.setColor(Color.BLUE);graphics.setFont(new Font(null,Font.BOLD,20));graphics.drawString(makeNum(),0,20);//告诉浏览器,这个请求用图片的方式打开resp.setContentType("image/jpeg");//网站存在缓存,不让浏览器缓存resp.setDateHeader("exprise",-1);resp.setHeader("Cache-Control","no-cache");//不要缓存控制,具体可以参考之前的HTTP章节resp.setHeader("Pragma","no-cache");//把图片写给浏览器ImageIO.write(image, "jpg", resp.getOutputStream());}//生成随机数private String makeNum(){Random random = new Random();String num = random.nextInt(999999)+"";//6位数的随机数StringBuffer stringBuffer = new StringBuffer();for(int i= 0;i<7-num.length();i++){stringBuffer.append("0");}num = stringBuffer.toString()+num;return num;}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
5.2.4、重定向
一个web资源收到客户端请求后,他会通知客户
去顾问另一个web资源-----这个过程就是重定向。
常见场景:
用户登录—登录成功跳转到另外的页面。
public void sendRedirect(String location) throws IOException;
测试:
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect("/HttpResponse/image");//其中如果想要跳转到某个页面,一定要加上项目的名称//也是重定向resp.setHeader("loaction","HttpResponse/image");resp.setStatus(302);/*不过HttpServletResponse.SC_MOVED_TEMPORARILY代表的也是302直接使用常量比较规范*/}
6、HttpServletRequest
HttpServletRequest代表了客户端的请求,用户的通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法我们可以获得客户端的所有信息。
1.获取前端传递的参数
getParameter(String name) //获取单个前端传递的参数
getParameterValues(String[] names) //获取多个前端传递的参数
前端请求页面
<html>
<body>
<h2>Hello World!</h2>
<%--注意,这里的action指代的是提交的路径,提交到相关的页面进行处理,而且需要寻找到处理页面的路径--%>
<%--注意,${pageContext.request.contextPath}代表的是当前的项目--%>
<form action="${pageContext.request.contextPath}/request" method="get"><%-- 寻找到当前项目下的login --%>姓名:<input type="text" name="username" value="请输入姓名" minlength="5"/><br>密码:<input type="password" name="password" value="请输入密码" maxlength="20" minlength="8"/><br>爱好:<input type="checkbox" name="hobbies">写代码<input type="checkbox" name="hobbies">弹琴<input type="checkbox" name="hobbies">看书<input type="checkbox" name="hobbies">听音乐<br><input type="submit"/>
</form>
</body>
</html>
后端Java程序
//Java程序
public class RequestDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("进入这个请求当中");//处理请求String username = req.getParameter("username");String password = req.getParameter("password");String[] hobbies = req.getParameterValues("hobbies");System.out.println("姓名:"+username);System.out.println("密码:"+password);System.out.println(Arrays.toString(hobbies));//将hobbies数组进行打印//作出回应,进入处理页面resp.sendRedirect("/HttpResponse/sucess.jsp");}
后端配置----绑定Servlet
<web-app><servlet><servlet-name>RequestDemo</servlet-name><servlet-class>com.zhangtao.Servlet.RequestDemo</servlet-class></servlet><servlet-mapping><servlet-name>RequestDemo</servlet-name><url-pattern>/request</url-pattern></servlet-mapping>
</web-app>
前端处理页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>成功处理请求</title>
</head>
<body><h2>请求成功处理</h2>
</body>
</html>
2.请求转发
//Java程序
public class RequestDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("进入这个请求当中");//处理请求String username = req.getParameter("username");String password = req.getParameter("password");String[] hobbies = req.getParameterValues("hobbies");System.out.println("姓名:"+username);System.out.println("密码:"+password);System.out.println(Arrays.toString(hobbies));//将hobbies数组进行打印//通过请求转发req.getRequestDispatcher(req.getContextPath()+"/sucess.jsp").forward(req,resp);req.setCharacterEncoding("utf-8");/***在请求转发的时候,会出现404现象这个时候往往是把项目名也输入进去请求转发不需要项目名,而“/”代表的是当前的web应用*/}
请求转发与重定向的区别:
相同点:
页面都会实现跳转
不同点:
- 请求转发的时候,url不会发生变化:307
- 重定向的时候,URL地址栏会发生变化:302
- 请求转发不需要项目名,重定向需要项目名
7、Cookie、Session
Cookie:
Session:会话
一个网站怎么证明你来过?
客户端 服务端
1.服务端给客户端一个信件,客户端下次访问服务端带上信件即可;(信件----cookies)
2.服务器登记你来过,下次你来的时候我来匹配你;session
7.1、会话
会话:用户打开一个浏览器,点击了很多的链接,访问多个web资源,关闭浏览器,这个过程就是会话。
**有状态会话:**客户端再次访问服务器,我们知道这个客户端来过,我们称这个过程为有状态过程。
7.2、保存会话的两种技术
Cookie
客户端技术(响应,请求)
Session
服务端技术;利用这个技术,可以保存用户的会话信息,我们可以将信息或者数据保存在Session中。
常见例子:网站登录之后,你下次就不用再登录,可以直接进去。
7.3、Cookie
1.从请求中拿到信息
2.服务器响应给客户端cookie
Cookie[] cookie = req.getCookies();//获得Cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie中的value
new Cookie("lastLoginTime",System.currentTimeMillis()+"");
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.encoder("","UTF-8")
解码
URLDecoder.decoder("","UTF-8");
7.4、Session(重点)
什么是Session?
- 服务器会给每一个用户(浏览器)创建一个Session;
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就会一直存在;
- 用户登录之后,整个网站都可以访问到–>保存用户的信息,保存购物车的信息等…
1、Session共享数据
之前Servlet共享数据是servletContext,但是如果数据过多的话,会引起服务器卡顿现象。
使用Session比较好
//ServletDedmo1
package com.Servlet.Session;import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;public class SessionDemo extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决乱码问题req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html; charset=UTF-8");//得到SessionHttpSession session = req.getSession();//往Session中存东西session.setAttribute("username1","张韬");//也可以通过其他类来存取键值对session.setAttribute("username2",new Person(1,"张韬"));//获取Session的IDString id = session.getId();//判断Session是不是新创建的if(session.isNew()){resp.getWriter().write("session创建成功:"+id);}else{resp.getWriter().write("session已经存在了ID::"+id);}//Session创建的时候做了什么事情Cookie cookie = new Cookie("JSESSIONID", id);resp.addCookie(cookie);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
//ServletDemo2
package com.Servlet.Session;import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;public class SessionDemo2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//解决乱码问题req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html; charset=UTF-8");//得到SessionHttpSession session = req.getSession();//获取Session中的数据String username1 = (String)session.getAttribute("username1");System.out.println(username1);//获取Session中存储的数据(通过其他类新建的键值对)Person person = (Person)session.getAttribute("username2");System.out.println(person.toString());/*** 这里之前是同时向Session中存储两个数据,不知道为何之前会报错500以及404问题* 有待之后再进行验证*/}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
//Person
package com.Servlet.Session;public class Person {private int age;private String username;public Person() {}public Person(int age, String username) {this.age = age;this.username = username;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}//为了调试方便,都会加上一个toString()@Overridepublic String toString() {return "Person{" +"age=" + age +", username='" + username + '\'' +'}';}
}
2、Session消除、注销
//ServletDemo3
package com.Servlet.Session;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 SessionDemo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获得sessionHttpSession session = req.getSession();//消除Session中的数据session.removeAttribute("username");//手动注销sessionsession.invalidate();/*** 注销就是相当于关闭这个请求*/}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}
注意:Session注销就是相当于关闭这个请求,原因:之前的SessionID被注销掉了,所以没有办法使用。
所以如果想要使用的话,那么就只能进行另一次请求。
会话自动过期,使用web.xml
<!--设置Session的时效--><session-config><!--15分钟后,session就会自动失效,单位为分钟--><session-timeout>15</session-timeout></session-config>
注意:这个session-config在里面也是可以配置cookie的,所以还需要进行操作。
3、Session和Cookie的区别
- Cookie是把用户的数据写给用户的浏览器,保存地址是浏览器(可以保存多个);
- Session把用户的数据写到用户独占的Session中,保存地址是服务器端(保存重要的信息,减少服务器资源的浪费);
- Session对象由服务器创建;
注意:还是有待测试;
3.1、详情图对比
Cookie详情
Session详情
ServletContext
注意:如果是两个人或者是多个人一起使用同一个资源的话,那么Session就不再适用(可能会占有很多的空间),这个时候使用ServletContext比较好。这个在之后也被成为applicationContext。
使用场景:
- 保存一个登陆用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,我们将它保存在Session中;
JavaWeb---Tomcat---Servlet相关推荐
- JavaWeb+Tomcat+Servlet使用<c:foreach>标签时,jsp等网页文件获取不到request域中的数据
自己也是刚学习就遇到了这个问题,上网找了两天,弄清楚了就分享出来 我的各个文件都没有报错,而且 jdk 和 jstl 的版本,web.xml 的版本都没什么问题,而且也能获取数据库中的数据,但是使用 ...
- JavaWeb:tomcat服务器安装总结及Http协议
JavaWeb:tomcat服务器安装总结 目录 JavaWeb:tomcat服务器安装总结 一:服务器端概述: 二:Tomcat下载: 三:安装: 四:HTTP问题: 五:深入了解tomcat服务器 ...
- javaweb(07) Servlet详解
javaweb(07) Servlet详解 什么是Servlet 简介 从广义上来讲,Servlet规范是Sun公司制定的一套技术标准,包含与web应用相关的一系列接口,是web应用实现方式的宏观解决 ...
- 基于javaweb+JSP+Servlet简单购物车
基于javaweb+JSP+Servlet简单购物车 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练习,学习演示等 public ...
- 基于javaweb+JSP+Servlet电影票售票管理系统
基于javaweb+JSP+Servlet电影票售票管理系统 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练习,学习演示等 } ...
- 基于javaweb+JSP+Servlet在线商城鲜花花卉商城(前台、后台)
基于javaweb+JSP+Servlet在线商城鲜花花卉商城(前台.后台) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练习, ...
- 基于javaweb+JSP+Servlet在线商城购物商城服装商城(前台、后台)
基于javaweb+JSP+Servlet在线商城购物商城服装商城(前台.后台) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练 ...
- 基于javaweb+JSP+Servlet学生成绩管理系统(管理员、教师、学生)
基于javaweb+JSP+Servlet学生成绩管理系统(管理员.教师.学生) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练 ...
- 基于javaweb+JSP+Servlet学生在线选课系统(管理员、教师、学生)
基于javaweb+JSP+Servlet学生在线选课系统(管理员.教师.学生) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练 ...
- 基于javaweb+JSP+Servlet网上书店图书商城(前台、后台)
基于javaweb+JSP+Servlet网上书店图书商城(前台.后台) 开发工具:eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计,大作业,毕业设计,项目练习,学习 ...
最新文章
- t-SNE(t-distributed stochastic neighbor embedding)
- 地壳中元素含量排名记忆口诀_【中考化学】初中化学记忆性知识点03-生活中的化学-生活常识...
- python中如何调用或修改元组中的元素_python 元组的使用方法
- 云重磅 | 没有硬件,苹果发布多款“云服务”;阿里云发布基于公共云的虚拟GPU服务;中国移动首发5G套餐...
- B-Tree及其建立过程
- mongoDB 3.0以前版本 - 入门指南、示例
- git学习(四)比较文件差异diff
- 转帖:Three Ways to Inject Your Code into Another Process
- 深度学习样本标完后图片增强标签内容不变
- 人生成功的十大说话技巧
- VIM 快捷键汇总(持续更新)
- 3D打印是什么?如何工作的?
- windows11 截屏键无法使用 Print screen
- 【H5钢琴示例代码】
- 三菱触摸屏怎么改时间_三菱触摸屏时钟设置步骤
- 总结学过的技术,实现加密注册,登录及过期不能访问,微信朋友圈功能,文章比较长,但是比较详细。
- 【转载】WPS通过设置密码的方式对Excel文件加密
- 清理工作区git clean -fd
- 外报分析中国房价上涨三原因 指开发商行为怪异
- 护肤品买了这么多还是不见好转,钱都去哪里了?
热门文章
- 嫌画笔长得不好看,今天教你如何隐藏Python画笔!
- [转]ISE ChipScope使用
- 用C++编写一个模拟战争的游戏
- 通过ROS控制真实机械臂(7)---三次样条插补
- 微信小程序1,常用组件 view、swiper、swiper-item、 scroll-view、 icon、progress、text、rich-text、button、input、image
- Java不适合做爬虫?试试这个工具!
- 内迁,沿海地理优势在劳动密集型产业中已不存在。中西部人将有望更多地在家乡工作。深圳只会是记忆。...
- 精彩的2009已经悄然离开,充满期待的2010年正向我走来。
- MotionBuilder-动作整合-Story(一)
- Gwt第三方组件、框架介绍