Servlet
Servlet:创建并返回基于客户请求的动态HTML页面;与其他服务器资源进行通信
生命周期:构造器(只调用一次),init,service,destroy(卸载前调用)。
load-on-startup:大于等于0,容器启动时候加载servlet;未指定或负数,使用该servlet时候才加载,正数越小优先级越高。
httpServlet继承GenericServlet,而GenericServlet的继承结构,实现了Servlet接口和ServletConfig接口。
Servlet接口有三个关键方法,init、service、destroy。还有另外两个方法,一个getServletConfig(),getServletInfo();
三个运行周期的方法,获取了ServletConfig,通过它可以获取到ServletContext。
GenericServlet类的方法;
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
private transient ServletConfig config;
public ServletConfig getServletConfig() {
return this.config;
}
有两个init方法,带参数的是为了方便在其他地方直接可以使用ServletConfig对象,就创建一个私有的成员变量config,然后通过getServletConfig方法可以获取。
init方法中还调用一个init方法,是因为我们需要在init方法中做些事情一般是继承GenericServlet并且重写了init(ServletConfig config)方法,但导致GenericServlet类中的成员变量config会一直是null,要想赋值,就必须在重写的init(ServletConfig config)方法中调用父类的init(ServletConfig config)方法,也就是super.init(ServletConfig config),太麻烦,我们需要在init方法中需要初始化别的数据,只需要重写init()这个方法,而不需要去覆盖init(ServletConfig config)这个方法。
service方法
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
是一个抽象方法, HttpServlet类继承了GenericServlet类
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
req是RequestFacadeleixing ,继承结构:RequestFacade、httpServletRequest、ServletRequest,所以可以强转;这个方法就是判断浏览器过来的请求方式是哪种,每种的处理方式不一样,我们常用的就是get,post.
重点的对象。ServletConfig、ServletContext,request、response
ServletConfig
getServletName(); //获取servlet的名称,也就是我们在web.xml中配置的servlet-name
getServletContext(); //获取ServletContext对象,该对象的作用看下面讲解
getInitParameter(String); //获取在servlet中初始化参数的值。这里注意与全局初始化参数的区分。这个获取的只是在该servlet下的初始化参数
getInitParameterNames(); //获取在Servlet中所有初始化参数的名字,也就是key值,可以通过key值,来找到各个初始化参数的value值。注意返回的是枚举类型
注意:可以不用先获得ServletConfig,然后在获取其各种参数,可以直接使用其方法。
ServletContext
tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁。
web项目*享数据:
setAttribute(String name, Object obj) 在web项目范围内存放内容,以便让在web项目中所有的servlet读能访问到
getAttribute(String name) 通过指定名称获得内容
removeAttribute(String name) 通过指定名称移除内容
整个web项目初始化参数:
getInitPatameter(String name) //通过指定名称获取初始化值
getInitParameterNames() //获得枚举类型
web.xml 配置 整个web项目的初始化
request
request就是将请求文本封装而成的对象,所以通过request能获得请求文本中的所有内容,请求头、请求体、请求行;
1、请求行内容的获取。请求行包括请求方式,资源路径,协议
如:request.getRequestURL(),request.getServletPath()
2、请求头的获取
req.getHeader(“Accept-Language”)
3、请求体的获取
String request.getParameter(String) 获得指定名称,一个请求参数值。
String[] request.getParameterValues(String) 获得指定名称,所有请求参数值。例如:checkbox、select等
Map<String , String[]> request.getParameterMap() 获得所有的请求参数
4、请求转发
request.getRequestDispatcher(String path).forward(request,response);
特点:浏览器中url不会改变,并且在转发后的页面,能够继续使用原先的request。
response
包含响应头,响应行,响应体。
常用的一个方法:response.setHeader(java.lang.String name, java.lang.String value) 设置指定的头,例如:response.setHeader(“Refresh”,3); //设置每隔3秒就自动刷新一次
重定向:
方式一:手动方案
response.setStatus(302); //状态码302就代表重定向
response.setHeader(“location”,”http://www.baidu.com“);
方式二:使用封装好的
response.sendRedirect(“http://www.baidu.com“);
特点:浏览器的地址栏中url会变,request是重新发起的,跟请求转发不一样。
其他
request请求参数出现的乱码问题
Get请求
根本原因是游览器使用UTF-8编码,http协议只支持ISO-8859-1。
String name2 = new String(name.getBytes(“ISO-8859-1”),”UTF-8”);
Post请求
post请求方式的参数是在请求体中,没有经过http协议这一步的编码过程
request.setCharacterEncoding(“UTF-8”); //命令Tomcat使用UTF-8码表解码,而不用默认的ISO-8859-1了。
response响应回浏览器出现的中文乱码
response对象是如何向浏览器发送数据的。两种方法,一种getOutputStream,一种getWrite。
ServletOutputStream getOutputStream(); //获取输出字节流。提供write() 和 print() 两个输出方法
PrintWriter getWrite(); //获取输出字符流 提供write() 和 print()两个输出方法
1、resp.getoutputStream().write(“汉字”.getBytes(“UTF-8”));
2、通知tomcat和浏览器都使用同一张码表
response.setHeader(“content-type”,”text/html;charset=uft-8”); //手动设置响应内容,通知tomcat和浏览器使用utf-8来进行编码和解码。
response.setContentType(“text/html;charset=uft-8”); //使用Servlet API 来通知tomcaat和强制浏览器使用UTF-8来进行编码解码,这个的底层代码就是上一行的代码,进行了简单的封装而已。
Cookie和Session
Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Cookie
Cookie cookie = new Cookie(key,value); //以键值对的方式存放内容,
response.addCookie(cookie); //发送回浏览器端
注意:一旦cookie创建好了,就不能在往其中增加别的键值对,但是可以修改其中的内容,
cookie.setMaxAge(expiry); //设置cookie被浏览器保存的时间。
expiry=-1:代表浏览器关闭后,也就是会话结束后,cookie就失效了,也就没有了。
expiry>0:代表浏览器关闭后,cookie不会失效,仍然存在。并且会将cookie保存到硬盘中,直到设置时间过期才会被浏览器自动删除,
expiry=0:删除cookie。不管是之前的expiry=-1还是expiry>0,当设置expiry=0时,cookie都会被浏览器给删除。
setPath(“/”); //在该服务器下,任何项目,任何位置都能获取到cookie
cookie操作
1.创建cookie:new Cookie(name,value)
2.发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
3.servlet接收cookie:HttpServletRequest.getCookies() 浏览器发送的所有cookie
注意:每一个cookie文件大小:4kb,cookie不能发送中文,如果要发送中文,就需要进行特别处理。
用途:记住用户名,历史记录等。
Session
首先浏览器请求服务器访问web站点时,程序需要为客户端的请求创建一个session的时候,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSIONID,如果已经包含了一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用,如果客户端请求不包含session id,则服务器为此客户端创建一个session并且生成一个与此session相关联的session id,sessionid 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将在本次响应中返回到客户端保存,保存这个sessionid的方式就可以是cookie,这样在交互的过程中,浏览器可以自动的按照规则把这个标识发回给服务器,服务器根据这个sessionid就可以找得到对应的session。
request.getSession(); //如果没有将创建一个新的,等效getSession(true);
关闭浏览器不会导致session被删除,服务器为seesion设置了一个失效时间,一般是30分钟。
session.invalidate()将session对象销毁
setMaxInactiveInterval(int interval) 设置有效时间,单位秒
在web.xml中配置session的有效时间
<session-config>
<session-timeout>30</session-timeout> //单位:分钟
<session-config>
服务器正常关闭后,就会将session持久化,写入文件中,等30分钟后,就会被删除。
转发和重定向:
转发的过程:
客户端浏览器发送请求,web服务器接收请求再进行在内部跳转,什么意思呢,也就是说,跳转只能在自己所在的web容器下的url,而不能跳转出去其他的url。
重定向的过程:
客户端发送请求,web服务器接收该请求后发送302状态码响应并且发送新的一个地址(location)给客户端浏览器,客户端接收到302则自动再发送一个新的请求,而这个请求就是新的location,既然是客户端发送的一个请求,就对web容器的request没关系了,它可以任意跳转到所有location。
其实它们最本质的区别就是,转发只需要一次的请求,仅仅是一次客户端的request,而重定向则需要两次请求,一次是客户端request,服务器响应后返回302给客户端浏览器,再由客户端浏览器再发一次请求。
不过对于重定向,因为是重客户端浏览器进行再次发送请求,所以在重定向过程中,之前传输的信息会被丢失。