servlet的学习
什么是servlet
servlet 是实现了servlet规范的java类,将其部署在servlet容器中,可以向客户端传输动态web资源。
当客户端向服务端发送了请求后,web服务器首先检查是否 已经创建了servlet的实例对象,若是没有创建,则装载并创建servlet实例对象并调用其servlet实例对象的init()方法。创建一个封装了http请求信息的HttpServletRequest对象,以及一个代表Http响应信息的HttpServletResponse对象,传入servlet重写的service方法中,调用service方法。
实现servlet类
首先在新建的web项目中新建一个java类,让此类继承servlet接口的实现类HttpServlet,并重写该类中的service方法,加上@WebServlet() 注解,注解中的属性value可以设为此资源的路径。
servlet的生命周期
servlet运行完全由servlet引擎来控制与调度。
所谓生命周期时指servlet容器何时创建servlet实例,何时调用方法进行请求的处理,何时销毁其实例的整个过程。
生命周期的各个阶段:
servlet运行完全由servlet引擎来控制与调度。
所谓生命周期时指servlet容器何时创建servlet实例,何时调用方法进行请求的处理,何时销毁其实例的整个过程。
生命周期的各个阶段:
1、实例与初始化时机: 当请求到达容器时容器查找servlet对象是否存在,不存在时创建并且初始化
2、就绪/调用/服务阶段:
有请求到达容器时,容器查找该servlet对象的service方法处理请求,在整个周期内可以多次调用
3、销毁时机:
容器关闭时,会将servlet实例进行销毁
上述生命周期可以通过servlet中的生命周期方法来观察
1、 初始化方法
public void init(ServletConfig config) throws ServletExcption
证明servlet实例被创建了 当请求到达容器时容器查找servlet对象是否存在,不存在时创建并调用初始化方法
2、
public void service(HttpServletRequest req,HttpServletResponse resp) 证明servlet进行服务了 用于处理请求,可多次调用
3、 public void destory()·
证明servlet实例被销毁了 servlet被销毁时调用
servlet生命周期可以简单概括为servlet类被加载–>实例化–>服务–>销毁
request对象
requst对象
- request对象是由servlet服务程序创建并传递至service方法中,其中包含了客户端请求的信息,包括请求的参数,
可以调用request对象中的方法对信息进行处理
String parameter = request.getParameter("uName");
System.out.println("用户名为:"+parameter);
String uPostWord = request.getParameter("uPostWord");
System.out.println("密码为:"+uPostWord);
//获取指定参数的所有值(用于复选框传值)
String[] parameterValues = request.getParameterValues("hobby");
//一般都先判断是否为空
if(parameterValues != null && parameterValues.length > 0){
for(String par :parameterValues){
System.out.println("爱好之一:"+par);
}
}
解决乱码问题:
调用request的getParamter等方法获取参数时,若是请求是get,tomcat8以上版本不会乱码,
但是post请求会乱码此时,必须设置服务端与客户端的编码格式才能解决乱码
调用request.setCharacterEncoding(“utf-8”)把编码格式设置为utf-8
可以写一个如下的jsp文件提交表单,提供这些属性进行实验
<%--
Created by IntelliJ IDEA.
User: www31
Date: 2021/2/26
Time: 11:24
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<%--action属性为servlet类所在相对地址,则在jsp文件提交属性时会跳转至servlet服务上--%>
<form method="post" action="/ser06"> </form>
姓名:<input type="text" name="uName"><br>
密码:<input type="password" name="uPostWord"><br>
<button>登录</button>
</body>
</html>
常用的HttpServletRequest对象的方法
接受请求:
1、 getRequestURL() //获取客户端发出请求时的完整URL
2、 getRequestURI() //获取请求行中的资源名称部分(从项目名称开始)
3、 getQueryString() //获取请求行中的参数部分
获取请求方式(get or post):
String method = req.getMethod();
System.out.println("获取请求方式:"+method);
获取当前版本协议
String protocol = req.getProtocol();
System.out.println("获取当前版本协议:"+protocol);
获取项目的站点名(项目对外访问路径)
String contextPath = req.getContextPath();
System.out.println("获取项目的站点名:"+contextPath);
请求跳转:
请求跳转是服务端行为,可以让请求从服务端跳转至客户端或者其他指定的servlet服务 请求跳转的特点:
1、地址栏不变
2、是服务端行为
3、自始至终只有一个请求
4、request对象数据可以共享
5、只可以跳转至本机的资源地址
请求跳转的各种 api:
request.getRequestDispatcher(“ser04”).forward(request,response);
getRequestDispatcher参数设置为跳转到的资源地址,返回值为RequestDispatcher对象
再通过调用RequestDispatcher对象中的forward方法把请求跳转至指定服务中 request域对象
该对象可以在一个请求中传递数据,作用范围在一次请求中有效,即服务端程序之间请求跳转时有效 三个处理域对象中数据的方法:
//设置域对象,name参数为数据名称,value为数据
request.setAttribute(String name,Object value); //获取域对象 request.getAttribute(String name); //删除域对象
request.removeAttribute(String name);
在情求传递前设置这些域对象数据,跳转到的服务端程序可以获取,修改或者销毁
response对象
response对象是服务器接受到请求时创建并传递至服务端程序的对象 可以向客户端传输数据
响应数据:
接受到客户端的请求后,服务端程序可以调用response对象的方法向客户端进行数据传述 有两种流可以在响应时传输数据
getWrite(); //字符输出流(只能传输字符) 一定会乱码, getWrite.write(“内容”)
getOutputStream(); //字节输出流(可以传输一切数据) 不一定会乱码,当服务端程序与客户端程序使用的编码方式相同且都支持中文时不乱码
outputStream.write(“内容”.getBytes(“utf-8”)); 两种不可以同时使用
乱码问题:
既然两种流会有乱码问题,那么我们不论是那种流,都先设置一下编码的话就不会产生乱码问题 response.setCharacterEncoding(“utf-8”); //设置服务端的编码格式
response.setHeader(“content-type”,“text/html;charset=UTF-8”);
//设置客户端的编码格式
response.setContentType(“content-type;charset=utf-8”); //同时设置客户端与服务端的编码格式
重定向:
重定向是由服务器指导的客户端行为 特点: 地址栏会改变 是客户端行为 有两次请求
请求转发的地址只能是本机的资源地址,但是重定向可以是任意站点地址
重定向中的request的数据是不共享的,不是同一个request对象,所以不可以共享
response.sendRedirect(“地址”);
cookie
cookie是用于客户端缓存数据的技术
cookie的创建与发送:
//创建cookie实例
Cookie cookie = new Cookie(各种参数);
//发送Cookie对象
reponse.addCookie(cookie);
//获取cookie对象数据
Cookie[] cookies = request.getCookies();
//由于返回值是Cookie数组,所以需要对其进行遍历
if(cookies!=null && cookies.length != 0){
for(Cookie cookie : Cookies){
String name = cookie.getName(); //获取cookie对象中缓存的name数据
String value = cookie.getValue(); //获取cookie对象中缓存的Value数据
}
}
cookie的缓存时间设置:
负整数:默认值为-1,表示数据一直缓存到浏览器关闭
正整数:表示数据缓存的时间,单位为秒
零:立刻删除
可以通过Cookie对象中的setMaxAge()方法来设置缓存时间
在设置后将cookie发送有效
cookie的注意事项:
1、cookie只保存在发送请求的那个浏览器,不能跨浏览器
2、cookie的中文保存乱码问题
cookie不能保存中文,若要保存中文需要转码
如:
String name = URLEncoder.encode("姓名")
再以name作为cookie的参数
获取参数时也要对其进行解码:
URLDecoder.decode(cookie.getName());
这种方法在浏览器中依旧无法使cookie变为中文
3、cookie同名问题:
如果向浏览器发送重复的cookie,先前的cookie会被覆盖掉
4、浏览器的cookie缓存数量限制:
不同的浏览器对cookie也有限定,cookie的存储是有上限的,一般是在4kb左右
一般来说cookie由服务端发送客户端保存,后期结合Session来实现回话跟踪。
cookie路径问题
cookie的setPath可以设置cookie的路径,这个路径决定服务器的请求是否会从浏览器中加载这些cookie
情景1:当前服务器任意资源都可以获取Cookie对象
//当前项目资源路径为"/ser01"
Cookie cookie = new Cookie(参数);
cookie.setPath("/"); //相当于设置可见路径为根路径,所有资源均可以访问
response.addCookie(cookie);
情景2:当前项目下的资源可以获取cookie对象(默认不设置cookie的path)
//当前项目资源路径为"/ser01"
Cookie cookie = new Cookie(参数);
cookie.setPath("/ser01");
response.addCookie(cookie);
情景3:指定项目下的资源可以获取到cookie对象
//当前项目资源路径为"/ser01"
Cookie cookie = new Cookie(参数);
cookie.setPath("/ser02"); //虽然此cookie是由项目ser01产生的,但是也依旧只能由ser02项目资源才能获取
response.addCookie(cookie);
情景4:只有指定目录下的资源才可以获取cookie对象
//当前项目资源路径为"/ser01"
Cookie cookie = new Cookie(参数);
cookie.setPath("/ser01/cook"); //只有此目录下的资源可以获取cookie对象
response.addCookie(cookie);
当前访问路径包含cookie设置路径时,那么cookie就会加载到request对象中去
HttpSession对象
HttpSession对象是HttpSession接口的实例
对于每一个链接到服务器的客户端,服务端都将他们视为一个session对象
servlet容器使用此接口实现客户端与服务端的会话,会话将保留指定的时间,跨越多个链接或来自多个客户的页面请求
一个会话对应于一个客户,一个客户可以多次访问一个站点
每当服务器接受到了请求,并开启了会话 那么服务器会首先查看是否从客户端回传来一个名为JSESSIONID的cookie,
若无,那么则认为这是一次新的会话,将会创建一个新的session对象
若有,则通过JSESSION去找是否有id为此值的session对象没有的话依旧认为这是一次新的会话,会创建新的session对象并标记
若有,则认为是已经有过的会话,返回该session,数据到达共享 因此,session的底层依赖cookie来实现
session域对象:
常用方法:
setAttribute() 方法设置session域对象
getAttribute() 方法获取session域对象数据
remove() 方法销毁session域对象
重定向与请求转发中的session数据均共享
session对象销毁
设置session对象到期时间
1.默认到期时间
tomcat设置session默认的存活时间为30min,即界面没有操作的时间,一旦有操作就会重新计时 可以在tomcat的conf目录下的web.xml文件中进行修改
2.自己设置到期时间
可以通过session.setMaxInactiveInterval(int); 方法来设置session最大不活动时间 单位为秒
可以通过session.getMaxInactiveInterval(); 方法来获取session最大不活跃时间
3.立即销毁
session.invalidate();
4.关闭浏览器
session底层依赖于cookie,而一旦关闭浏览器,cookie就会被销毁,则session也无法存活
5.关闭服务器
服务器被关闭时,所有对象将会重置
ServletContext对象
每一个web应用都有且仅有一个ServletContext对象,又称Application对象,从名称中可以知道这是直接于应用程序相关的
服务器启动时,会为每一个web应用程序创建一个对应的servletContext对象
此对象有两大作用
第一:作为域对象来共享数据,此时数据在整个应用程序中共享(不推荐保存过多数据,因为若是没有手动移除的话数据将一直存在)
第二:该对象保存了大量当前应用程序相关信息,可以通过servlet对象中的一些方法来获取这些信息
获取ServletContext对象
1.通过request获取
ServletContext servletContext = request.getServletContext();
2.过session对象获取
ServletContext servletContext1 = request.getSession().getServletContext();
3.通过ServletConfig对象获取
ServletContext servletContext2 = getServletConfig().getServletContext();
4.直接获取 只能在servlet中使用
ServletContext servletContext3 = getServletContext()
ServlerContext常用方法:
1.获取服务器版本信息
String serverInfo = servletContext.getServerInfo();
System.out.println(serverInfo);
2.获取项目真实路径
String realPath = servletContext1.getRealPath("/"); //设置为获取根路径
System.out.println(realPath);
ServletContext域对象的使用:
//设置域对象
servletContext.setAttribute("name","value");
//获取域对象
String value = (String)servletContext.getAttribute("name");
//销毁域对象
servletContext.removeAttribute("name");
servlet三大域对象:
1. request域对象
一次请求中有效,请求转发数据共享,重定向数据不共享
2. session域对象
一次会话中有效,请求转发与重定向均数据共享,session若是被销毁后会失效
3. servletContext域对象
在整个应用程序中有效,服务器关闭后失效