关于Servlet的个人心得

1,servlet 的生命周期

1>无参构造
2>初始化init(),含有唯一的一个参数,servletConfig,可以通过其获取servletContext
3>service()
4>销毁destroy()
5>单例多线程
6>load-on-startup让servlet在服务器启动时已经实力初始化

2,web容器中的两个map

3,ServletConfig

ServletConfig 是个接口,就相当于时servlet配置文件。
一般而言,servletConfig对象只是只读的,不可修改,故不存在线程安全问题
不同的servlet会创建不同的servletConfig对象,一个servlet就会存在一个servletConfig对象,二者的对象关系为一对一。

4个方法(parameter,参数)
1>getInitParameter(String name);获得当前指定参数的值
2>getInitParameters();获得一个枚举,里边放置所有的初始化参数名称
3>getServletContext();获得servlet上下文,便于获得当前servlet上下文中设置的属性等
4>getServletName();在web.xml文件中配置的servletName标签中值,即servlet的名字

4,servletContext(相当于一个application域)

servletContext,即servlet上下文,是个接口,是web应用中所有servlet在web容器中运行的上下文环境,随着web应用启动而启动,随着销毁而销毁。
其所含有的所有的servlet共享,均可以通过servletConfig获得的servletContext对servlet上下文环境进行读取和配置。
换句话而言,servletContext可以代表整个应用。故又名安排application

方法(attribute,属性)
1>getInitParameter(String name);获得当前指定参数的值
2>getInitParameters();获得一个枚举,里边放置所有的初始化参数名称
3>setAttribute();
4>getAttribute();
5>removeAttribute();这三个方法,在同一个servlet中不会同时执行,例如,添加了一个属性后,然后删除,再次查看,该属性依旧存在。
		  同时,设置的属性不会放置XML文件中,每重启一次web容器后,即会失效。需重新设置。
6>getRealPath();获取当前web应用下文件的绝对路径,基于盘符
7>getContextPath();获得当前应用在web应用的名称,相当于web应用的名称,因为一个servletContext就相当于代表一个web应用。如:/Test01-servlet

5,欢迎页面的设置

在<welcome-file-list>中设置<welcome-file>即可
当将其全部删除后,容器也会存在默认欢迎页面,在tomcat安装目录下的conf/web.xml文件中。

6,关于servlet的url

1,精确路径
2,通配符路径,如/test/*
3,全路径,/*或者/,其中/*会对所有的请求进行拦截,/除了动态的jsp请求不拦截,其他均拦截。在监听器,过滤器中会涉及到对请求的拦截。
4,后缀名,如/*.do,/*.test,类似于上边的通配符路径。
5,一个servlet可以配置多个url,值得注意的是,通配符不能与后缀名同时存在,同时存在将导致服务器无法启动。
6,关于路径的匹配原则,@1,路径后缀优先匹配;@2,精确路径优先匹配;@3,最长路径优先匹配。   

7,GenericServlet

除了service()方法需要程序员的手动重写,其他方法均空实现。

8,HttpServlet

9,HttpServletRequest(相当于一个request域)

1,请求的生命周期,太过短暂,对服务器发出请求的时候创建,服务器做出response相应后,请求over(),然后被destory();
2,请求参数,通过map这种集合框架进行接受,即所谓的键值对,key为String类型,value为String类型数组,因为表单中的多选属性可能会有多个值。
	方法:1>getParameterMap();
	          2>getParameterNames();
	          3>getParameterValues(String name);
	          4>getParameter(String name); 值得注意的是,如果name对应的是多个值,则其所得的值相当于getParameterValues(String name)[0]
3,关于request域
	方法:1>setAttribute();
	          2>getAttribute();
	          3>removeAttribute();
	          4>getRequestDispatcher(String path).forward(HttpServletRequest request, HttpServletResponse response);请求转发
		关于请求转发,我们会发现存在中文乱码的问题,参照第6条。

4,关于doGet(),doPost(),还有service(),前两者与后者同时执行的话,后者执行,前二者不执行。原因是重写service方法的时候,未调用doget,这种方法,
     如果需要的话,在重写的service中添加super.service()

5,关于获取服务端相关信息的方法。
	方法:1>getRequestURL();获取请求的url,从请求协议开始的绝对路径。如:http://127.0.0.1/Test01-servlet/test01
	          2>getRequestURI();获取请求的uri,从项目开始的请求路径。如:/Test01-servlet/test01
	          3>getContextPath(); 获取当前web项目的名称。如:/Test01-servlet,这个与通过servletContext的getContextPath获得的web名称一致。
	          4>getServletPath();   获取当前servlet的名称。如:/test01		
	          5>getPathInfo();       获取当前通配符路径的*号所代表的名称。如:/aa/bb/cc或者null
		值得注意的是,URL = 协议+地址+URI
		                        URI = ContextPath + servletPath + PathInfo
	          6>getMethod();       获得请求方式
                          7>getRemoteAddr(); 获得客户端浏览器的IP地址。
6,关于request请求的中文乱码问题。关于请求转发的乱码问题也通过该方法去处理。
	username=%E9%A9%AC%E6%9E%97
	关于get,post的两种提交方式。推送出不同的在方法。
	方法:Post ,setCharacterEncoding("编码格式");
	          Get ,TomCat/conf/servlet.xml/8080端口号下添加encoding = “编码格式”。
	          万能解决方案,先解码,在组码。
		String username = request.getParameter("username");
		byte[] bytes = username.getBytes("iso8859-1");//解码
		username = new String(bytes, "utf-8");//组码 
7,关于响应的中文乱码问题。
	当我们需要将Java代码处理后的结果向网页中写入时,我们需要通过response的getWriter(),获得向网页写内容的流。
	但是当响应中文的时候,会出现中文乱码问题,相应的解决方案为,response.setContextType("MIME类型;编码格式");
	如编码格式:charset = utf-8;
	值得注意的是:此设置需要在获得PrintWriter之前,否则将无法对得到的流作用。

10,请求转发与重定向

1,请求转发。
	相当于在服务器内进行跳转。一次发送,一次请求。	
	通过request.getRequestDispatcher(path).forward(request,response);
	达到请求转发的效果,但此方法会导致恶意刷新导致服务器宕机等。
	这种情况不存在请求数据丢失的情况。

2,重定向。
	相当于在服务器外进行跳转。执行完请求之后,重定向至指定的路径。
	通过response.sendRedirect(String location)达到重定向的效果。
	这种方式有效防止了恶意刷新,但是因为重定向后又是一次新的请求,故会导致原始请求中的数据丢失。

3,关于重定向的数据传输,请参考get提交方式的参数提交形式,之后在其sendRedirect()时,将其按照对象格式写入。

4,重定向的中文乱码问题。
	首先,乱码问题是出现在URL中的URI中,因为在换为URI的时候,已经发生乱码现象了。
	故其解决方案:在正常解决乱码问题的时候,对字符串进行先解码,在组码。
	URLEncoder.encode(username,"utf-8");这个步骤在重定向之前执行。
	URLDecoder.decode(username,"utf-8");这个步骤在重定向后的文件中执行。
	需要注意的是,重定向后的那个请求方式是get,而非post,故在其解决请求的中文乱码问题时,需要使用万能解决方案。
	
5,关于二者的选择
	1,跳转到其他应用,重定向
	2,重型应用执行完毕后,重定向。
	3,servlet之间的跳转,重定向。防止表单重复提交,恶意刷新
	4,其余,一般请求转发。

11,关于RequestDispatcher的两个方法

1,forward()
	使用该方法,当前的servlet只能进行业务的处理,不能向浏览器发送需要显示的数据。只有请求转发后的servlet具有向浏览器输出的能力。
2,include()
	使用该方法,当前的servlet将整合请求转发后的资源,将二者向浏览器发送的数据进行合并(按照顺序),然后发送给浏览器

3,关于二者的不同
	forward()方法是在请求转发后到达的页面上打开输出流。而include()是在当前页面打开输出流。
	如果在include()的情况下,在请求转发后的页面将输出流进行了关闭,则导致之后的内容无法写入。

12,关于访问路径的大问题

1,访问路径的组成。
	由资源路径+资源名称(最后一个/后的名称)。组成
	资源路径:协议+主机名:端口号+项目名 ;如http://127.0.0.1/Test01-servlet
	资源名称: 如:/test01
	二者相加就是所谓的URL。
2,绝对路径。
	就是URL,统一资源定位符
3,相对路径
	需要注意的是,绝对路径=参照路径+相对路径。
	根据相对路径是否以/开头,路径出现的文件位置不同,默认的参照路径是不同的。
	1,以/开头的相对路径
		1>前台路径,其主要作用是查找
			值得注意的是,前台路径的参照路径为http://localhost:8080。
			所以在表单中的action需要填写具体的项目名/servlet,例如:/Test01-servlet/one
		2>后台路径,其主要作用是标识
			后台路径的参照路径为:http://localhost:8080/Test01-servlet
			其中,重定向中的路径如果填写/开头的相对路径,其参照路径为tomcat的根,而非当前项目的根,所以重定向时,需要加上request.getContextPath()
	
	2,以路径开头的相对路径
		其参照路径均为当前访问路径的资源路径。

13,Servlet的线程问题(同多线程安全解决方案基本一致)。

1,将需要的变量声明为局部变量
2,将使用成员变量的方法使用synchronized修饰。

14,Cookie

1,一种web开发技术。

2,其底层的数据结构相当于一个Map。键一般为name ,值一般为value,均为String字符串。

3,cookie构造, Cookie(String name,String Value)
     将cookie添加至响应头,addCookie(Cookie cookie)

4,修改绑定路径
     cookie.setPath();一旦发生修改后,除非访问与之对应的Path,否则该cookie将无法展示在请求头上。

5,修改cookie的有效时间。(enpiry 逾期)
     cookie.setMaxAge(int enpiry),单位为秒
     如果不进行修改的话,其随着session的失效而失效。
     值得注意的是,enpiry等于0 的时候,cookie产生后直接失效。

6,服务端读取请求中的Cookie
      getCookies()

15,session

1,会话,一种web开发技术,打开浏览器,发送请求,直到浏览器关闭后,一次会话完成。

2,session对象的创建
	当需要使用session存放数据的时候,使用getSession(true)或者getSession()方法得到session。
	当需要使用session查看数据的时候,使用getSession(false)的到session。

3,关于session域的操作(每个域基本上都有这个操作)
	方法:1>setAttribute();
	          2>getAttribute();
	          3>removeAttribute();

4,Session的工作原理
	不同的会话,对应不同的Session对象,系统使用神奇的JSessionID(32位长的随机字符串,这个东西相当于一个cookie,可以通过cookie查看)
	一般客户端不关闭,cookie就不会失效,所以浏览器中的cookie缓存就不会消失,这就保证了会话的稳定,可以确保我们追踪到该会话。

5,Session 的失效
	如果某个会话在指定的时间范围内一直未发生访问,session将失效。
	默认失效时间未30分钟。从最后一次访问session时开始计时。
	1,通过<session-config>
		<session-timeout>120</session-timeout>
	      </session-config>
	     控制其失效时间
	2,调用invalide()也会使session失效。
	
	3,cookie禁用后的session会话跟踪。
		在会话栏的最后添加  ;jsessionid="当前会话的jsessionid"跟踪会话,但是如此将导致会话的不安全。

16,关于域属性。

servlet 中含有4大域,范围从大到小分别是:
servletContext(application),可以完成跨会话共享数据
sessionContext,	              可以完成跨请求共享数据
requestContext,	              可以完成跨servlet共享数据,相当于跨page
pageContext	              最小的域,一般不用。

以上为自己的一些整理,原因无二,看过之后未曾记在心底,故整理一番。
同时,警醒自己一段话:不要着急,稳扎稳打,多多练习,会成功的。加油,亲爱的自己,为了你规划的未来。
                                                                                                       2018/11/15

猜你喜欢

转载自blog.csdn.net/qq_42036640/article/details/84108991
今日推荐