zoukankan      html  css  js  c++  java
  • Servlet 学习总结

     

    Servlet资料整理【很全很强大】

    分类: J2EE 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>
  • 相关阅读:
    UEditor使用报错Cannot set property 'innerHTML' of undefined
    freemarker如何在url中传递中文参数
    freemarker字符串转换成日期和时间
    freemarker 类型转换
    内存分析工具 MAT 的使用
    Ubuntu13.04下Eclipse中文乱码解决
    自定义上下文对话框
    格局中@null的代码实现方式
    Android xml资源文件中@、@android:type、@*、?、@+含义和区别
    探讨:你真的会用Android的Dialog吗?
  • 原文地址:https://www.cnblogs.com/isoftware/p/3748450.html
Copyright © 2011-2022 走看看