Servlet&JSP中的知识点

时间:2021-11-22 08:40:20

先sun提出的是Servlet体系,这个体系使得使用JAVA的程序员也能开发基于B/S架构的WEB应用程序,使用Servlet类将HTTP请求和响应封装在标准JAVA类中来实现各种WEB应用方案。随着大量的B/S架构程序开发出来以后,人们发现Servlet类的编写是非常繁琐的,主要集中在几个问题上:首先有大量冗余代码,这些代码在每个servlet类中都是一模一样或者基本近似的.其次是开发Servlet的程序员很少有精通美工的,导致使用Servlet开发无法方便的做到各种页面效果和丰富多彩的风格,这个时候sun借鉴了微软的ASP方式,正式提出JSP(也就是Servlet 1.1),JSP推出后,JAVA程序员也能象ASP的程序员那样将服务端代码添加在已经由美工设计好的静态页面上,经过一个JSP容器对JSP文件进行自动解析并转换成Servlet类(jsp to servlet 编译过程)来交给WEB服务器运行。这么一来,极大的提高了工作效率。
其中jsp与servlet是没有本质区别的,因为jsp最后在提交的时候还是要编译成servlet类。JSP是Servlet技术的扩展,是基于java servlet技术,本质上是Servlet的简易方式,更强调应用的外表表达。Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,servlet主要用于控制逻辑。

当我们访问一个JSP页面的时候,这个文件首先会被JSP引擎翻译为一个Java源文件,其实就是一个Servlet,并进行编译,然后像其他Servlet一样,由Servlet引擎来处理。Servlet引擎装载这个类,处理来自客户的请求,并把结果返回给客户,以后再有客户访问这个页面的时候,只要该文件没有发生过更改,JSP引擎就直接调用已经装载的Servlet。如果已经做过修改的话,那就会再次执行以上过程,翻译、编译并装载。

Servlet的生命周期

servlet容器负责加载和实例化servlet 。这个生存期由javax.servlet.Servlet接口的init,service和destroy方法表达。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。

 只有一个servlet对象

 第一次请求的时候被初始化,只一遍

 初始化后先调用init方法,只一遍

 每个请求,调用一遍serviceàserviceàdoGet/doPost。以多线程的方式运行

 不要在servlet中设计成员变量。

 卸载前servlet容器调用destroy方法

forward() 与redirect()的区别

前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。

Sendredirect

Forward

是不同的request

虽然是不同的对象,但是,可以取到上一个页面的内容

send后的语句会继续执行,除非return

forward后的语句不会继续发送给客户端

速度慢

速度快

需要到客户端的往返,可以转到任何页面,

服务器内部转换,

地址栏有变化

地址栏没有变化

可以传参数,直接写在url后面

可以传参数

 

JSP相关知识点

 

JSP 知识点可以用"23379"来概括,即两种注释,三种指令,三个脚本元素,七个动作,九个内置对象。具体如下:

 

两种注释

一种是HTML的注释,用于描述JSP页面执行后的结果页面的功能:<!-- -->:可以在客户端显示,查看HTML文件时可以显示

一种是JSP本身的,用来描述JSP代码的:<%-- --%>:只在源代码中显示,在客户端不可以显示

 

三种指令

 

page指令:描述了和页面相关的指示信息。在一个页面中,page指令可以出现多次,但是每一种属性只能出现一次(除了import属性),重复的属性设置将覆盖先前的设置。

<%@page language=" " session="true|false" erroPage=" " isErrorPage="

import=" "...%>

在一个JSP文件中可以定义多个page指令,但不可以多次指定同一属性,除了import属性。

记住:在JSP中缺省导入的包有java.lang javax.servlet javax.servlet.http javax.servlet.jsp.

session属性的缺省值是true,如果指定session="false",则session隐含变量未定义,使用时将引起错误。

 

include指令:用来包含另一个文件

<%@include file=" "%> :将指定的JSP程序或者HTML文件包含近来

 

taglib指令:用来指示这个JSP页面所使用的标签库

<%@ taglib uri=" " prefix=" " %>

 

三个脚本元素

 

<%! ...%>声明:页面范围的变量和方法的声明,被声明的变量和方法将在JSP页面初始化时初始化。

实际上,声明变量和方法的语句完全可以放在脚本中<% ... %>,两者的区别是在生成的servlet中写入代码的位置,放在<%! ...%>中的声明语句在编译为Servlet的时候将作为类的成员(在_jspService()方法之外)而存在,而放在<% ... %>中的声明将放在_jspService()方法内部被声明。因此在声明中声明的变量是全局的,在脚本中声明的变量是局部的。因此在声明中声明的变量对脚本,表达式,HTML都是可见的,但在脚本中声明的变量仅在脚本范围内可见。在声明中可以:变量声明:小心变量的写权限,因为servlet默认是多线程的。

方法定义:因为生成的代码不在_jspService()方法中,所以它没有权限访问内置对象,如果要使用它们,必须将之显式传递到方法中。、

内部类定义:内部类式解决类型安全方式中的方案之一

 

<% ... %>脚本(Scriptlet):嵌入页面内的JAVA程序片段

在脚本中使用的式JAVA中的语法。

Scriptlet代码成了Servlet中_jspService()方法的一部分

而上面声明中的代码是在_jspService()方法之外(作为类的成员)与生成的源文件合成一体。

注意Scriptlet,表达式,HTML代码全部集成到_jspService()方法中。

 

<%=...%>表达式:把表达式变成String类型以便于包含在页面的输出中

注意表达式一定要有一个可以输出的值才可以。

 

七个动作

 

动作可以影响输出的文本流,使用编辑建立对象。

id属性和scope属性式每一个JSP动作都具有的属性,其中id表示一个动作的名称,而scope表示一个动作的作用域。

scope作用域的取值有:

page:由javax.servlet.jsp.PageContext得到在用户请求次页面过程中有效

request:由ServletRequest.getAttribute(name)得到在用户的整个请求过程中有效

session:由HttpSession.getValut(name)得到在用户的整个会话期有效

application:由ServletContext.getAttribute(name)得到在WEB应用程序执行期间有效

 

<jsp:useBean> </jsp:useBean> :是JSP中最重要的一个动作,它可以动态使用JavaBeans组件来扩充JSP的功能。

<jsp:setProperty> </jsp:setProperty> :用于向一个JavaBean的属性赋值。注意在这个动作中使用到的name属性的值将是一个前面已经使用<jsp:useBean> 动作引入的JavaBean的名字。

<jsp:getProperty> </jsp:getProperty> :用于从一个JavaBean中得到某个属性的值,无论原来这个属性是什么类型的,都将被转换成一个String类型的值。

<jsp:include page=" "> </jsp:include>:用于引入一个静态或动态的页面到JSP文件中,该动作可以包含一个或几个<jsp:param> 子动作用于向要引入的页面传递参数。

<jsp:forward page=" "> </jsp:forward>:用于引导客户端的请求到另一个页面或者是另一个Servlet中去。该动作可以包含一个或几个<jsp:param> 子动作用于向要引入的页面传递参数。

当<jsp:forward>动作发生的时候,如果已经有文本被写入输入流而且页面没有设置缓冲,那么将抛出IllegalStateException异常。

<jsp:param name=" " value=" "/>:常常是作为<jsp:include >,<jsp:forward>,<jsp:plugin> 的子动作使用。

<jsp:plugin type="applet|javabean"> </jsp:plugin>:用的较少,它提供了一种在JSP文件种嵌入客户端运行的JAVA程序(如:APPLET,JAVABENA)的方法。

 

九个内置对象

 

内置对象(又叫隐含对象,有9个内置对象):不需要预先声明就可以在脚本代码和表达式中随意使用

out:javax.servlet.jsp.JspWriter类型,代表输出流的对象。作用域为page(页面执行期)

 

config:javax.servlet.ServletConfig,作用域为page(页面执行期)

 

exception:java.lang.Throwable,通过JSP错误页面中一个catch块已经益出但没有捕获的java.lang.Throwable的任意实例,传向了errorPage的URI。作用域为page(页面执行期)。注意exception只有在page指令中具有属性isErrorPage="true"时才有效。

 

page:java.lang.Object类型,指向页面自身的方式。作用域为page(页面执行期)

 

pageContext:javax.servlet.jsp.PageContext(抽象类)类型,作用域为page(页面执行期)。此对象提供所有四个作用域层次的属性查询和修改能力,它也提供了转发请求到其它资源和包含其他资源的方法:

该对象的方法都是抽象方法

 

request:javax.servlet.ServletRequest的子类型,此对象封装了由WEB浏览器或其它客户端生成地HTTP请求的细节(参数,属性,头标和数据)。作用域为request(用户请求期)。

方法由:

java.lang.String getHeader(java.lang.String name)

java.util.Enumeration getHeaderNames()

HttpSession getSession()

java.lang.String getParameter(java.lang.String name)

java.util.Enumeration getParameterNames()

void setCharacterEncoding(java.lang.String env)

java.lang.Object getAttribute(java.lang.String name)

java.util.Enumeration getAttributeNames()

void removeAttribute(java.lang.String name)

 

response:javax.servlet.ServletResponse的子类型,此对象封装了返回到HTTP客户端的输出,向页面作者提供设置响应头标和状态码的方式。经常用来设置HTTP标题,添加cookie,设置响应内容的类型和状态,发送HTTP重定向和编码URL。作用域为page(页面执行期)。

方法有:

void sendRedirect(java.lang.String location)

boolean isCommitted()

void setStatus(int sc)

void setHeader(java.lang.String name, java.lang.String value)

void addHeader(java.lang.String name, java.lang.String value)

 

session:javax.servlet.http.HttpSession类型,主要用于跟踪对话。作用域session(会话期—)。HttpSession是一个类似哈希表的与单一WEB浏览器会话相关的对象,它存在于HTTP请求之间,可以存储任何类型的命名对象。

如果不需要在请求之间跟踪会话对象,可以通过在page指令中指定session="false"

方法有:

java.lang.Object getAttribute(java.lang.String name)

java.util.Enumeration getAttributeNames()

void setAttribute(java.lang.String name, java.lang.Object value)

long getCreationTime()

java.lang.String getId()

需要记住的是pageContext对象也可以与session.getAttribute(),session.setAttribute()一样的方式取得并设置会话属性。

 

application:javax.servlet.ServletContext类型,servlet的环境通过调用getServletConfig().getContext()方法获得。作用域是application(整个程序运行期)。它提供了关于服务器版本,应用级初始化参数和应用内资源绝对路径,注册信息的方式

方法有:

java.lang.String getRealPath(java.lang.String path) :获取应用内资源绝对路径

java.lang.String getServerInfo() :获取服务器信息

java.lang.String getInitParameter(java.lang.String name) :获取应用级初始化参数

java.util.Enumeration getInitParameterNames()

java.lang.Object getAttribute(java.lang.String name)

void setAttribute(java.lang.String name, java.lang.Object object) //这两个方法同seesion中的方法有一样的作用,只不过它跟踪的会话信息的范围更大了,是整个application.在实际应用中,根据需要选择使用哪个进行跟踪会话。

Servlet三个要素

1.必须继承自HttpServlet

2.必须实现doGet()或者doPost()

3.必须在web.xml中配置Servlet

<servlet>

<servlet-name></servlet-name>

<servlet-class></servlet-class>

</servlet>

<servlet-mapping>

<servlet-name></servlet-name>

<url-pattern></url-pattern>

</servelt-mapping>

 

HttpServeltRrequest:请求对象

getParameter():获得表单元素的值

getAttribute():获得request范围中的属性值

setAttribute():设置reqeust范围中的属性值

setCharacterEncoding():设置字符编码

 

HttpSerletResponse:相应对象

sendRedirect():外部跳转

getWriter():获得输出流对象

setContentType("text/html; charset=utf-8"):设置相应内容格式和编码

1.必须继承自HttpServlet

2.必须实现doGet()或者doPost()

3.必须在web.xml中配置Servlet

<servlet>

<servlet-name></servlet-name>

<servlet-class></servlet-class>

</servlet>

<servlet-mapping>

<servlet-name></servlet-name>

<url-pattern></url-pattern>

</servelt-mapping>

 

HttpServeltRrequest:请求对象

getParameter():获得表单元素的值

getAttribute():获得request范围中的属性值

setAttribute():设置reqeust范围中的属性值

setCharacterEncoding():设置字符编码

 

HttpSerletResponse:相应对象

sendRedirect():外部跳转

getWriter():获得输出流对象

setContentType("text/html; charset=utf-8"):设置相应内容格式和编码

 

四种会话跟踪方式

1.Session

HttpSession session = request.getSession();

session.setAttribute("name", "zhangsan");

session.setAttribute("pwd", "aaa");

String name = (String) session.getAttribute("name");

 

2.cookie:

//创建Cookie

Cookie cookie = new Cookie("name", "zhangsan");

//设置Cookie的超时时间

cookie.setMaxAge(24 * 60 * 60 *60);

//把Cookie发送到客户端

response.addCookie(cookie);

 

//得到客户端发送的Cookie

Cookie [] cookies = request.getCookies();

for(int i=0; i<cookies.length; i++) {

Cookie temp = cookies[i];

String key = temp.getName();

String value = temp.getValue();

}

 

3.隐藏表单域

<input type="hidden" name="name" value="zhangsan" />

request.getParameter("name");

 

4.Url重写

问号传参

LoginServlet?username=zhangsan&pwd=123

String name = request.getParameter("username");

String pwd =request.getPareameter("pwd");

1.Session

HttpSession session = request.getSession();

session.setAttribute("name", "zhangsan");

session.setAttribute("pwd", "aaa");

String name = (String) session.getAttribute("name");

 

2.cookie:

//创建Cookie

Cookie cookie = new Cookie("name", "zhangsan");

//设置Cookie的超时时间

cookie.setMaxAge(24 * 60 * 60 *60);

//把Cookie发送到客户端

response.addCookie(cookie);

 

//得到客户端发送的Cookie

Cookie [] cookies = request.getCookies();

for(int i=0; i<cookies.length; i++) {

  Cookie temp = cookies[i];

  String key = temp.getName();

  String value = temp.getValue();

}

 

3.隐藏表单域

<input type="hidden" name="name" value="zhangsan" />

request.getParameter("name");

 

4.Url重写

问号传参

LoginServlet?username=zhangsan&pwd=123

String name = request.getParameter("username");

String pwd =request.getPareameter("pwd");

内部跳转和外部跳转

内部跳转:

LoginServlet

request.getRequestDispatcher("index.jsp").forward(request, resposne);

外部跳转:

response.sendRedirect("index.jsp");

内部跳转是一次请求和一次响应

外部跳转是两次请求和两次响应

内部跳转:

LoginServlet

request.getRequestDispatcher("index.jsp").forward(request, resposne);

外部跳转:

response.sendRedirect("index.jsp");

内部跳转是一次请求和一次响应

外部跳转是两次请求和两次响应

1.静态内容:html

2.指令:page, include, taglib:

<%@ 指令名 属性1="属性值1" 属性2="属性值2" %>

3.表达式:<%=表达式 %>

4.Scriptlet<% Java代码 %>

5.声明:<%! %>:变量和方法

6.动作:<jsp:动作名 属性="属性值"></jsp:动作名>

7.注释:

客户端看不到的:<%-- --%>

客户端可以看到的:<!-- -->

Jsp的执行过程

1.转译:Jsp--->Servlet

2.编译:Servlet---->.class

3.执行:.class

第一次访问jsp的时候响应速度较慢,后面请求时响应速度快

1.转译:Jsp--->Servlet

2.编译:Servlet---->.class

3.执行:.class

第一次访问jsp的时候响应速度较慢,后面请求时响应速度快