Servlet

1.servlet

就Servlet是一个普通的JAVA类,但是能够处理http的请求与响应过程。

1 Servlet的基本架构 

 Servlet的自身就是一个接口,同时还有一个ServletConfig的接口。分别处理的不同事务。

  • Servlet接口
//
// Source code recreated from a.class file by IntelliJ IDEA
// (powered by FernFlowerdecompiler)
//

package javax.servlet;

import java.io.IOException;

public interface Servlet {

    //当前的对象初始化 ***

    void init(ServletConfig var1)throws ServletException;

    //获取到ServletConfig实例对象
    ServletConfig getServletConfig();

    //服务的提供方法 *****
    void service(ServletRequestvar1, ServletResponse var2) throws ServletException, IOException;

    //获取到Servlet信息
    String getServletInfo();

    //销毁服务 ***
    void destroy();
}
  • ServletConfig接口

        该接口主要的功能就是实现配置加载 

//
// Source code recreated from a.class file by IntelliJ IDEA
// (powered by FernFlowerdecompiler)
//
package javax.servlet;

import java.util.Enumeration;

public interface ServletConfig {

    //获取到Servlet的名字
    String getServletName();

    //获取到Servlet的上下文
    ServletContext getServletContext();

    //获取到Servlet配置中的初始化参数
    String getInitParameter(String var1);

    //获取到Servlet配置中的所有的初始化参数
    Enumeration<String> getInitParameterNames();
}
  • GenericServlet

        该类虽然实现了Servlet接口,但是更多的是对ServletConfig接口进行了实现,而把对应的Http请求方法Service,扔给了其子类HttpServlet。 

//
// Source code recreated from a.class file by IntelliJ IDEA
// (powered by FernFlowerdecompiler)
//
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.se 
rvlet.LocalStrings");
    private transientServletConfig config;

    public GenericServlet() {}

    public void destroy() {}
    public String getInitParameter(String name) {
    ServletConfig sc =this.getServletConfig();
    if (sc == null) {
        throw new IllegalStateException(lStrings.getString("err.servlet_config_not_ini
tialized"));
        } else {

     return sc.getInitParameter(name);
        }
    }
    public Enumeration<String> getInitParameterNames() {
    ServletConfig sc =this.getServletConfig();
        if (sc == null) {
        throw new IllegalStateException(lStrings.getString("err.servlet_config_not_ini
tialized"));
        } else {
            return sc.getInitParameterNames();
        }
    }
    public ServletConfig getServletConfig() {
        return this.config;
    }
    public ServletContext getServletContext() {
    ServletConfig sc = this.getServletConfig();
        if (sc == null) {

         throw new IllegalStateException(lStrings.getString("err.servlet_config_not_ini
tialized"));
        } else {
        return sc.getServletContext();
        }
    }
    public String getServletInfo(){
        return "";
    }
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    public void init() throws ServletException {}

    public void log(String msg) {
        this.getServletContext().log(this.getServletName() + ": " + msg);
    }
    public void log(String message, Throwable t) {
    this.getServletContext().log(this.getServletName() + ": " +message, t);
    }
    //由子类实现对应请求服务响应
    public abstract void service(ServletRequest var1,ServletResponse var2) throws
ServletException, IOException;
    public String getServletName(){
        ServletConfig sc = this.getServletConfig();
        if (sc == null) {
        throw new IllegalStateException(lStrings.getString("err.servlet_config_not_ini
tialized"));
        } else {
    return sc.getServletName();
}
}
}
  • HttpServlet

         该类主要就是完成用户的请求和响应。自定义的Servlet必须继承该类!

    protected void service(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {

        //获取到请求方式
        String method = req.getMethod();
        long lastModified;

        //根据不同的请求方式调用不同doXXX()方法
        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);
}
}
  •  自定义Servlet

      声明一个类,继承自HttpServlet 

package com.csi.eshop.controller;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 步骤1:需要继承自HttpServlet
*
* 思考:自定义Servlet是一个单例的还是多例的?(面试题)
* Servlet是一个单例设计,同时能够支持多线程并发访问,所以可能会造成线程安全性问题。
*/
public class TestController extends HttpServlet {
    //对象的创建
    public TestController(){

        System.out.println("当前的Servlet对象被创建了...");
    }
    //对象初始化
    @Override
    public void init()throws ServletException {
        System.out.println("当前的Servlet被初始化了...");
    }
    //提供服务
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws
ServletException,IOException {
        System.out.println("hello...");
        System.out.println(this);
    }
    //销毁

    @Override
    public void destroy() {
        System.out.println("我即将消失,不要对我留恋...");
        System.out.println("我即将消失,不要对我留恋...");
        System.out.println("我即将消失,不要对我留恋...");
}
}
  •  配置部署Servlet

         在web.xml中,配置Servlet的信息

<!--步骤1:先配置Servlet的位置-->

<servlet>
<!--定义Servlet的名字,供将来请求时能够找到该Servlet-->
    <servlet-name>TestController</servlet-name>
    <servlet-class>com.csi.eshop.controller.TestController</servlet-class>
<!--可以不写
    <init-param>
    <param-name>username</param-name>
    <param-value>zhangsan</param-value>
    </init-param>
    <init-param>
    <param-name>age</param-name>
    <param-value>20</param-value>
    </init-param>-->
</servlet>
    <!--步骤2:配置什么样的请求要找到哪一个对应Servlet-->
<servlet-mapping>
    <servlet-name>TestController</servlet-name>
    <url-pattern>/TestController</url-pattern>
</servlet-mapping>

         Servlet运行步骤:

                1. 先去URL中找到对应的请求(url-partten)
                2. 找到请求所对应的Servlet的名字(servlet-name)
                以上两个部分都是在servlet-mapping中.
                3. 根据名字找到Servlet配置节点中的Servlet的名字(servlet-name)
                4. 再确定Servlet的class所在位置(servlet-class) 

 1.Servlet生命周期

 

  •  实例化Servlet

         首先由客户端发起请求,容器会解析请求的URL,找到对应Servlet配置中的"url-partten",紧跟着继续查找对应“servlet-name”,找到了“servlet-name”就会使用"servlet-class"实现类实例化。

  •  调用init方法实现Servlet初始化

         当容器执行自定义Servlet时,会自动调用init方法,实现Servlet的初始化。

         Servlet是一个单例设计的类,能够提高多线程的访问能力。因此可能会存在线程安全性问题。

  •  调用init方法实现Servlet初始化

        当容器执行自定义Servlet时,会自动调用init方法,实现Servlet的初始化。 

         Servlet是一个单例设计的类,能够提高多线程的访问能力。因此可能会存在线程安全性问题。

  •  调用Service方法提供服务

         在HttpServlet中的Service方法,会根据用户提交的方式,选择调用doXXX方法,如果我们自己重写了Service方法,而没有调用doXXX具体的方法,可能在请求后,如果同时存在service以及对应doXXX方法时,只会调用service这一个方法。

  •  调用destory方法实现销毁

        当web容器销毁时,会调用每一个自定义Servlet中的destory实现对Servlet的销毁功能。 

3. 在Servlet中获取request、session、application内置对象的方式

//获取request,在调用doXX方法和service方法时,会存在两个对应对象,其中一个就是request
doXXX(HttpServletRequest request,HttpServletResponse response)
service(HttpServletRequest request,HttpServletResponse repsonse)

//获取Session
HttpSession session = request.getSession() ;

//获取Application
ServletContext application = request.getServletContext() ;

4.request的一些其他方法

  •  getContextPath(): 获取到当前项目的上下文路径
  • getMethod():获取到请求的方式
  • getHeader(String str):获取到请求的头信息的内容

 5.response的一些其他方法

  •  getWriter() :获取到PrintWriter对象,在内置对象中,代表out对象。
PrintWriter out = response.getWriter() ;

out.println() ;
  •  setContentType(String txt):设置当前页面响应的内容形式。

 

response.setContentType("application/json;charset=utf-8") ;

response.setContentType("img/jpeg")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值