• 第一章_servlet


    [Servlet与Jsp学习指南]

    *学习这servlet前。需要下载servlet-api.jar,MyEclipse给自己带来的需求javaEE3.0的天赋足以使用注解获得的版本号servlet

    1.1Servlet API概述

    Javax.servlet 包括定义ServletServlet容器之间契约的类和接口

    Javax.servlet.http 包括定义http servletservlet容器之间契约的类和接口

    Javax.servlet.annotation 包括对servletfilterlistener进行标注的注解。它还为标注元件指定元数据。

    Javax.servlet.descriptor 包括为web应用程序的配置信息提供编程式訪问的类型。

    Servlet技术的核心是Servlet接口。这是全部Servlet类都必须直接或者间接实现的一个接口。用户的请求会引发Servlet容器调用一个servletservice方法,并给这种方法传入一个ServletRequest实例和一个ServletResponse实例。

    1.2Servlet

    Servlet接口定义了下面5个方法。

    Void init(ServletConfig config) throws ServletException

    Void service(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOException

    Void destroy()

    java.lang.String getServletInfo()

    ServletConfig getServletConfig()

    Initservicedestroy方法属于Servlet声明周期方法。Servlet容器将依据下面原则调用这三个方法。

    1. Init

    第一次请求Servlet时,Servlet容器就会调用这种方法。在兴许的请求中,将不再调用该方法。

    能够利用这种方法来编写一些应用程序初始化相关的代码。在调用这种方法时,Servlet容器会传递一个ServletConfig。一般来说,会将ServletConfig赋给一个类级变量,以便Servlet类中的其它方法也能够使用这个对象。

    2. Service。每次请求Servlet时,Servlet容器都会调用这种方法。

    必须在这里编写要Servlet完毕的对应代码。第一次请求Servlet时,Servlet容器会调用init方法和service方法,对于兴许请求,则仅仅调用service方法。

    3. Destroy

    要销毁Servlet时,Servlet容器就会调用这种方法。它通常发生在卸载应用程序,或者关闭Servlet容器的时候。

    一般来说,能够在这种方法中编写一些资源清理相关的代码。

    Servlet中的另外两个方法是非声明周期方法:getServletInfogetServletConfig

    1.  getServletInfo

    该方法返回Servlet的描写叙述,能够返回可能实用的随意字符串,甚至是null

    2. getServletConfig。该方法返回由Servlet容器传给init方法的ServletConfig。可是,为了让getServletConfig返回非null值。你肯定已经为传给init方法的ServletConfig赋给了一个类级变量。

    *必须注意个一点是线程安全性。一个应用程序中的全部用户将共用一个Servlet实例。因此不建议使用类级变量。除非他们是仅仅读的,或者是java.util.concurrent.atomic包中的成员。

    1.3、编写基础的Servlet应用程序

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    @WebServlet(name="MyServlet",urlPatterns={"/my"})
    public class MyServlet implements Servlet{
    	private transient ServletConfig servletConfig ;
    
    	@Override
    	public void destroy() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public ServletConfig getServletConfig() {
    		// TODO Auto-generated method stub
    		return servletConfig;
    	}
    
    	@Override
    	public String getServletInfo() {
    		// TODO Auto-generated method stub
    		return "My Servlet";
    	}
    
    	@Override
    	public void init(ServletConfig servletConfig) throws ServletException {
    		// TODO Auto-generated method stub
    		this.servletConfig = servletConfig ;
    	}
    
    	@Override
    	public void service(ServletRequest req, ServletResponse res)
    			throws ServletException, IOException {
    		// TODO Auto-generated method stub
    		String servletName = servletConfig.getServletName() ;
    		res.setContentType("text/html");
    		PrintWriter writer = res.getWriter() ;
    		writer.print("<html><head></head><body>Hello from " + servletName + "</body></html>") ;
    	}
    	
    }
    

    1.4ServletRequest

    对于每个HTTP请求,Servlet容器都会创建一个serveltRequest实例,并将它传给Servletservice方法。ServletRequest封装有关请求的信息。

    以下是ServletRequest接口中的方法。

    Public int getContentLength()

    返回请求主体中的字节数。假设不知道字节的长度,该方法将返回-1

    Public java.lang.String getContentType()

    返回请求主体MIME类型,假设不知道类型。则返回null

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

    返回指定请求參数的值

    Public java.lang.String getProtocol()

    返回这个HTTP请求的协议名称和版本

    getParameterServletRequest中最经常使用的方法。

    该方法通经常使用来返回一个HTML表单域的值。

    getParameter也能够用来获取查询字符串的值。比如:假设利用以下这个URI调用一个servlet

    http://domain/context/servletName?

    id=123

    将能够在Servlet中利用以下这个语句来获取id的值

    String id = request.getParameter(“id”) ;

    注意。假设该參数不存在,那么getParameter将返回null

    1.5ServletResponse

    ServletResponse中定义的当中一个方法是getWriter方法,它返回能够将文本传给client的java.io.PrintWriter。在默认情况下,PrintWriter对象採用ISO-8859-1编码。

    1.6ServletConfig

    为了从一个Servlet内部获取某个初始參数的值。应该在由Servlet容器传给Servletinit方法的ServletConfig中调用getInitParameter方法。

    getInitParameter方法的签名例如以下:

    java.lang.getInitParameter(java.lang.String name) ;

    此外,getInitParameterNames方法则是返回全部初始化參数名称的一个Enumeration

    java.util.Enumeration<java.lang.String> getInitParameterNames()

    除了这2个方法外,ServletConfig还提供了还有一个非常实用的方法:getServletContext。能够利用这种方法从Servlet内部获取ServletContext


    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebInitParam;
    import javax.servlet.annotation.WebServlet;
    @WebServlet(name="ServletConfigDemoServlet",
    		urlPatterns={"/servletConfigDemo"},
    		initParams={
    			@WebInitParam(name="admin",value="Benjamin"),
    			@WebInitParam(name="email",value="whx449261417@sina.com")
    		}
    	)
    public class ServletConfigDemoServlet implements Servlet{
    	private transient ServletConfig servletConfig ;
    	@Override
    	public void destroy() {
    	}
    
    	@Override
    	public ServletConfig getServletConfig() {
    		// TODO Auto-generated method stub
    		return servletConfig;
    	}
    
    	@Override
    	public String getServletInfo() {
    		// TODO Auto-generated method stub
    		return "servletConfig demo";
    	}
    
    	@Override
    	public void init(ServletConfig servletConfig) throws ServletException {
    		// TODO Auto-generated method stub
    		this.servletConfig = servletConfig ;
    	}
    
    	@Override
    	public void service(ServletRequest req, ServletResponse res)
    			throws ServletException, IOException {
    		ServletConfig servletConfig = getServletConfig() ;
    		String admin = servletConfig.getInitParameter("admin") ;
    		String email = servletConfig.getInitParameter("email") ;
    		res.setContentType("text/html");
    		PrintWriter writer = res.getWriter() ;
    		writer.print("<html><head></head><body>Admin:"+admin+"<br/>Email:"+email+"</body></html>") ;
    	}
    	
    }
    


    1.7ServletContext

    ServletContext标识Servlet应用程序。每一个Web应用程序仅仅有一个context。在分布式环境中,一个应用程序同一时候部署到多个容器中。而且每台java虚拟机都有一个ServletConfig对象。

    ServletConfig中调用getServletContext方法能够获得ServletContext

    1.8GenericServlet

    GenericServlet通过在init方法中将ServletConfig对象赋给一个类级变量servlet-config,实现对ServletConfig的保存。以下是GeneericServlet的源码:

    package javax.servlet;
    
    import java.io.IOException;
    import java.io.Serializable;
    import java.util.Enumeration;
    import java.util.ResourceBundle;
    
    public abstract class GenericServlet
      implements Servlet, ServletConfig, Serializable
    {
      private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
      private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
      private transient ServletConfig config;
    
      public void destroy()
      {
      }
    
      public String getInitParameter(String name)
      {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
          throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
        }
    
        return sc.getInitParameter(name);
      }
    
      public Enumeration<String> getInitParameterNames()
      {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
          throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
        }
    
        return sc.getInitParameterNames();
      }
    
      public ServletConfig getServletConfig()
      {
        return this.config;
      }
    
      public ServletContext getServletContext()
      {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
          throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
        }
    
        return sc.getServletContext();
      }
    
      public String getServletInfo()
      {
        return "";
      }
    
      public void init(ServletConfig config)
        throws ServletException
      {
        this.config = config;
        init();
      }
    
      public void init()
        throws ServletException
      {
      }
    
      public void log(String msg)
      {
        getServletContext().log(getServletName() + ": " + msg);
      }
    
      public void log(String message, Throwable t)
      {
        getServletContext().log(getServletName() + ": " + message, t);
      }
    
      public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
        throws ServletException, IOException;
    
      public String getServletName()
      {
        ServletConfig sc = getServletConfig();
        if (sc == null) {
          throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
        }
    
        return sc.getServletName();
      }
    }

    大家考虑一下为什么GenericServlet中有两个init方法?

    GenericServlet通过在init方法中将ServletConfig对象赋给一个类级变量servletConfig,实现对ServletConfig的保存。

    可是假设在类中覆盖了这种方法,则调用servlet中的init方法。而且必须调用super.init(servletConfig)来保存ServletConfig。为了避免这么做。GenericServlet又另外提供了一个init方法,它不带參数。当把ServletConfig赋给servletConfig之后。这种方法就会被第一个init方法调用。从而不影响servletConfig的创建。

    1.9HTTP Servlet

    1.9.1 HttpServlet

    HttpServlet类覆盖javax.servlet.GenericServlet类。在使用HttpServlet时,还要使用HttpServletRequestHttpServletResponse对象,它们分别标识Servlet请求和Servlet响应。

    HttpServletRequest接口集成javax.servlet.ServletRequestHttpServletResponse继承javax.servlet.ServletResponse

    这个新的service方法与javax.servlet.Servlet中的差别在于。前者接受的是HttpServletRequestHttpServletResponse,而不是ServletRequestServletResponse

    原始的service方法将请求和响应对象进行向下转换。分别从Servlet容器转换成HttpServletRequestHttpServletResponse,并调用新的service方法。

    HttpServlet中新的service方法会查看通经常使用来发送琴秋(通过调用request.getMethod)Http方法,并调用下面某个方法(doGetdoPostdoHeaddoPutdoTracedoOptionsdoDelete)

    总之,HttpServlet中有两项特性是GenericServlet所没有的:

    1、不覆盖service方法,而是覆盖doGetdoPost,或者两者都覆盖调。

    2、将用HttpServletRequestHttpServletResponse取代ServletRequestServletResponse

    1.9.2 HttpServletRequest

    HttpServletRequest表示HTTP环境中的Servlet请求。它集成javax.servlet.ServletRequest接口。并添加了几个方法。比如:

    Java.lang.String getContextPath()

    返回表示请求context的请求URI部分。

    Cookie[] getCookies()

    返回一个Cookie对象数组

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

    返回指定HTTP标头的值

    java.lang.String getMethod()

    返回发出这条请求的HTTP方法的名称

    java.lang.String getQueryString()

    返回请求URL中的查询字符串

    HttpSession getSession()

    返回与这个请求有关的session对象。

    假设没有找到,则创建新的session对象。

    HttpSession getSession(boolean create)

    返回与这个请求有关的session对象。假设没有找到,而且create參数为true,那么将创建新的session对象。假设为false,返回空

    1.9.3 HttpServletResponse

    HttpServletResponse表示HTTP环境下的Servlet响应。以下是当中定义的部分方法:

    Void addCookie(Cookie cookie)

    给这个响应对象加入cookie

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

    给这个响应对象加入标头

    Void sendRedirect(java.lang.String location)

    发送响应代号,将浏览器重定向到指定的位置

    1.10、处理HTML表单

    1.11使用部署描写叙述符(配置文件)

    package app01c;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @SuppressWarnings("serial")
    public class SimpleServlet extends HttpServlet{
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    			throws ServletException, IOException {
    		resp.setContentType("text/html") ;
    		PrintWriter writer = resp.getWriter() ;
    		writer.print("<html><head></head><body>Simple Servlet</body></html>") ;
    	}
    }
    

    package app01c;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @SuppressWarnings("serial")
    public class WelcomeServlet extends HttpServlet{
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    			throws ServletException, IOException {
    		resp.setContentType("text/html") ;
    		PrintWriter writer = resp.getWriter() ;
    		writer.print("<html><head></head><body>Welcome</body></html>") ;
    	}
    }
    


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
    	xmlns="http://java.sun.com/xml/ns/javaee" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      <servlet>
      	<servlet-name>ss</servlet-name>
      	<servlet-class>app01c.SimpleServlet</servlet-class>
      	<load-on-startup>10</load-on-startup>
      </servlet>
      <servlet-mapping>
      	<servlet-name>ss</servlet-name>
      	<url-pattern>/simple</url-pattern>
      </servlet-mapping>
      
       <servlet>
      	<servlet-name>ww</servlet-name>
      	<servlet-class>app01c.WelcomeServlet</servlet-class>
      	<load-on-startup>20</load-on-startup>
      </servlet>
      <servlet-mapping>
      	<servlet-name>ww</servlet-name>
      	<url-pattern>/welcome</url-pattern>
      </servlet-mapping>
    </web-app>
    

    这样我们就能够利用以下这些路径去訪问它们了:

    http://localhost:8080/app01c/simple

    http://localhost:8080/app01c/welcome

    1.12、小结

    Servlet技术是JavaEE技术的组成部分。Servlet容器中执行的全部Servlet,以及容器与Servlet之间的契约,都採用了javax.servlet.Servlet接口的形式。Javax.servlet包也提供了实现Servlet接口的GenericServlet抽象类。

    这是一个便利类。能够通过扩展它来创建Servlet。可是,大多数现代的Servlet都在HTTP环境中处理请求。因此,将javax.servlet.http.HttpServlet类子类化会更有意义。HttpServlet类本身也是GenericServlet的一个子类。




    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    [mac]macOS Big Sur大苏尔动态壁纸下载
    JAVA各种OOM代码样例及解决方法
    详解Flask上下文
    Python代码规范检测
    深入掌握K8S Pod
    Java中包装类Test类测试出错的解决方法(JUnit5)
    细说selenium的等待条件
    利用tox打造自动自动化测试框架
    JAVA实现BP神经网络算法
    Oracle游标简介与使用
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4872822.html
Copyright © 2020-2023  润新知