javaweb-Servlet详解

Servlet 生命周期:

public class MyFirstServlrt implements Servlet {
 
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("Servlet正在初始化");
    }														//servlet init
 
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
 									//this method returns the ServletConfig object from the servlet container to init method
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //provide service
        System.out.println("Servlet正在提供服务");
 
    }
 
    @Override
    public String getServletInfo() {
        return null;
    }
 				//get a string about Serlvet information
    @Override
    public void destroy() {
        System.out.println("Servlet正在销毁");
    }
    			//destroy serlvet
}  

配置Servlet的Maven的依赖

<dependencies>
        <!-- servlet依赖的jar包start -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- servlet依赖的jar包start -->
        <!-- jsp依赖jar包start -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <!-- jsp依赖jar包end -->
        <!--jstl标签依赖的jar包start -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--jstl标签依赖的jar包end -->
    </dependencies>

配置Servlet的映射

<servlet>
    <servlet-name>ServletTest01</servlet-name>
    <servlet-class>edu.sdmu.SerlvetTest</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ServletTest01</servlet-name>
  <url-pattern>/Servlet01</url-pattern>
</servlet-mapping>
/*Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。*/
public interface ServletRequest{
    Object getAttribute(String var1)    //返回以var1为属性的值,如果该属性不存在则返回null
    Enumeration<String> getAttributeNames();   //返回所有属性的名字,如果没有则返回一个空的枚举
    String getCharacterEncoding();			//返回请求正文使用的字符编码的名字。如果请求没有指定字符编码,这个方法将返回null。
      void setCharacterEncoding(String var1) throws UnsupportedEncodingException;
    //覆盖在请求正文中所使用的字符编码的名字
    int getContentLength();        //以字节为单位,返回请求正文的长度。如果长度不可知,这个方法将返回-1
    long getContentLengthLong();   
    String getContentType();       //返回请求正文的MIME类型。如果类型不可知,这个方法将返回null   MIME:多用途互联网邮件扩展类型
    String getParameter(String var1);//返回请求参数的值
}

ServletResponse接口

public interface ServletResponse {
    String getCharacterEncoding();
		
    String getContentType();

    ServletOutputStream getOutputStream() throws IOException;   //向浏览器以二进制的形式发送数据

    PrintWriter getWriter() throws IOException;                 //返回了一个可以向客户端发送文本的的Java.io.PrintWriter对象

    void setCharacterEncoding(String var1);

    void setContentLength(int var1);

    void setContentLengthLong(long var1);

    void setContentType(String var1);

    void setBufferSize(int var1);

    int getBufferSize();

    void flushBuffer() throws IOException;

    void resetBuffer();

    boolean isCommitted();     //判断服务器端是否已经将数据输出到客户端。

    void reset();

    void setLocale(Locale var1);

    Locale getLocale();
}

ServletConfig接口

  • 初始化Servlet的时候,Init方法需要一个ServletConfig参数
public interface ServletConfig {
    String getServletName();       //获取servlet web.xml中的name值

    ServletContext getServletContext();		//返回指定上下文范围的初始化参数值。

    String getInitParameter(String var1);   //获得servlet的初始化参数

    Enumeration<String> getInitParameterNames();	//获得servlet初始化参数的名字		
}

ServletContext接口:

  • WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象包含Web应用中所有 Servlet 在 Web 容器中的一些数据信息。
  • ServletContext中不仅包含了 web.xml 文件中的配置信息,还包含了当前应用中所有Servlet可以共享的数据。
//常见的SerlvetContext方法
String getInitParameter ();     //获取web.xml文件的中指定名称的上下文参数值 。
Enumeration<String> getInitParameterNames();     //过去web.xml文件中所有的上下文参数,返回类型为枚举型
void setAttribute(String var1, Object var2);     //在ServletContext中有一处公共空间,getAttribute方法就是将一些数据存放在这一处公共空间。
Object getAttribute(String var1);              //获得在公共空间内存储的数据
void removeAttribute(String var1);             //移除在公共空间内存储的数据
String getRealPath(String path)                //获取当前 Web 应用中指定文件或目录在本地文件系统中的路径。
String getContextPath()                        //获取当前应用在 Web 容器中的名称。
ServletContext实现多个Servlet数据共享:

Servlet01:

public class Servlet01 extends HttpServlet {
    public Servlet01() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = "Lacer";
        context.setAttribute("username",username);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

Servlet02:

public class Servlet02 extends HttpServlet {
    public Servlet02() {
        super();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String)context.getAttribute("username");

        resp.getWriter().print("username:"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

当先通过Servlet01在ServletContext中设置数据后,在通过Servlet02就可以访问到Servlet01在SerlvetContext中设置的数据。

ServletContext获得初始化参数:
  • 设置初始化参数:
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306</param-value>
  </context-param>
  • 获取初始化参数:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print("url:"+url);
    }
  • 运行效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8dfC360-1623979392081)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20210617222038026.png)]

ServletContext转发功能:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext(); context.getRequestDispatcher("/Servlet03").forward(req,resp);
}
ServletContext读取资源:
  • 建立db.properties
username="Lacer"
password="123456"
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop = new Properties();
        prop.load(is);
        String user = prop.getProperty("username");
        String pwd = prop.getProperty("password");

        resp.getWriter().print(user+":"+pwd);
    }

GenericServlet抽象类:

  • GenericServlet抽象类实现了Servlet和ServletConfig接口
  • 调用Servlet接口实现方法,如果不是抽象类,则需要重写所有的方法,有些不需要使用的方法,也需要重写,而且还需要手动维护ServletConfig接口。
GenericServlet实现了Servlet方法:
  • 实现了String getServletInfo()方法
  • 实现了void destory()方法,空实现
  • 实现了void init(ServletConfig)方法,用来保存ServletConfig参数,this.config = config;
  • 实现了ServletConfig getServletConfig()方法
GenericServlet实现了ServletConfig接口:
  • 实现了ServletContext getServletContext()方法
  • 实现了String getInitParameter()方法
  • 实现了String getServletName()方法
  • 实现了Enumeration getInitParameterNames()方法
GenericServlet两个Init方法:

该方法会被init(ServletConfig)方法调用
如果希望对Servlet进行初始化,那么应该覆盖init()方法,而不是init(ServletConfig)方法

HttpServlet抽象类:

HttpServlet抽象类,是GenericServlet的子类, 它的功能要比GenericServlet要强大,使用HttpServlet类中的Service方法时,还需要使用HttpServletRequest和HttpServletResponse两个接口

service方法:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;
    this.service(request, response);} 
    else {
        throw new ServletException("non-HTTP request or response");
        }
    }
}

  • service方法首先将ServletRequest 和 ServletResponse 转化为HttpServletRequest和HttpServletResponse
  • 然后将他们传入类中的另一个service方法:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

该类实现了Http请求的七种方式,七种最重要的就是doGet和doPost,对应着Get请求和Post请求


版权声明:本文为mr_yuyou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。