1 : servlet:
init(): 当我们发出第一个HTTP请求时,此时会初始化一个servlet,也就是说此时应用服务器会调用init方法
而当实例生成完成后,此时如果我们再发出一个请求,就不会再实例化一个对象了,因为一般情况下serlvet是单例的
同时,servlet也是线程安全的,针对每一个HTTP请求,应用服务器会启动一个线程去处理它,不同的线程处理不同的请求
一般我们不再servlet中定义全局变量,因为如果我们使用全局变量而且又对他进行了修改的话,会导致线程不安全
的问题出现,因为servlet是单例,多个线程是共享的同一个servlet
destroy(): 当我们终止应用服务器或者重新部署项目的时候会调用destroy方法
load-on-startup: 表示我们在服务器启动的时候就实例化servlet,而不是等到第一个HTTP请求时才进行实例化
get和post方法:
大部分的时候我们发出的请求都是get请求,除非我们显示指定提交请求的方法是post,才会发动post请求
比如说表单提交的时候,设置method="post"
get请求通过在URL地址后面附加参数的形式来向后台递交数据
·post请求则通过HTTP head来递交数据,既不会出现在URL地址的后面
·由于get是将参数附加在URL的地址后面,所以,他的长度可能会受到浏览器的限制
·post请求的数据长度一般不会受到限制
POS方法则不改变URL的地址:
在客户端,get与post的主要区别在于是否通过URL的地址来传输,GET使用起来很方便,但不适合大批数据
的传输,POST则需要定义一个form元素才可以使用,所以
·大批量数据提交请用POST
·要方便,数据量少,请用GET
在服务器端,
·在服务器端,一般情况下无需关注是GET还是POST方法提交的数据,不管是get还是POST,对于服务器端来说,其接受从客户端传递来的参数的过程是完全一样的
2: 编码问题:
request:
为了每次避免都要针对HTTP GET请求传递的参数进行编码解码操作,我们可以在server.xml文件中
进行配置:
不过这种编码解决方式只对get请求有效,对于POST请求则无效,此时我们只能通过以下方式
解决POST请求的编码问题: request.setCharacterEncoding("UTF-8");
在获得参数之前进行如上设置即可
response:
response.setCharacterEncoding("UTF-8");
或者:
response.setContentType("text/html;charset=UTF-8");
3: 路径问题: 路径的好的解决办法是使用绝对路径:
首先找出现在的文件的绝对路径:如:http://localhost:8080/jspAndServlet02/encode.jsp
然后我们再找出需要请求的目标路径: 如:http://localhost:8080/jspAndServlet02/a/b/post.jsp
那此时我们就可以在encode.jsp的页面中填写
的请求路径为:../a/b/post.jsp, ../表示找到的路径为http://localhost:8080/jspAndServlet02
4: forward and redirect:
forward: 服务器端从一个servlet转向另一个Servlet
在一个Servlet中可以通过setAttribute往request中传递一些值,
在另外一个Servlet中,可以通过getAttribute从request中取值,在两个Servlet中访问到的request的数据是一样的(也就是是同一个request)
整个过程是在一个请求范围中
redirect: 服务器端实际上已经向客户端产生了响应,客户端根据响应的HTTP HEAD中
包含的redirect地址,向服务器重新发起了一个请求(GET方式)
后面这个请求与一开始那个请求不是同一个请求,所以,在前一个请求中调用setAttribute放进去的
数据已经丢失
通过代码的测试证明,当我们使用forward进行重定向的时候,整个流转的过程是在同一个请求的过程中
也就是说forward只是在一个请求周期内,也就是在某一次的HTTP请求,整个过程客户端只向服务器发送了一个
一次请求
而当我们采用redirect进行重定向的时候,当我们从客户端发送第一个请求时,到达请求的servlet进行数据处理完成后
,当执行response.sendRedirect("RedirectServlet");代码时,表示服务器向客户端传送了一个响应,
在响应的头信息中有重新向的地址(Location),此时,浏览器会再根据该请求地址重新向服务器发送请求,
此时,整个过程就有两个HTTP请求,两个请求产生了两个request对象,所以转向后的Servlet通过
request.getAttribute()方法就获取不到前一个Servlet的通过request.setAttribute方法设置的值
当我们涉及到了增删改的时候我们一定要采用重定向的操作,这样可以防止增删改的重复操作,当转向一个具体的视图的时候,我们一般采用请求转发
5: HTTP协议的无状态性:
即每次请求都是独立的,分离的,一旦一个请求-响应周期结束,那么客户端将断开和服务器的链接,下一个请求-响应周期,客户端与服务器将重新链接和断开
这就意味着所有的工作必须在一次请求-响应的周期中完成
6: HttpSession:
Cookie JSESSIONID=FB24FE1F1E1A202A8344E35F629ADD8D
HttpSession其实是保存客户端状态的一种机制,
原理:
当我们第一次请求的时候,如果服务器端没有指定用户存在的session在的话,此时就会创建一个session,并且服务器会将此session所对应的他的唯一标志Id,也就是JSESSIONID返回给客户端,客户端接受到响应后 会将此JSESSIONID存在客户的磁盘上,也就是Cookie中,此后当我们再像服务器端发送请求时,客户端同时也会将 之前的那个JSESSION发送给服务器端,服务器端会根据JSESSIONID找到对应的HttpSession,这样就实现了保存客户端状态的功能,当浏览器关闭后,服务器端的HttpSession并没有销毁,但是此时客户端保存之前的JSESSIONID的Cookie会在本地磁盘被销毁,当浏览器再次被打开的时候,此时向服务器发送请求后在服务器端就找不到对应的HttpSession了,此时又会重新生成一个HttpSession,并赋予它一个JSESSIONID
调用getSession() : 如果还没有session对象,则创建一个,相当于调用getSession(true)
调用getSession(false) : 如果还没有session对象,返回null(不创建新的session对象)
我们可以在部署文件中web.xml配置会话的实现周期:
1
这就表示我们保存客户端的状态的周期为1分钟,如果在一分钟之后还没有进行任何操作,
服务器端的HttpSession就会被销毁,之后再进行操作就会重新生成一个HttpSession
7: ServletContext:
全局性的保存机制,可以在多个会话session中共享某些数据:ServletContext ac=request.getSession().getServletContext();
ServletContext sc=this.getServletContext();
8: JSP: JavaServer Page:
jsp中写java代码有三种方式:
脚本: <%%>
表达式: <%=%>
声明: <%!%>
jsp内置对象:
HttpServletRequest request=null;
HttpServletResponse response=null;
PageContext pageContext=null;
HttpSession session=null;
ServletContext application=null;
ServletConfig config=nul;
JspWriter out=null;;
Object page=null;
Exception exception=null;
jsp内置对象的作用域范围:
PageContext :当前页面范围
request :当前请求-响应周期范围内
session :当前会话范围
application: 当前web应用程序范围
base的作用:可以解决路径的问题
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
静态包含:include: <%@ include="fileName.jsp"%>,这里不会单独再生成一个fileName_jsp.java文件了,会直接嵌套在当前页面中
jsp动作:
:
<%=customer.getName() %>
动态包含:: 在运行的时候将该页面包含进来
jsp中的静态包含和动态包含jsp中有两种包含模式,一种是<%@ include file="要包含的页面路径" %>,
这种叫静态包含,另一种是 ,这叫做动态包含.
静态包含是直接把要包含的页面原样嵌入总的页面后再统一编译,而动态包含总的页面和要嵌入的页面是分开编译的.
现在看到这两种包含的意义了么?jsp是建议我们凡是*.jsp的页面如果要被另一个页面包含,那么应该用动态包含,
如果只是html或者是一段文本,那么用动态包含和静态包含都可以.因此原则上我们都倾向于使用动态包含.
:表示先会显示总页面,等到嵌套页面编译完后再进行显示
: 表示总页面会等到嵌套页面编译完后一起加载到浏览器进行显示
9: JSTL
会依次到各个Scope中去查找,范围由小到大,表示以xml的形式输出
name:
以上的逻辑相当于if。。。else
http://java.sun.com/jsp/jstl/functions 函数标签,自定义函数
http://java.sun.com/jsp/jstl/fmt 格式化标签
http://java.sun.com/jsp/jstl/core 核心标签库
自定义标签: 必须继承TagSupport或者BodyTagSupport
自定义函数(function)标签:定义的函数必须是static的
EL表达式:${},根据作用域的范围从小到大依次进行查找
10: Cookie: 它是用户访问web服务器时,服务器在用户硬盘上存放的信息
服务器可以根据Cookie来跟踪用户,cookie中保存的name是JSESSIONID,值是随机的一个字符串
服务器端可以通过响应向客户端发送cookie,可以通过request获得客户端发送来的cookie数组
11: Filter
既可以拦截请求对象,同时也可以拦截响应对象,实际开发中一般对于登录的请求是不需要进行拦截的 此时我们可以获得请求的URI地址,通过 判断然后进行处理
串联Filter的使用: MultiFilter1 before chain.doFilter()
MultiFilter2 before chain.doFilter()
lisi
zhangsan
MultiFilter2 after chian,doFilter()
MultiFilter1 after chain.doFilter()
在web.xml文件中配置filter的时候,如果我们是针对所有的请求进行过滤的话,filter-mapping
元素中的url-pattern元素可以配置为/*,如果我们是针对具体的某一个请求进行过滤
那么我们可以配置相应的请求路径就行, 如 /MultiFilterServlet
Listener:
Servlet中常见的有以下几种监听器接口:
* ServletContextAttributeListener: 主要是监听web应用中ServletContext属性状态改变的一些信息,
比如说属性的添加,属性的删除,属性的替换的操作
* ServletContextListener: 在服务器启动和关闭的时候由服务器调用
主要是监听服务器的启动和关闭时的一些状态信息
在框架中启动服务器的时候加载一些资源,在spring中运用较为普遍
* HttpSessionListener: 主要是监听活动的session被创建和被销毁时的一些状态信息
* HttpSessionAttributeListener: 监听活动的session属性状态改变的一些信息,如属性的添加,删除,替换等