Servlet 学习总结

分类: J2EE2009-10-23 00:51 671人阅读 评论(0) 收藏 举报
    刚学习完了Servlet相关的知识,现在做一下整理以备日后方便查找与复习.
一.Servlet的定义
    Servlet是一个位于服务器端的独立于平台和协议的Java应用程序,可以生成动态的web页面,也可以像jsp一样直接输出信息.
    Servlet类是一个继承了HttpServlet类的Java类,但是有自己的规则.Servlet是位于Web服务器内部的服务器端的Java应用程序,像所有的Java程序一样,Servlet拥有面向对象Java语言的所有优势 
    Servlet必须在web.xml文件中注册.服务器启动的时候,可以根据这些配置来加载Servlet类.
二.Servlet的作用:
    Servlet主要用来在控制层结合mvc模式做控制转发.
Servlet的应用:
    表单是HTML中使用最广泛的传递信息的手段,Servlet使用HttpServlet类中的方法与表单进行交互,HTTPServer把客户请求正确的映射到相应的函数上:
a) doGet 用于处理GET请求,也可以自动的支持HEADER请求
b) doPost 用于处理POST请求
三.Servlet的生命周期
Servlet继承了HTTPServlet类,所以要扩展父类中的方法:
1.init()方法:
在 Servlet 的生命期中,仅执行一次init方法.它是在服务器装入 Servlet 时执行的.
例:
 /**
  * Initialization of the servlet. <br>
  *
  * @throws ServletException if an error occure
  * 在servlet被第一次访问时,本方法将会被自动调用
  * 本方法被称为初始化方法
  * 只会被调用一次
  */
 public void init() throws ServletException {
  // Put your code here
  System.out.println("我是init方法");
 }
2.service()方法:
service方法是Servlet的核心.每当一个客户请求一个HttpServlet对象,该对象的service()方法就要被调用,doGet和doPost这两个方法是由service方法调用的 
例:
 /**
  * 具体的业务方法
  * 该方法将会被调用多次
  * 每次访问servlet时,该方法都会被调用
  * service根据request.getMethod得到你的提交方式,然后由它来决定对doGet.doPost的调用
  */
 public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
  super.service(request, response);
  System.out.println("我是service.....................................");
 }
3.destroy()方法 
destroy()方法仅执行一次,即在服务器停止且卸装Servlet时执行该方法.
例:
  /**
  * Destruction of the servlet. <br>
  * servlet被注销的时候
  * 本方法为销毁方法
  * 也只是被服务器自动调用一次
  * 
  */
 public void destroy() {
  super.destroy(); // Just puts "destroy" string in log
  // Put your code here
  System.out.println("destroy方法被调用..............");
 }
四.Servlet定义的步骤
1.定义一个类,继承HTTPServlet类.
2.重写doGet和doPost方法.
3.实现doGet和doPost的逻辑.
4.在web.xml部署描述文件中定义Servlet的映射方式.
五.Servlet在web.xml中的配置
1.配置说明
<servlet>内的<servlet-name>,是一个逻辑名,可以是任何有效的标识名;
<init-param>是Servlet初始参数在Servlet的init()方法中通过getInitParameter(“ip”)取得,返回String型数据;
 
<servlet- mapping>内的<servlet-name>与<servlet>内的<servlet-name>一一对应,把客户端对/HelloServlet的请求对应到<servlet- class>project1.HelloServlet</servlet-class>所指定的位置;
<url-pattern>/HelloServlet</url-pattern>指在IE url中的请求形式.这里的/是相对于当前的web目录的.
例:
<servlet> 
   <servlet-name>HelloServlet</servlet-name> 
   <servlet-class>project1.HelloServlet</servlet-class> 
</servlet>
<servlet-mapping> 
   <servlet-name>HelloServlet</servlet-name> 
   <url-pattern>/HelloServlet</url-pattern> 
</servlet-mapping>
2.欢迎页面的设置:
<welcome-file-list> 
 <welcome-file>index.html</welcome-file> 
 <welcome-file>index.htm</welcome-file> 
 <welcome-file>index.jsp</welcome-file> 
</welcome-file-list>
如果第一个页面找不到,会依次向下找
3.errorpage的配置:
<error-page>
<error-code>404</error-code>
<location>/notFileFound.jsp</location>
</error-page>
<error-page>
 <exception-type>java.lang.NullPointerException</exception-type>
 <location>/null.html</location>
</error-page>
4.为Servlet定义初始化参数
使用getInitParameter()方法来提取servlet的初始化参数
定义如下:
<servlet>
    <servlet-name>a</servlet-name>
    <servlet-class>jsj.lx.demo.MyServlet</servlet-class>
    <init-param>
    <param-name>type</param-name>
    <param-value>text/html;charset=GBK</param-value>
    </init-param>
</servlet>
提取方式:
String str = this.getInitParameter("type");
六.用Servlet控制会话
    Servlet定义了一个HTTPsession接口,实现session的功能.在访问者从某个特定的主页到离开为止的那段时间,每个访问者都会单独获得一个session.
    使用HTTPServletRequest的getSession方法得到当前存在的session,如果当前没有定义session,则创建一个新的session.
    当用完session后,可以使用session.invalidate()方法关闭session.但是这并不是严格要求的.因为,Servlet引擎在一段时间之后会自动关闭session.还可以在web.xml中配置session的过期时间,单位是分钟:
<session-config> 
    <session-timeout>30</session-timeout>
</session-config>
例:
(1)
HttpSession session = request.getSession();
session.setAttribute("username", "scott");
RequestDispatcher rd  = request.getRequestDispatcher("A.jsp");
rd.forward(request, response);
(2)
HttpSession ss = request.getSession();
List list=new ArrayList();
list.add("SMITH");
list.add("ALLEN");
ss.setAttribute("userlist", list);
七.Filter过滤器
1.定义:ServletFilter是Servlet2.3规范中新增加的,它是截取用户从客户端提交的请求,在还没有到达需要访问的资源时欲行的一个类.它的操纵来自客户端的请求,在资源还没有发送到客户端前截取响应,并处理这些还没有发送到客户端的响应.
2.ServletFilter的作用:
权限的校验,日志记录,图片的转换,数据的加密等等.
3.实现:一个ServletFilter可以分为两部分:Java类自身以及在web.xml文件中xml.
要作为 ServletFilter的Java类必须实现Filter接口.该接口由一对自描述的生命周期方法 init(FilterConfig),destroy()和一个行为方法doFilter(ServletRequest, ServletResponse, FilterChain).
4.实现步骤:
a.实现Filter接口
b.实现doFilter方法
c.传递过滤链,放请求通过
d.在web.xml文件中注册过滤器
八.监听器Listener
1.定义:Listioner是Servlet的监听器,它可以监听客户端的请求,服务取得操作等.
通过监听器,可以自动激发一些操作,比如监听在先的用户的数量.当增加一个HTTPsession时,就激发sessionCreated(HTTPsessionEvent sec)方法,这样就可以进行页面访问统计了.
2.常用监听接口:
a) ServletContextAttributeListenner监听对ServletContext属性的操作,比如增加,删除,修改属性.
b) ServletContextListener监听ServletContext.
当创建ServletContext时,激发contextInitialized(ServletContextEvent sce)方法.
当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法.
c) HttpSessionListener监听HttpSession的操作
当创建一个Session时,激发sessionCreated(HttpSessionEvent se)方法;
当销毁一个Session时,激发sessionDestroyed(HttpSessionEvent se)方法.
d) HttpSessionAttributeListener监听HttpSession中的属性的操作
当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;
当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;
当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se)方法.
Listener的配置:
<listener> 
    <listener-class>OnLineCountListener</listener-class> 
</listener>
九.字符的中文转换问题
中文转换可以分多种情况:
1.如果页面中使用jsp:include或jsp:forward关系,中文字符集转换用:
request.setCharacterEncoding("GBK");
2.在Servlet中显示中文:
由于无法使用jsp页面中的编码指令
<%@ page language="java" import="java.util.*" contentType="text/html;charset=GBK"%>
那么在Servlet中设置输出编码就应该通过:
response.setContentType("text/html;charset=GBK");
3.普通的参数传递
普通的参数也需要考虑到中文的问题.除了页面显示设置contentType="text/html;charset=GBK"之外,我们还需要对中文字符进行字符转换硬编码:
超链接:
String str = request.getParameter("username");
str = new String(str.getBytes("iso8859-1"),"GBK");
form表单:
String str=     request.getParameter("username");
str = new String(str.getBytes("iso8859-1"),"GBK");
javascript转向:
String str =  request.getParameter("username");
str = new String(str.getBytes("ISO8859-1"),"gbk");
response方式转向:
String message = "我的中文测试";
response.sendRedirect("L.jsp?message="+URLEncoder.encode(message));
接收页面:
String message = request.getParameter("message");
message  = new String(message.getBytes("ISO8859-1"),"GBK");
request等作用域不需要进行转换,只要在页面显示设置中设置就可以了
request.setAttribute("username","我的测试名称");
session.setAttribute("passwd","我的密码");
十.Servlet线程
Servlet体系结构是建立在java多线程机制之上的,它的生命周期是由web容器负责的.当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类.当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例.Servlet容器会自动使用线程池等技术来支持系统的运行.
例:
boolean shutdown = true;
/**
* 线程体
*/
public void run(){
 int i = 0;
 while(true){
  i++;
  System.out.println(Thread.currentThread().getName()+"="+i);
  if(shutdown == false){
   break;
  }
 }
 System.out.println("本线程结束!");
}
java线程共享数据的概念:
多线程使用的数据是共享的,Servlet本身建立在多线程的基础上,所以对于全局变量也存在"共享数据"的问题.
在Servlet中定义一个全局变量,该数据将会被多个线程"共享"
例:
String username;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
 response.setContentType("text/html");
 PrintWriter out = response.getWriter();
 username = request.getParameter("username");
 
 try{
  Thread.sleep(1000*6);
 }catch(InterruptedException e){
  e.printStackTrace();
 }
 out.println(username);
 out.close();
}
对于上面这个例子,如果同时提交两个请求:
http://loclhost:8088/servlet/MyServlet?username=zhangsanfeng 
http://loclhost:8088/servlet/MyServlet?username=zhangwuji 
则两个结果都将显示为zhangwuji.
这是因为第一个在访问时,得到了zhangsanfeng的值,后来username的值被赋为zhangwuji.又因为username是被多个线程所共享的,所以所有里面的username都变成了zhangwuji.为了避免这样的错误,最好避免使用全局变量而使用临时变量.因为方法中的临时变量时在栈上分配空间,而且每个线程都有自己私有的栈空间,所以他们不会影响线程的安全.
十一.自动加载Servlet
Servlet有一个生命周期方法,init,service,destroy.其中init在 Servlet第一次访问的时候访问,它只能被访问一次.而如果你需要在服务器启动的时候让Servlet自动启动,你可以通过load-on- startup来实现.load-on-startup是web.xml文件中Servlet的配置节点.
举例:
如果想要在服务器启动时从数据库中查询所有的用户名列表,以便在其他页面中可以直接使用,而不需要从数据库在进行查询,如何实现?
1.ServletContentListener可以再服务器启动时自动执行其方法
2.可以使用一个Servlet,然后定义load-on-startup,让它能够在服务器启动时自动执行其方法.使用<load-on-startup>1</load-on-startup>可以指定服务器加载顺序.
代码如下:
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occure
* 本方法在servlet被加载时访问
* 这里,我们在服务器启动,自动加载一段数据,起到数据缓存的效果
*/
public void init() throws ServletException {
 // Put your code here
 List<String> list = new ArrayList<String>();
 list.add("WARD");
 list.add("JONES");
 list.add("JAMES");
 this.getServletContext().setAttribute("datalist",list);
}
配置文件设置:
<servlet>
   <servlet-name>DataCacheServlet</servlet-name>
   <servlet-class>com.sun.demo.DataCacheServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>
上一篇:Android优秀资源整理合集(论菜鸟到高级攻城狮)


下一篇:BZOJ4550 小奇的博弈 【Nimk游戏 + dp + 组合数】