【Servlet、Cookie和Session】

Servlet的实现

学习导图

Servlet导图

Servlet简介

Servlet是Server与Applet的缩写,是服务端小程序的意思。使用Java语言编写的服务端程序,可以像生成动态的WEB页,Servlet主要运行在服务器端,并由服务器调用执行,是一种按照Servlet标准来开发的类,是SUN公司提供的一门用于开发动态Web资源的技术。
Servlet本质上也是Java类,但要遵循Servet规范进行编写,没有main()方法,它的创建、使用、销毁都由Servlet容器进行管理(如Tomcat)
Servlet是和HTTP协议是紧密联系的,其可以处理HTTP协议相关的所有内容。这也是Servlet应用广泛的原因之一。

Servlet的实现【@WebServlet注解】

【实现步骤】

  1. 在Web项目下创建包中的java类
package com.xxxx.servlet;
public class Servlet01{
}
  1. 实现Servlet规范
    实现Servlet规范,即继承HttpServlet类,并到如响应的包,该类中已经完成了通信的规则,我们只需要进行业务的实现即可。
package com.xxxx.servlet;
import javax.servlet.http.HttpServlet;
public class Servlet01 extends HttpServlet{
}
  1. 重写service方法
    满足Servlet规范只是让我们的类能够满足接收请求的要求,接收到请求后需要对请求进行分析,以及进行业务逻辑处理,计算出结果,则需要添加代码,在规范中有一个叫做service的方法,专门用来做请求处理的操作,业务代码则可以写在该方法中。
package com.xxxx.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 Servlet01 extends HttpServlet{
	@Override
	protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Hello Servlet!");
		resp.getWeriter().write("Hello World!");
	}
}
  1. 设置注解
    在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源。
    开发servlet项目,使用 @WebServlet 将一个javax.servlet.http.HttpServlet的类定义为Servlet组件。在Servlet3.0中,可以使用@WebServlet注解将一个继承于javax.servlet.http.HttpServlet的类标注为可以处理用户请求的Servlet。
package com.xxxx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/s02")//在浏览器中输入的url添加上/s02可以直接访问到当前的Servlet动态资源
public class Servlet01 extends HttpServlet{
	@Override
	protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Hello Servlet!");
		resp.getWeriter().write("Hello World!");
	}
}

【后端操作通过@WebServlet与前端交互】
前端创建一个与上面Servlet类(通过下面的标签s02)相关联的jsp界面,其中前端数据会自动通过Tomcat服务器传入后端,后端可以通过request.getParamer("uname");request.getParamer("upwd");获得
在这里插入图片描述

Servlet的实现方式

  • HttpServlet继承于父类GenericServlet,故要想实现Servlet类可以继承于GenericServlet类,如:
@WebServlet("/ser01")
public class Servlet01 extends GenericServlet{
	@Override
	protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Hello Servlet!");
		resp.getWeriter().write("Hello World!");
	}
  • 实现Servlet接口
@WebServlet("/ser01")
public class Servlet01 implements Servlet{
	@Override
	protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Hello Servlet!");
		resp.getWeriter().write("Hello World!");
	}
  • doGet方法与doPost方法
@WebServlet("/ser01")
public class Servlet01 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Get请求……");
	}
	@Override
	protected void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		Sysetem.out.println("Post请求……");
	}

结论最常用的还是继承HttpServlet类并重写service方法。

Servlet的生命周期

简介Servlet没有main()方法,不能独立运行,它的运行完全由Servlet引擎来控制与调度。所谓生命周期,指的是servlet容器何时创建servlet实例何时调用其方法进行请求的处理何时并销毁其实例的整个过程

  • 实例和初始化时机
    当请求到达容器时,容器查找该servlet对象是否存在,如果不存在,则会创建实例并进行初始化。
//init方法,在Servlet实例创建后执行(证明该Servlet有实例创建了)
public void init(ServletConfig config)thows ServletException{
	System.out.println("实例创建了……");
}
  • 就绪/调用/服务阶段
    有请求到达容器,容器调用servlet对象的service()方法,处理请求的方法在整个生命周期中可以被多次调用;HttpServlet的service()方法,会依据请求方式来调用doGet()或者doPost()方法。但是,这两个do方法默认情况下,会抛出异常,需要子类去override。
//service方法,每次有请求到达某个Servlet方法时执行,用来处理请求(证明该Servlet进行服务了)
protected void service(HttpServletRequest req,HttpServletResponse resp)thows ServletException,IOException{
	System.out.println("服务调用了……");
}
  • 销毁时机
    当容器关闭时(应用程序停止时),会将程序中的Servlet实例进行销毁。
//destroy方法,Servlet实例销毁时执行(证明该Servlet的实例销毁了)
public void destroy(){
	System.out.println("实例销毁了……");
}

上述的生命周期可以通过Servlet中的生命周期方法来观察。在 Servlet中有三个生命周期方法,不由用户手动调用,而是在特定的时机有容器自动调用 ,观察这三个生命周期方法即可以观察到Servlet的生命周期。

时序图与说明
时序图

  1. Web Client向Servlet容器(Tomcat)发出Http请求
  2. Servlet容器接收Web Client的请求
  3. Servlet容器创建一个HttpServletResquest对象(上面的req,将Web Client请求的信息封装到这个对象中都是Servlet容器自动创建自动封装的
  4. Servle容器创建一个HttpServletResponse对象(上面的resp都是Servlet容器自动创建自动封装的
  5. Servlet容器调用HttpServlet对象service方法,把Request(req)和Response(resp)作为参数,传给HttpServlet
  6. HttpServlet调用HttpServletRequest对象的相关方法,获取Http的请求信息
  7. HttpServlet调用HttpServletResponse对象的相关方法,生成响应数据
  8. Servlet容器把HttpServlet的响应结果传给Web Client

HttpServletRequest对象

简介

HttpServletRequest对象:主要作用是 用来接收客户端发送过来的请求 ,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service()方法中形参接收的是HttpServletRequest接口的实例化对象,表示该对象主要应用在HTTP协议上,该对象是由Tomcat封装好传递过来的。
在HttpServletRequest接口中,定义的方法很多,但都是围绕接收客户端参数的。但是怎么拿到该对象呢? 不需要,直接在Service方法中由容器传入过来,而我们需要做的是取出对象中的数据,进行分析,处理。

常用方法

下面的request和respose即是req和resp

方法

请求参数获取

在这里插入图片描述

请求乱码问题

由于现在的request属于接收客户端的参数,所以必然有其默认的语言编码,主要是由于在解析过程中默认使用的编码方式为ISO-8859-1(不支持中文),所以解析时一定会出现乱码。要想解决这种乱码问题,需要设置request中的编码方式,告诉服务器以何种方式来解析数据。或者在接收到乱码数据以后,再通过相应的编码格式还原。

  • 方式一:request.setCharacterEncoding("UTF-8")这种方式只针对POST有效(必须再接收所有的数据之前设定
  • 方式二:new String(request.getParamer(name).getBytes("ISO-8859-1"),"UTF-8"),对任何请求方式都有效,是通用的。
  • 注意:Tomcat8以后的GET方式请求时不会出现乱码的。

请求转发

请求转发,是一种服务器行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL地址不会改变 ,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出,实现方式如下,达到多个资源协同响应的效果。【通俗来说,就是能实现页面跳转页面跳转后能数据都相互传递共享
request.getRequestDispatcher(url).forword(request,response);
request.getRequestDispatcher(s02).forword(request,response);//Servlet之间数据共享,要是标签为s01使用此语句,则s01获得的请求参数或数据会共享给s02
request.getRequestDispatcher(login.xml).forword(request,response);//共享界面,可以使得当前的Servlet共享login.xml页面(相当于跳转)

request作用域

通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效【即要搭配请求转发语句一起使用,如下:
作用域对象
Servlet05:
在这里插入图片描述
Servlet06:
在这里插入图片描述
此时Servlet05的数据就可以共享给Servlet06了,同理也可以将Servlet05的数据共享给jsp页面

request域对象中的数据在一次请求中有效,则经过请求转发,request域中的数据依旧存在,则在请求转发的过程中可以通过request来传输/共享数据。

HttpServletResponse对象

简介

Web服务器收到客户端http请求,会针对每一次请求,风别创建一个用于用于代表请求的request对象和代表响应的response对象。
request和response对象代表请求和响应:获取客户端数据,需要通过request对象;向客户端输出数据,需要通过response对象
HttpServletResponse的主要功能用于服务器对客户端的请求进行响应,将Web服务器处理后的结果返回给客户端。service()方法中的形参接收的是HttpServletResponse接口的实例化对象,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法

响应数据

接收到客户端请求后,可以通过HttpServletResponse对象进行响应,响应时候需要获取输出流有两种形式:

  • getWriter()获取字符流(只能响应回字符)使用PrintWriter writer = response.getWriter();writer.write("Hello");
  • getOutputStream()获取字节流(能响应一切数据)使用ServletOutputStream out = response.getOutputStream();out.write("Hi".getBytes());
  • 两者不能同时使用

响应乱码问题

在响应中,如果我们响应的内容中含有中文,则有可能出现乱码,这是因为服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则会出现乱码。

  • getWriter()的字符乱码
    在这里插入图片描述

  • getOutputStream()的字符乱码
    在这里插入图片描述
    【注意】可以同时设置客户端和服务端的编码方式,上面两种情况都通用,一般用这种方式response.setContentType("text/html,charset=UTF-8");

重定向

重定向是一种服务器指导,客户端行为(1)、(客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址下次请求的地址response.sendRedirect(url或.jsp);//重定向跳转到url或.jsp), (2)、 当客户端接收到响应后,会立刻、马上、自动根据服务器给的新地址发起第二个请求,服务器接收请求并做出响应,重定向完成

重定向与请求转发的区别

区别

Cookie对象

简介

Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保留在客户端,或者在客户端进行处理的数据,放在本地的计算机上,不需要通过网络传输,因而 提高网页处理的效率,并且能够减少服务的负载,但是由于Cookie是服务器端保存在客户端的信息,所以安全性也是很差的。例如常见的记住密码则可以通过Cookie来实现。
有个专门操作Cookie的类javax.servlet.http.Cookie.随着服务器端的响应发送给客户端,保存在浏览器。当下次再访问服务器时把Cookie再带回服务器。
Cookie的格式:键值对用"=“链接,多个键值对通过”;"隔开。

Cookie的创建和发送

通过new Cookie("key","value");来创建一个Cookie对象要想将Cookie随响应发送到客户端,需要先添加到response对象中response.addCookie(cookie);此时该cookie对象则随着响应发送至了客户端。在浏览器上可以看见。

//创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
//发送Cookie对象
response.addCookie(cookie);

Cookie的获取

在服务器端只提供了一个getCookie()的方法用来获取客户端回传的所有cookie组成的一个数组,如果需要获取单个cookie则需要通过遍历getName()获取Cookie的名称getValue()获取Cookei的值

//获取客户端传来的Cookie数组
Cookie[ ] cookies = request.getCookiees();
//判断数组是否为空
if(cookies !=null&&cookies.length>0){
	//遍历Cookie数组
	for(Cookie cookies:cookies){
		System.out.println(cookie.getName());
		System.out.println(cookie.getValue());
	}
}

Cookie设置到期时间

除了Cookie的名称和内容外我们还需要关心一个信息,到期时间,到期时间用来指定cookie何时失效默认为当前浏览器关闭即失效。我们可以手动设定cookie的有效时间(通过到期时间计算),通过setMaxAge(int time);方法设定cookie的最大有效时间,以秒为单位.
【到期时间取值】

  1. 负整数
    若为负数,表示不存储cookie。
    cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活,一旦关闭浏览器,那么cookie就会消失。
  2. 正整数
    若大于0的整数,表示存储的秒数。
    表示cookie对象可存活指定的秒数。当生命大于0时,浏览器会把Cookie保存在硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活相应的时间。

  3. 若为0,表示删除该cookie
    cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。

Cookie的注意点

  1. Cookie保存在当前浏览器中。
    在一般的站点中常常有记住用户名这样的操作,在操作只是将信息保存在本机上,换电脑以后这些信息就无效了。而且cookie还不能跨浏览器。
  2. Cookie存在中文问题
    Cookie中不能出现中文,如果有中文则通过URLEncoder.encode()来进行编码,获取时通过URLDecoder.decode()来进行解码。
String name = "姓名";
String value = "张三";
//通过URLEncoder.enode()来进行编码
name = URLEncoder.encode(name);
value = URLEncoder.encode(value);
//创建Cookie对象
Cookie cookie = new Cookie(name,value);
//发送Cookie对象
response.addCookie(cookie);


//获取时通过URLDecoder.decode()来进行解码
URLDecoder.decode(cookie.getName());
URLDecoder.decode(cookue.getValue());

  1. 同名Cookie问题
    如果服务器端发送重复的Cookie(同名的Cookie)那么会覆盖原有的Cookie。
  2. 不同的浏览器对Cookie也有限定,Cookie的存储是有上限的。Cookie是存储在客户端(浏览器)的,而且一般是由服务器端创建和设定。后期结合Session来实现会话跟踪。

Cookie的路径

在这里插入图片描述
在这里插入图片描述

HttpSession对象

Session概述

在这里插入图片描述
在这里插入图片描述

标识符JSESSIONID

JSESSIONID

session域对象

【概述】Session用来表示一次会话,在一次会话中数据是可以共享的【与request域对象只能实现一次请求数据共享不同的是,只要是在一次会话中(同一个session)session可以实现多个请求的数据共享,这时候session作为域对象存在,可以通过setAttribute(name,value)方法向域对象中添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据。

//获取session对象
HttpSession session = request.getSession();
//设置session域对象
session.setAttribute("uanme","admin");
//获取指定名称的session域对象
String uname = (String)request.getSession().getAttribute("uname");
//移除指定名称的session域对象
session.removeAttribute("uname");

………………………………………………………………session实现共享数据…………………………………………………………
@WebServlet("/s02")
public class Servlet01 extends HttpServlet{
	@Override
	protected void service(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
		//获取session对象
		HttpSession session = request.getSession();
		//设置session域对象
		session.setAttribute("uanme","admin");
		session.setAttribute("upwd","123");
		//移除指定名称的session域对象
		session.removeAttribute("upwd");

		//请求转发跳转到jsp页面
		request.getRequestDispatcher("index.jsp").forward(request,response);
		//重定向到jsp页面
		response.sendRedirect("index.jsp");
	}
}

index.jsp代码如下:
在这里插入图片描述
【结果】:无论是请求转发还是重定向到index.jsp页面,session域对象中的数据都是能够共享的。

注意:数据存储在session域对象中,当session对象不存在了,或者是两个不同的session对象时,数据也就不能共享了。这就不得不谈到session的生命周期了。

session对象的销毁

【概述】:登录一个网站,过了一段时间不操作,浏览器会提醒 “登录过时请重新登录”,这就说明session已经失效了。其中sessoin的有效时间有下面几种情况:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ServiceContext对象

【简介】
在这里插入图片描述
【ServletContext对象的创建以及一些常用方法】
在这里插入图片描述
【ServletContext域对象】
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值