学习笔记之Servlet

本文主要是学习Javaweb做的学习笔记,对应张宇鹏老师讲课视频的笔记,另外参考了 刘扬俊的博客(https://blog.csdn.net/qq_19782019/article/details/80292110)。如果需要引用,请引用原始文献。

1.Servlet概念


Servlet是用Java编写的服务器端程序,主要功能是在于交互地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指实现了这个Servlet接口的类,一般情况下,我们理解为后者。

2.Servlet API


  1. javax.servlet 其中包含定义servlet和servlet容器之间契约的类和接口。
  2. javax.servlet.http 其中包含定义HTTP Servlet 和Servlet容器之间的关系。
  3. javax.servlet.annotation 其中包含标注servlet,Filter,Listener的标注。它还为被标注元件定义元数据。
  4. javax.servlet.descriptor,其中包含提供程序化登录Web应用程序的配置信息的类型。

3.Servlet的工作原理


  1. 当用户发来请求时,TomCat服务器调用对应的Servlet,执行service方法,同时会传入一个ServletRequest对象和一个ServletResponse对象。
    ServletRequest对象和ServletResponse对象由Tomcat服务器封装好了,不需要我们实现。
    ServletRequest对象中封存在此次HTTP请求。ServletResponse对象表示此次请求对应的响应。
  2. Servlet根据客户端请求生成响应内容并将其传给服务器
  3. 服务器将响应返回客户端

具体的实现过程:
在这里插入图片描述

4.Servle的生命周期


Servlet生命周期是:从第一次调用到服务器关闭的过程。但是web.xml文件中如果配置了load-on-startup,Servlet的生命周期就是 从服务器开启到服务器关闭

web.xml文件的配置如下代码:

<!--配置Servlet  -->
 		<!--配置servlet类路径  -->
 		<servlet>
 			<servlet-name>first</servlet-name>
 			<servlet-class>com.ouc.servlet.firstServlet</servlet-class>
 			<load-on-startup>1</load-on-startup>
 		</servlet>
 		<!--配置访问方式  -->
 		<servlet-mapping>
 			<servlet-name>first</servlet-name>
 			<url-pattern>/first</url-pattern>
 		</servlet-mapping>

Servlet生命周期中有两个重要的方法:init()方法和destory()方法。

注意:
init()方法是对Servlet进行初始化的一个方法,在Servlet第一次被请求,加载进行存储时执行。
destory()方法是在Servlet被销毁时执行,也是Tomcat关闭时执行。

代码示例:

public class ServletLife extends HttpServlet {
	//初始化方法,在servlet第一次加载内容的时候被调用
	@Override
	public void init() throws ServletException {
		System.out.println("servlet初始化完成");
	}
	//service方法,真正处理请求的方法
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.getWriter().write("servlet life");
		System.out.println("servlet life");
	}
	@Override
	public void destroy() {
		System.out.println("我被销毁了...");
	}
}

5.Service()、doGet()和doPost()的区别


不管是get请求还是post请求,如果Servlet类中有service方法,优先调用Servic方法。在没有service()方法的情况下,get请求调用doGet()方法,post请求调用doPost()方法。

注意:
如果在覆写service方法中调用了父类的service()方法(super.service(arg0,arg1)),在service方法处理完之后,会再次根据请求方式响应doGet()方法和doPost()方法。因此一般情况下,不覆写service中调用父类的service方法。

6.Request对象


浏览器发起请求到服务器,会遵循Http协议将请求数据发送给服务器。服务器接受到请求数据会使用request对象进行存储,服务器每接受到一个请求,就会创建一个request对象来存储此次的请求数据。

HTTP请求格式:

  • 请求行:请求方式、请求的地址和HTTP协议版本。
  • 请求头:消息报头,一般是用说明客户端要使用的一些附加信息。存储格式为键值对。
  • 空行:位于请求头和请求数据之间,空行是必须的。
  • 请求数据:非必须。
    在这里插入图片描述因此我们可以通过Request对象分别获得HTTP协议的请求行,请求头和请求体。

获取请求行数据:

  • 获取请求方式:String getMethod();
  • 获取URL:String getRequestURL();
  • 获取URI:String getRequestURI();
  • 获取HTTP协议版本:String getScheme();

获取请求头数据:

  • String getHeader(String name);
  • Enumeration getHeaderNames();

获取请求体数据:

  • String getParameter(String name) ;
  • Enumeration getParameterNames();
    //获取所有用户请求数据的键的枚举集合。

7.Response对象


在使用Request对象获取了请求数据并进行处理之后,处理的结果会通过Response对象显示到浏览器中。

HTTP的响应格式:

  • 响应行(状态行):HTTP版本、状态码、状态消息。
  • 响应头:消息包头,客户端使用的附加消息。
  • 空行:响应头和相应实体之间的,必须存在的。
  • 相应实体:服务器返回给浏览器的信息。
    在这里插入图片描述因此我们可以通过Response对象提供的方法分别设置响应行,响应头,响应体。

设置响应头:

  • setHeader(String name, String value);
  • addHeader(String name, String value);
    这两种方法,都可以在响应头中添加响应信息:setHeader方法相同键名会被覆盖,addHeader方法相同键名不会被覆盖。
    例:设置响应编码格式
    resp.setHeader(“content-type”,“text/html;charset=utf-8”);
  • sendError(int num,String msg);
    设置响应状态码

设置响应实体

  • PrintWriter getWriter()
    获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
    resp.getWriter().write(String s)
    在向客户端发送响应时,大多数都是使用该对象向客户端发送HTML。

8.Request乱码问题和Response的乱码问题


Request乱码问题:

产生乱码的原因:在页面中我们一般使用utf-8进行编码,而在service中使用的编码解码方式默认为:ISO-8859-1编码,但此编码并不支持中文。因此会出现中文乱码的问题。
解决方式:

  • 万能方式:使用String进行重新编码。
    parameter = newString(parameter.getbytes(“iso8859-1”),“utf-8”);
  • Get请求方式:分两步
    第一步:在service方法中使用req.setCharacterEncoding(“UTF-8”);
    第二步:在tomcat服务器目录下修改conf文件下找到server.xml文件,打开进行如下配置:
    添加属性:useBodyEncodingForURI=“true”
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" useBodyEncodingForURI="true"/>
  • Post请求方式:
    在service方法中使用req.setCharacterEncoding(“UTF-8”);

Response乱码问题:

解决方式:两种方式

  • resp.setContentType(“text/html;charset=utf-8”);
  • resp.setHeader(“content-Type”,“text/html;charset=utf-8”);

9.Request请求转发和作用域

Request请求转发:
服务器在接受到浏览器的请求后,仅仅使用一个servlet进行请求处理,会造成不同的Servlet逻辑代码冗余,Servlet职责不明确。可以使用请求转发解决这个问题。

 				req.getRequestDispatcher("URI").forward(request, response);
				return;

参数:
      地址:填写相对路径,直接写Servlet的别名即可
注意:
      请求转发后,直接用return结束。

请求转发的特点:

  • 一次请求;
  • 地址栏信息不会发生改变;

Request作用域

使用请求转发后,不同的Servlet之间可以使用Request对象的作用域来进行数据共享。

req.setAttribute("object name", "object value");
req.getAttribute(onject obj);//返回的是一个Obj对象,需要强转

作用域:基于请求转发,一次请求中的所有Servlet共享

10.重定向


我们考虑两种情况:

  1. 如果当前请求,Servlet不能够处理,应该怎么办呢?比如说,在淘宝购物时,我们选定商品需要付款的时候,淘宝并不能够处理付款信息,而会自动将链接跳转的支付宝平台。
  2. 如果使用请求转发,造成表单数据重复提交,怎么办呢?比如在网络比较卡的时候,我们会重复刷新,造成数据表单的重复提交。

为了解决上述两种问题,使用重定向

					response.sendRedirect("路径");
					return;

参数:
      本地路径:URI
      网络路径:定向资源的URL

重定向的特点:

  • 两次请求
  • 浏览器地址信息会发上改变
  • 避免表单重复提交

使用时机:

  • 如果请求中有表单数据,而且数据比较重要,不能重复提交
  • 如果请求被Servlet接手后,无法进行处理。

11.Cookie学习


Cookie技术是浏览器端的数据存储技术,解决了不同的请求需要使用相同的请求数据的问题。我们把请求需要共享的请求数据存储在浏览器端。

其特点为:

  1. 浏览器端的数据存储技术;
  2. 适合少量的数据;
  3. 不安全;
  4. 以键值对的形式存储。

注意:

  1. 一个Cookie对象只能存储一条数据。
  2. 默认的Cookie信息存储好之后,每次请求都会附带,除非设置有效路径

Cookie数据存储:

	//临时存储,不设置存储时间,默认为一次会话,存储在浏览器中,浏览器关闭即失效
		//创建Cookie对象
		Cookie c = new Cookie(String name, String value);
		//响应Cookie信息给客户端
		resp.addCookie(c); 
	//定时存储,设置存储时间,存储在用户电脑中
		//创建Cookie对象
		Cookie c = new Cookie(String name, String value);
		//设置Cookie的存储时间
		c.setMaxAge(3*24*3600);//设置存储时间为3天
		//设置有效路径
		c.setPath("URI")
		//响应Cookie信息给客户端
		resp.addCookie(c); 

Cookie数据获取:

//获取cookie信息
Cookie[] cks=req.getCookies();
if(cks!=null){//非空判断
	//遍历Cookie信息
	for(Cookie c:cks){
		String name=c.getName();
		String value=c.getValue();
		}
	}

12.Session学习


Request可以解决一次请求内的不同Servlet的数据共享问题。
Session可以解决一个用户的不同请求的数据共享。
原理:
用户第一次向服务器发送请求,服务器接受请求后,调用相应的Servlet进行处理,同时会给用户创建一个session对象,用来存储用户请求处理的相关公共数据,并将该session对象的JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够获取到
共享的数据。

特点:

  • 存储在服务器端
  • 服务器进行创建
  • 依赖Cookie技术
  • 一次会话
  • 默认存储时间是30分钟
//创建session对象/获取session对象
	HttpSession hs=req.getSession();
	//如果请求中拥有session的标识符也就是JSESSIONID,则返回其对应的session对象
	//如果请求中没有session的标识符也就是JSESSIONID,则创建新的session对象,并将其JSESSIONID存储到浏览器内存中
 	//如果session对象是失效了,也会重新创建一个session对象,并将其JSESSIONID存储在浏览器内存中。
//设置session存储时间
	hs.setMaxInactiveInterval(int seconds);
    //在指定的时间内session对象没有被使用则销毁,如果使用了则重新计时。
//设置session强制失效
	hs.invalidate();
//存储和获取数据
//存储:
	hs.setAttribute(String name,Object value);
//获取:
	hs.getAttribute(String name) //返回的数据类型为Object
	//存储的动作和取出的动作发生在不同的请求中,但是存储要先于取出执行。

使用时机:
一般用户在登陆web项目时会将用户的个人信息存储到Sesion中,供该用户的其他请求使用。
session失效处理:
将用户请求中的JSESSIONID和后台获取到的SESSION对象的JSESSIONID进行比对,如果一致
则session没有失效,如果不一致则证明session失效了。重定向到登录页面,让用户重新登录。
注意:
JSESSIONID存储在了Cookie的临时存储空间中,浏览器关闭即失效。

13.ServletContext对象和ServeletConfig对象

ServletContext对象

Request可以解决一次请求内的不同Servlet的数据共享问题。
Session可以解决同一个用户的不同请求的数据共享。
ServletContext不用用户的数据共享问题。

特点:

  • 服务器创建
  • 用户共享
  • 一个项目只有一个
  • 生命周期:服务器启动到服务器关闭
  • 作用域:整个项目

使用

  • 获取ServletContext对象
//第一种方式:
ServletContext sc=this.getServletContext();
//第二种方式:
ServletContext sc=this.getServletConfig().getServletContext();
//第三种方式:
ServletContext sc=req.getSession().getServletContext();
  • 整个项目内数据共享
//数据存储
	sc.setAttribute(String name, Object value);
//数据获取
	sc.getAttribute("str");//返回的是Object类型
//注意:不同的用户可以给ServletContext对象进行数据的存取。获取的数据不存在返回null。
  • 获取项目中web.xml文件中的全局配置数据
sc.getInitParameter(String name); //根据键的名字返回web.xml中配置的全局数据的值,返回String类型。 如果数据不存在返回null。
sc.getInitParameterNames();//返回键名的枚举
配置方式:
//注意 一组<context-param>标签只能存储一组键值对数据,多组可以声明多个 <context-param>进行存储。
<context-param>
  	<param-name>name</param-name>
  	<param-value>zhangsan</param-value>
</context-param>
//作用:将静态数据和代码进行解耦。
  • 获取项目webroot下的资源的绝对路径。
String path=sc.getRealPath(String path);	
//获取的路径为项目根目录,path参数为项目根目录中的路径
  • 获取webroot下的资源的流对象
InputStream is = sc.getResourceAsStream(String path);
//此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取。path参数为项目根目录中的路径
ServeletConfig对象

使用ServletConfig对象获取在web.xml中给每个servlet单独配置的数据

//获取ServletConfig对象
	ServletConfig sc=this.getServletConfig();
//获取web.xml中的配置数据
	String code=sc.getInitParameter("config");

web.xml配置:

<servlet>
    <servlet-name>ServletConfigServlet</servlet-name>
    <servlet-class>com.ouc.servlet.ServletConfigServlet</servlet-class>
    <init-param>
    	<param-name>config</param-name>
    	<param-value>utf-8</param-value>
    </init-param>
  </servlet>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值