欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Servlet基础

时间:2023-07-07
Servlet

中文乱码问题

// post方式下 设置编码,防止中文乱码// get 方式目前不需要设置编码// 需要注意的是,设置编码这一句代码必须在所有的获取参数动作之前request.setCharacterEncoding("UTF-8");

servlet的继承关系

继承关系

javax.servlet.Servlet接口javax.servlet.GenericServlet抽象类 javax.servlet.http.HttpServlet抽象子类

相关方法

javax.servlet.Servlet接口:

void init(config) - 初始方法void service(request, response) - 服务方法void destory - 销毁方法

javax.servlet.GenericServlet抽象类

void service(request,response) - 仍然是抽象的

javax.servlet.http.HttpServlet抽象子类

void service(request,response) - 不是抽象的

String method = req.getMethod 获取请求的方式

各种if判断,根据请求方式不同,决定去调用不同的do方法

在HttpServlet这个抽象类中,do方法都差不多

小结:

继承关系:HttpServlet -> GenericServlet -> ServletServlet中的核心方法:init(), service(), destory()服务方法:当有请求过来时,service方法会自动响应(其实是tomcat容器调用的)

​ 在HttpServlet中我们会去分析请求的方式:到底是get、post、head、还是delete等等

然后再决定调用哪个do开头的方法

那么再HttpServlet中这些do方法默认都是405的实现风格-要我们子类去实现对应的方法,否则就会报405错误

因此,我们新建Servlet时,我们才会考虑请求方法,从而决定重写哪个do方法

Demo01Servlet.java

public class Demo01Servlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); }}

Demo01Servlet com.atguigu.servlets.Demo01Servlet Demo01Servlet /Demo01

Servlet的生命周期

生命周期:从出生到死亡的过程就是生命周期。对应Servlet中的三个方法:init、service 、 destory

默认情况下:

第一次接受请求时,这个Servlet会进行实例化,初始化,然后服务从第二次请求开始,每一次都是服务当容器关闭时,其中的所有servlet都会被销毁通过案例发现,tomcat只会创建一个servlet实例,所有的请求都是这个实例去响应。Servlet初始化时机:可以通过设置来设置servlet启动的先后顺序,数字越小,启动越靠前,最小值为0Servlet在容器中是:单例的、线程不安全的

单例:所有请求都是个实例去响应线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。但是在中间某个时机,另一个线程改变了成员变量的值,导致第一个发生了变化我们已经知道了Servlet线程是不安全的,所以尽量不要在servlet中定义成员变量,即使定义了也不修改,不根据成员变量的值进行判断。

//演示Servlet的生命周期public class Demo02Servlet extends HttpServlet { @Override public void init() throws ServletException { System.out.println("正在初始化..."); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("正在服务..."); } @Override public void destroy() { System.out.println("正在销毁..."); }}

Demo02Servlet com.atguigu.servlets.Demo02Servlet Demo02Servlet /demo02

HTTP协议

HTTP:Hyper Text Transfer Protocol超文本传输协议。HTTP最大的作用就是确定了请求和响应数据的格式。浏览器发送给服务器的数据:请求报文;服务器返回给浏览器的数据:响应报文。Http是无状态的Http请求响应包含两个部分:请求和响应

请求:请求包含三部分:1.请求行 2、请求消息头 3、请求主体请求行包含三个信息:1.请求的方式;2.请求的URL;3、请求的协议(一般都是HTTP1.1)请求消息头包含了很多客户端需要告诉服务器的信息,比如:我的浏览器型号,版本,我能接受的内容的类型,发送的内容的类型,内容的长度等等请求体,三种情况

get方式,没有请求体,但是有一个queryStringpost方式,有请求体,form datajson格式,有请求体,request payload 响应:

响应也包含三部分:1、响应行 2.响应头 3、响应体相应行: 1.协议 2、响应状态码 3、响应状态响应头: 包含了服务器的信息;服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)响应体:响应的实际内容(比如请求add.html页面时,响应的内容就是 会话

Http是无状态的

HTTP无状态:服务器无法判断这两次请求是同一个客户端发送过来的,还是不同客户端发送过来的

无状态带来的现实问题:第一次请求是添加商品到购物车,第二次请求是结账;如果两次服务器无法区分是同一用户,那么结账就会导致混论。

通过会话跟踪技术解决无状态问题。

// 演示sessionpublic class Demo03Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取session,如果获取不到,则创建一个新的 HttpSession session = req.getSession(); System.out.println("sessionID:"+session.getId()); }}

session获取不到,则创建新的,然后响应给客户端

sessionID带给服务器,那么服务器就能获取到了,那么服务器就判断这一次请求和上次某次请求是同一个客户端,从而能够区分开客户端。

常用的API:

request.getSession -> 获取当前会话,没有则创建

request.getSession(true) ->同上

request.getSession(false) ->没有则返回false 不会创建新的

session.getId() - > 获取sessionID

session.isNew() -> 判断当前session是否是新的

session.getMaxInactiveInterval() -> session的非激活间隔时常,默认1800秒

session.invalidate()-> 强制让会话立即失效

session 保存作用域

session.setAttribute(“unname”,“lina”);session.getAttribute(“name”);

// 演示向HttpSession保存数据public class Demo04Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.setAttribute("uname","lina"); }}

public class Demo05Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Object unname = req.getSession().getAttribute("uname"); System.out.println(unname); }}

服务器内部转发以及客户端重定向

服务器内部转发:request.getRequestDispatcher("…").forward(request,response);

一次请求响应的过程,对于客户端而言,内部经过了多少次转发,客户端是不知道的 客户端重定向:response.sendRedirect("…");

两次请求响应的过程客户端肯定知道,请求的URL有变化。

这里演示的是转发

Demo06Servlet.java

public class Demo06Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("demo06..."); //服务器内部转发 req.getRequestDispatcher("demo07").forward(req,resp); }}

// 演示服务器内部转发以及客户端重定向public class Demo07Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("demo07.。。。"); }}

下面是重定向(URL发生变化,直接改为demo07)

public class Demo06Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("demo06..."); //服务器内部转发// req.getRequestDispatcher("demo07").forward(req,resp); resp.sendRedirect("demo07"); }}

Thymeleaf - 视图模板技术

保存作用域

原始情况下有四个:page(页面级别,现在几乎不用), request,session,application

request:一次请求范围

request.setAttribute("name","lili")response.sendRedirect("demo02")

request.getAttribute("name");

此时获取不到"lili" 因为重定向之后这属于两次请求了(转发则可以获取到,多次转发也可)

session:当前客户端能获取到(getAttribute(“name”))

application:最大范围,所有客户的都可以请求到(getAttribute(“name”))

//ServletContext Servlet上下文ServletContext application = request.getServletContext();

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。