Java Web专题攻关
servlet概念
servlet其实就是运行在服务器的一个小程序
如何去理解呢?我们访问服务器的资源包括静态资源和动态资源,其中静态资源是我们放置的模板,CSS、JS等文件,是不变的。而我们访问的动态资源,是根据我们访问的请求路径,路由到指定的类去加载,运行其对应的方法而给出浏览器资源的响应。那么凭什么我们的服务器会帮我们去加载,去运行指定的方法呢?或者说服务器是怎么做到的呢?我们一定是需要遵循服务器某些规则才行的,而规则在 Java 中 就是接口,Servlet就是被服务器(Tomcat)识别的接口,我们需要根据这个接口来定义响应的方法。
快速入门
创建一个 Java EE 项目,定义一个类,实现 Servlet 接口
public class ServletDemo1 implements Servlet
实现接口中的抽象方法
在web.xml中配置 Servlet
<!-- 配置Servlet -->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>org.taoguoguo.web.ServletDemo1</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
Servlet执行原理:
- 当服务器接受客户端浏览器的请求后,会解析请求的URL路径,获取访问Servlet的资源路径
- 查找web.xml文件,是否有对应的
<url-pattern>标签体内容 - 如果有,则会找到对应的
<servlet-class>全类名 - tomcat 会将字节码文件加载进内存,并且创建其对象
- 调用其方法
Servlet中的生命周期:
被创建:执行 init 方法,只执行一次
Servlet 什么时候被创建?
默认情况下, 第一次访问时,Servlet被创建
可以配置Servlet的创建时机,如下:
<!-- 配置Servlet -->
<servlet>
<servlet-name>demo2</servlet-name>
<servlet-class>org.taoguoguo.web.ServletDemo2</servlet-class>
<!--指定Servlet的创建时机
1.第一次被访问时创建,创建
<load-on-startup>的值为负数,默认为 -1,或者不配置 也是在第一次访问被创建
2.在服务器启动时,创建
<load-on-startup>的值为0或正整数 一般设置为 1
-->
<load-on-startup>-1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>demo2</servlet-name>
<url-pattern>/demo2</url-pattern>
</servlet-mapping>
注意:Servlet的 init 方法只执行一次,说明servlet在内存中只存在一个对象,是单例的,所以多个用户线程同时访问时,可能存在线程安全问题。解决方案:1.尽量不要在Servlet中定义成员变量,因为成员变量时每个线程共享的资源,可能有的线程会修改,而部分线程会去获取,容易出现数据安全问题。尽量在方法内部定义局部变量代替成员变量。因为局部变量是在每个线程方法栈中独享的一份资源,可以保证数据安全性。2.如果必须要定义成员变量,不要在方法中去修改成员变量的值,仅用于线程获取,是不会有线程安全问题的。3.在servlet解决多线程安全问题时,切记使用同步锁,因为会非常的消耗性能
提供服务: 执行 service 方法,执行多次
- 每次访问 Servlet 时,service 方法都会被调用一次
被销毁:执行 destory 方法,只执行一次
- servlet 被销毁时执行,只有服务器正常关闭时,servlet 被销毁 才会执行destory 方法。destory 是在被销毁之前执行,一般用于释放资源
Servlet 3.0:
支持注解配置,可以不需要web.xml了
使用方法:在创建的servlet 上 加上注解
@WebServlet("资源路径"),支持如下写法@WebServlet(urlPatterns = "/demo3")@WebServlet("/demo3")
HTTP
概念:
Hyper Text Transfer Protocol 超文本传输协议
传输协议:
定义了 客户端 和 服务器端通信时,发送数据的格式
特点:
1.基于TCP/IP的高级协议(安全的,需要经过三次握手)
2.默认端口号:80
3.基于 请求/响应 模型 (请求响应 一 一 对应,一次请求,一次响应)
4.无状态的:每次请求之间相互独立,不能交互数据
历史版本:
1.0:每一次请求,建立一次新的连接
1.1: 复用连接,对缓存性能较好
请求消息数据格式:
请求行
组成格式:请求方式 请求url 请求协议/版本
请求行: GET /login.html HTTP/1.1
HTTP协议有7种请求方式,常用的有两种请求头
GET
请求参数在请求行中,在url后。
请求的url长度有限制
相对安全
POST
请求参数在请求体中
请求的url是没有限制的
相对安全
请求头(客户端告知服务端自身信息)
组成格式: 请求头名称:请求头值
Host:localhost 当前主机
User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
//作用:服务端可以根据这个头信息区分不同浏览器解决浏览器兼容问题
Accept:告诉服务器,浏览器可以解析哪些格式类型的信息 如 text/html
Accept-Language: 告诉服务器所支持的语言环境
Accept-Encoding: 告诉服务器所支持的压缩格式
Referer:http://localhost:8080/login.html 告诉服务器,当前请求从那里来
Referer的常用场景: 1.防盗链 2.统计工作
Connection: keep-alive 连接状态 保持活跃服用
Upgrade-Insecure-Requests:1 浏览器升级信息
请求空行
- 空行,用于用于分割POST请求的请求头,和请求体的
请求体
- 封装POST请求消息的请求参数
username=zhangsan
- 封装POST请求消息的请求参数
响应消息数据格式:
服务端发送给客户端的数据
1.响应行
- 格式:协议/版本 响应状态码 状态码描述
HTTP/1.1 200 OK
响应状态码:服务器告诉客户端本次请求和响应的一个状态
状态码都是三位数字:
1xx: 服务器接收客户端消息,但是没有接收完成,等待一段时间后,发送1xx 状态码询问客户端
2xx: 成功。代表: 200
3xx: 重定向。
302(重定向) 服务器响应状态码302 并给客户端响应一个地址,客户端收到302状态码后自动请求对应地址进行重定向。 304 (访问缓存)例如请求访问图片等大二进制数据时较慢,当浏览器请求服务器,服务器返回图片资源时,浏览器会进行图片的本地缓存,当再次访问时,如果服务器资源没有变化,
并且当前浏览器存在图片缓存,可返回状态码 304 告知浏览器访问缓存,提高交互体验。
4xx: 客户端错误
404 客户端访问路径错误,未找到访问资源 - 405 请求方式没有对应的 doXXX 方法
5xx: 服务端错误
500 服务器内部异常
2.响应头
1.格式: 头名称:值
2.常见的响应头:
Content-Type: 服务器告诉客户端本次响应体数据格式及编码格式
Content-Length: 响应字节长度
Date: 响应时间
Content-disposition: 服务器告诉客户端以什么格式打开响应体数据
默认值: in-line 在当前页面打开
attachment;filename 以附件形式打开响应体,文件下载中使用
3.响应空行
4.响应体
响应体就是传输的响应数据,有整个页面的解析响应,也有二进制数据
Request
request对象和response对象的原理
- request对象和response对象是由服务器创建的,我们来使用它
- request对象是来获取请求消息,response对象是来设置响应消息的
Request对象继承体系结构
- ServletRequest -- 接口
- HttpServletRequest -- 子接口(继承 ServletRequest)
- org.apache.catalina.connector.RequestFacade 类(Tomcat)
- HttpServletRequest -- 子接口(继承 ServletRequest)
request功能:
1.获取请求消息数据
1.获取请求行数据
*GET /day14/demo1?name=zhangsan HTTP/1.1
获取请求方式:GET
String getMethod();
获取虚拟目录:/day14
String getContextPath();
获取servlet路径:/demo1
String getServletPath();
获取get方式请求参数:name=zhangsan
String getQueryString();
获取请求的URI:/day14/demo1
//URI: 统一资源标识符 共和国
//URL: 统一资源定位符 中华人民共和国
String getRequestURI(); //URI如: /day14/demo1
StringBuffer getRequestURL(); //URL如: http://localhost/day14/demo1
获取协议及版本:HTTP/1.1
String getProtocol(); //ServletRequest中的方法
获取客户机的IP地址
String getRemoteAddr();
2.获取请求头数据
String getHeader(String var1); //通过请求头的名称获取请求头的值
Enumeration<String> getHeaders(String var1); //获取所有的请求头名称
根据所有请求头获取所有的请求头对应的值:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
Enumeration<String> names = request.getHeaderNames();
while(names.hasMoreElements()){
String s = names.nextElement();
System.out.println(s +":" + request.getHeader(s));
}
}
判断浏览器版本,根据请求头
1user-agent的值来判断 是否包含指定浏览器关键字,比如Chromeuser-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
判断请求来源,用于防盗链 可根据请求头
referer的值来判断referer:http://localhost:8080/hello.html
3.获取请求体数据
请求体:只有POST请求,才有请求体,在请求体中封装了POST请求的请求参数
步骤:
1.获取流对象
BufferedReader getReader() //获取字符输入流,只能操作字符数据
获取页面表单提交数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体-请求参数
//1.获取字符流
BufferedReader br = request.getReader();
//2.读取数据
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
2.再从流对象中拿数据
ServletInputStream getInputStream() //获取字节输入流 可以操作所有类型数据 文件上传中使用
4.其他功能
1.获取请求参数通用方式:
不论是get 还是post 请求方式都可以使用下列方法来获取请求参数
String getParameter(String name) 根据请求参数获取参数值 username=zhangsan&password=123
@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post获取请求参数
String username = request.getParameter("username");
System.out.println("post");
System.out.println(username); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get获取请求参数
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);
}
}
String[] getParameter(String name) 根据请求参数获取参数值的数组 hobby=study&hobby=eat
Enumeration getParameterNames() 获取所有请求的参数名称
Map<String, String[]>getParameterMap()获取所有的请求参数和值 封装为一个Map返回
技巧:获取前台参数时,可创建一个Java Bean对象,然后使用BeanUtils.populate(Object obj,Map map)
将map集合的键值信息,封装到 Java Bean对象中
获取请求参数乱码问题
get方式:Tomcat 8 已经将get方式乱码问题解决
post方式:会乱码
解决方法:获取参数前设置一下流的编码,编码来自于请求提交页面编码格式
request.setCharacterEncoding("utf-8");
2.请求转发:
一种在服务器内部资源跳转的方式
步骤:
1.通过 request 对象获取请求转发器对象,RequestDispatcher getRequestDispatcher(String var1);
2.使用 RequestDispatcher 来进行转发:forward(ServletRequest var1, ServletResponse var2)
特点:
1.浏览器地址栏不发生变化
2.转发只能转发当前服务器的内部资源,比如不能转发到访问百度
3.转发是一次请求
3.共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据。
request域:代表一次请求,一般用于一次请求转发的访问多个资源中共享数据
方法:
1.setAttribute(String name,Object obj); 存储对象
2.Object getAttribute(String name); 通过键获取值
3.removeAttribute(String name); 通过键移除值
4.获取ServletContext
ServletContext getServletContext()
Response
功能:设置响应消息
1.设置响应行
1.格式:HTTP /1.1 200
一般是设置响应状态码 :setStatus(int sc)
2.设置响应头
setHeader(String name, String value)
3.响应体
使用步骤:
1.获取输出流
1.字符输出流:PrintWriter getWriter()
2.字节输出流:ServletOutputStream getOutputStream()
2.使用输出流,将数据输出到客户端浏览器
案例:
1.完成重定向
重定向是客户端浏览器访问服务器时,服务器响应客户端访问重定向另一个资源进行处理的过程
第一种方式:
设置响应状态码为302 response.setStatus(302);
设置响应头location 值为要跳转的路径 response.setHeader("location","/demo7");
第二种方式:
使用response对象的重定向方法: response.sendRedirect("/demo7");
重定向特点
1.地址栏发生变化
2.重定向可以访问其他站点服务器资源
3.重定向是多次请求,不能使用request域对象来共享数据
路径分类
相对路径:通过相对路径不可以确定唯一资源
- 如:./index.html
- 相对路径通常以 . 开头
- 写法规则:先确定当前资源和访问的目标资源之间的相对位置关系
- ./ 代表当前目录,也可省略 , ../ 代表上一级目录
相对目录路径写法举例:
比如一个项目,有个路径为 demo1的 Servlet,访问路径为::
http://localhost:8080/project/demo1 -> 目标资源
项目的web目录下有个index.html,访问路径为:
http://localhost:8080/project/index.html -> 当前资源
当前资源和目标资源在同一个层级上,那么从 index.html访问 demo1的路径通常为
<a href="./demo1">访问Demo1</a>当前目录的 ./ 是可以省略的,所以也可以简写为:demo1绝对路径:通过绝对路径可以确定唯一资源
如:http://localhost:8080/project/demo1 这是完整的绝对路径
也可以简写,以 / 开头的路径 如:/project/demo1 因为协议和主机端口等通常都是固定的
写法规则:判断路径是给谁用的的?如何判断,就是看请求从哪里发出。客户端发出就是给客户端用,服务端发出就是给服务端用。
给客户端使用:需要加虚拟目录(项目的访问路径),常见的比如标签,
注意,重定向本质上是两次请求,服务端给出路径资源,客户端重新发起请求,所以转发时是需要使用全路径的,通常我们会采用动态获取的方式来拿到虚拟目录。
response.sendRedirect(request.getContextPath()+"/demo7"); //比如重定向
Java Web专题攻关的更多相关文章
- Java Web专题
- 【原创】三分钟教你学会MVC框架——基于java web开发(2)
没想到我的上一篇博客有这么多人看,还有几位看完之后给我留言加油,不胜感激,备受鼓励,啥都别说了,继续系列文章之第二篇.(如果没看过我第一篇博客的朋友,可以到我的主页上先浏览完再看这篇文章,以免上下文对 ...
- Java Web 高性能开发,第 2 部分: 前端的高性能
Web 发展的速度让许多人叹为观止,层出不穷的组件.技术,只需要合理的组合.恰当的设置,就可以让 Web 程序性能不断飞跃.Web 的思想是通用的,它们也可以运用到 Java Web.这一系列的文章, ...
- Java Web 高性能开发,第 1 部分: 前端的高性能
Web 发展的速度让许多人叹为观止,层出不穷的组件.技术,只需要合理的组合.恰当的设置,就可以让 Web 程序性能不断飞跃.所有 Web 的思想都是通用的,它们也可以运用到 Java Web.这一系列 ...
- 使用Intellij idea新建Java Web项目(servlet) 原理及初步使用
准备 JDK (配置JDK_HOME\bin 和 CLASSPATH) 注:JDK8下载已经需要注册了,请使用JDK11(现在是官方长期支持的版本) 对于我们新手来说,JD ...
- 大型Java进阶专题(一) 前言
前言 各位读者好,本系列为Java进阶专题,为那些有一定工作经验,做了多年业务的码农,希望突破技术瓶颈,但没有形成系统的Java只是体系,缺乏清晰的提升方法和学习路径的人,比如作者本人.该课题的是 ...
- Java登录专题-----创建用户(一)
Java登录专题-----创建用户(一) 我来填坑了 创建用户 入参 应该包括: 用户姓名,用户密码,用户手机号,用户所属机构 用户版本号,角色id 出参: 没有 数据结构: JavaBean ...
- 高效 Java Web 开发框架 JessMA v3.5.1
JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate.MyBatis 与 J ...
- 高效 Java Web 开发框架 JessMA v3.4.1
JessMA 是功能完备的高性能 Full-Stack Web 应用开发框架,内置可扩展的 MVC Web 基础架构和 DAO 数据库访问组件(内部已提供了 Hibernate.MyBatis 与 J ...
- java web 之客户关系管理系统
这个周末真的是觉得自己学会了一个比较高大上的本领,为什么这么觉得呢?那是因为星期六的时候觉得自己可以看看源码能做出来,可是让我头疼的是花费了一上午的时间还是没有弄出来,还好上天给了我机会,要是没有老师 ...
随机推荐
- 制作visual studio 离线安装包
应用场景:脱机.内网环境安装vs开发环境. 概述:在互联网环境下载安装工具,下载根据需求并缓存布局(类似功能模块),压缩缓存内容拷贝至离线环境进行安装. 1.官网下载指定版本的vs安装客户端 创建基于 ...
- Polar靶场web刷题记录
Polar靶场 web刷题记录 简单部分 swp 考点:敏感文件.preg_match()函数绕过 根据题目名提示 访问 /.index.php.swp 可以用代码格式化工具美化一下 function ...
- 全网最适合入门的面向对象编程教程:03 类和对象的Python实现-为自定义类添加属性
摘要: 本文主要介绍了,当使用 Python 创建自定义类时,如何为其添加属性,包括为类和实例添加属性两种,以及如何获取自定义的属性等内容. 往期推荐: 学嵌入式的你,还不会面向对象??! 全网最适合 ...
- oeasy 教您玩转 linux 010400 总结 summary
###### 上一部分我们都讲了什么?* 各种gui* qt和gdk两个开源工具跨平台开发库* 发行版和gui之间的关系###### 我们一起来回顾一下整个学习过程* 我们从零开始* ...
- vscode取消json文件注释下划线
使用 vscode 打开一个json文件,如果有单行或多行注释,则会显示红色下划线,解决办法如下: 方法1 点击底部的JSON,选择 JSON with Comments 即可,然后红色下划线消失,底 ...
- freemarker+minio实现页面静态化
什么是页面静态化? 将原本动态生成的网页内容通过某种形式转化为html并存储在服务器上,当用户请求这些页面时就不需要执行逻辑运算和数据库读 优点: 性能:提高页面加载速度和响应速度,还可以减轻数据库. ...
- 一次url请求全过程
一次url请求全过程 1,从宏观总体来看url请求全流程 2,从家庭实际网络架构来看一看网络是如何搭建和传输的 3,从网络七层协议的角度来看一看网络在各个层次之间的传输过程 4,从三次握手四次挥手的角 ...
- python变量 方法 属性
python变量 方法 属性 所有成员中,只有普通变量/字段/属性的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通变量/字段/属性.而其他的成员,则都是保存在类中,即:无论对象的多 ...
- 【Java】Input,Output,Stream I/O流 02 文件流 & 缓冲流
Reader & Writter 只适合文本的输入输出 [.txt .java .c .cpp] 传输文件,不能使用文本IO进行读写,需要使用文件输入输出流 public class IOTe ...
- 【Java】POI Excel导出 动态行合并
一般情况: Excel导出一般都是一行一行的记录输出 . 这是Controller代码: 标题行的设置: 标题行会设置获取的结果集的字段名,数据会自动根据设置的名称匹配装填 特殊的需求: 如页面的效果 ...