Servlet基础知识点*(初学者)

  1. Servlet 的基本架构
  2. Serclet 的生命周期
  3. Servlet 是一个单列(单列和多列的分别是因为?),是一个多线程 ,存在线程安全性问题
  4. Servlet 中获取request、session、application 内置对象的方式
  5. request 的一些其他方法
  6. response 的一些 方法

1.Servlet 自身是一个接口,处理不用的服务,还有一个ServletConfig 接口

ServletConfig接口的功能就是实现配置加载。

 如:Servle的源码 和ServletConfig的源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.servlet;

import java.util.Enumeration;

public interface ServletConfig {
    String getServletName();

    ServletContext getServletContext();

    String getInitParameter(String var1);

    Enumeration<String> getInitParameterNames();
}

Servlet接口

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.servlet;

import java.io.IOException;

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}
GenericServlet 类 实现了Servlet接口,但更多是对ServletConfig接口进行了实现,把对应的HTTP请求方法Service 扔给了子类HttpServlet ;
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

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 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_initialized"));
        } 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_initialized"));
        } 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_initialized"));
        } 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_initialized"));
        } else {
            return sc.getServletName();
        }
    }
}

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

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package javax.servlet.http;

import java.io.IOException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public abstract class HttpServlet extends GenericServlet {
    private static final String METHOD_DELETE = "DELETE";
    private static final String METHOD_HEAD = "HEAD";
    private static final String METHOD_GET = "GET";
    private static final String METHOD_OPTIONS = "OPTIONS";
    private static final String METHOD_POST = "POST";
    private static final String METHOD_PUT = "PUT";
    private static final String METHOD_TRACE = "TRACE";
    private static final String HEADER_IFMODSINCE = "If-Modified-Since";
    private static final String HEADER_LASTMOD = "Last-Modified";
    private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
    private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");

    public HttpServlet() {
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

    protected long getLastModified(HttpServletRequest req) {
        return -1L;
    }

    protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        NoBodyResponse response = new NoBodyResponse(resp);
        this.doGet(req, response);
        response.setContentLength();
    }

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_put_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_delete_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(405, msg);
        } else {
            resp.sendError(400, msg);
        }

    }

    private Method[] getAllDeclaredMethods(Class<? extends HttpServlet> c) {
        Class<?> clazz = c;

        Method[] allMethods;
        for(allMethods = null; !clazz.equals(HttpServlet.class); clazz = clazz.getSuperclass()) {
            Method[] thisMethods = clazz.getDeclaredMethods();
            if (allMethods != null && allMethods.length > 0) {
                Method[] subClassMethods = allMethods;
                allMethods = new Method[thisMethods.length + allMethods.length];
                System.arraycopy(thisMethods, 0, allMethods, 0, thisMethods.length);
                System.arraycopy(subClassMethods, 0, allMethods, thisMethods.length, subClassMethods.length);
            } else {
                allMethods = thisMethods;
            }
        }

        return allMethods != null ? allMethods : new Method[0];
    }

    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Method[] methods = this.getAllDeclaredMethods(this.getClass());
        boolean ALLOW_GET = false;
        boolean ALLOW_HEAD = false;
        boolean ALLOW_POST = false;
        boolean ALLOW_PUT = false;
        boolean ALLOW_DELETE = false;
        boolean ALLOW_TRACE = true;
        boolean ALLOW_OPTIONS = true;

        for(int i = 0; i < methods.length; ++i) {
            String methodName = methods[i].getName();
            if (methodName.equals("doGet")) {
                ALLOW_GET = true;
                ALLOW_HEAD = true;
            } else if (methodName.equals("doPost")) {
                ALLOW_POST = true;
            } else if (methodName.equals("doPut")) {
                ALLOW_PUT = true;
            } else if (methodName.equals("doDelete")) {
                ALLOW_DELETE = true;
            }
        }

        StringBuilder allow = new StringBuilder();
        if (ALLOW_GET) {
            allow.append("GET");
        }

        if (ALLOW_HEAD) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("HEAD");
        }

        if (ALLOW_POST) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("POST");
        }

        if (ALLOW_PUT) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("PUT");
        }

        if (ALLOW_DELETE) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("DELETE");
        }

        if (ALLOW_TRACE) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("TRACE");
        }

        if (ALLOW_OPTIONS) {
            if (allow.length() > 0) {
                allow.append(", ");
            }

            allow.append("OPTIONS");
        }

        resp.setHeader("Allow", allow.toString());
    }

    protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String CRLF = "\r\n";
        StringBuilder buffer = (new StringBuilder("TRACE ")).append(req.getRequestURI()).append(" ").append(req.getProtocol());
        Enumeration reqHeaderEnum = req.getHeaderNames();

        while(reqHeaderEnum.hasMoreElements()) {
            String headerName = (String)reqHeaderEnum.nextElement();
            buffer.append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName));
        }

        buffer.append(CRLF);
        int responseLength = buffer.length();
        resp.setContentType("message/http");
        resp.setContentLength(responseLength);
        ServletOutputStream out = resp.getOutputStream();
        out.print(buffer.toString());
    }


 
    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);
        }

    }

    private void maybeSetLastModified(HttpServletResponse resp, long lastModified) {
        if (!resp.containsHeader("Last-Modified")) {
            if (lastModified >= 0L) {
                resp.setDateHeader("Last-Modified", lastModified);
            }

        }
    }

    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");
        }
    }
}

自定义的Servlet类 继承HttpServlet

  1. 自定义的Servlet 是一个单例还是多例?(面试题)
  2. Servlet  是一个单例设计,同时能够支持多线程并发访问,所以可能会造成多线程安全性问题。
  3. xx

配置部署Servlet

在文本.xml 配置Servlet的信息

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--    步骤1.先设置serclet的位置-->

<!--    定义servlet的名字,提供将来请求时能够找到改servlet-->
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.csi.eshop.controller.TestServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>CodeServlet</servlet-name>
        <servlet-class>com.csi.eshop.utils.CodeServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>LoginController</servlet-name>
        <servlet-class>com.csi.eshop.controller.LoginController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>RegistController</servlet-name>
        <servlet-class>com.csi.eshop.controller.RegistController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>InvalidateController</servlet-name>
        <servlet-class>com.csi.eshop.controller.InvalidateController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>ProductInfoController</servlet-name>
        <servlet-class>com.csi.eshop.controller.ProductInfoController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>pageIndexController</servlet-name>
        <servlet-class>com.csi.eshop.controller.pageIndexController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>ListProductBrandController</servlet-name>
        <servlet-class>com.csi.eshop.controller.ListProductBrandController</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>FindProductController</servlet-name>
        <servlet-class>com.csi.eshop.controller.FindProductController</servlet-class>
    </servlet>



    <servlet>
        <servlet-name>FindProductIdController</servlet-name>
        <servlet-class>com.csi.eshop.controller.FindProductIdController</servlet-class>
    </servlet>



    <servlet-mapping>
        <servlet-name>FindProductIdController</servlet-name>
        <url-pattern>/FindProductIdController</url-pattern>
    </servlet-mapping>





    <servlet-mapping>
        <servlet-name>FindProductController</servlet-name>
        <url-pattern>/FindProductController</url-pattern>
    </servlet-mapping>


    <servlet-mapping>
        <servlet-name>ListProductBrandController</servlet-name>
        <url-pattern>/ListProductBrandController</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>pageIndexController</servlet-name>
        <url-pattern>/pageIndexController</url-pattern>
    </servlet-mapping>


    <servlet-mapping>
        <servlet-name>ProductInfoController</servlet-name>
        <url-pattern>/ProductInfoController</url-pattern>
    </servlet-mapping>




    <servlet-mapping>
        <servlet-name>InvalidateController</servlet-name>
        <url-pattern>/InvalidateController</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>RegistController</servlet-name>
        <url-pattern>/RegistController</url-pattern>
    </servlet-mapping>




    <servlet-mapping>
        <servlet-name>LoginController</servlet-name>
        <url-pattern>/LoginController</url-pattern>
    </servlet-mapping>




    <servlet-mapping>
        <servlet-name>CodeServlet</servlet-name>
        <url-pattern>/CodeServlet</url-pattern>
    </servlet-mapping>

<!--    步骤2.配置什么样的请求 要找到哪一个对应的servlet-->
    <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/TestServlet</url-pattern>
    </servlet-mapping>

</web-app>

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

Servlet的生命周期

1.实例化 Servlet:
首先由客户端发起请求,容器会解析请求的
URL ,找到对应 Servlet 配置中的 "url-partten"
紧跟着继续查找对应 “servlet-name” ,找到了
“servlet-name” 就会使用 "servlet-class" 实现类实例化。
2.调用 init 方法实现 Servlet 初始化
当容器执行自定义 Servlet 时,会自动调用 init
法,实现 Servlet 的初始化
3. 调用 Service 方法提供服务
HttpServlet 中的 Service 方法,会根据用户提
交的方式,选择调用 doXXX 方法,如果我们自己
重写了 Service 方法,而没有调用 doXXX 具体的方
法,可能在请求后,如果同时存在 service 以及对
doXXX 方法时,只会调用 service 这一个方法。
4.调用 destory 方法实现销毁
web 容器销毁时,会调用每一个自定义 Servlet
中的 destory 实现对 Servlet 的销毁功能。

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


//获取Session
HttpSession sessiom = request.getSession 

//获取aalicaton
ServletContext application = request.getServletContext 
 request 的一些其他方法
getContextPath(): 获取到当前项目的上下文路径
getMethod(): 获取到请求的方式
getHeader(String str): 获取到请求的头信息的内容
response 的一些其他方法
getWriter() : 获取到 PrintWriter 对象,在内置对象中,代表 out 对象。
PrintWriter out = resp.getWriter();
out.println("n hao a ");
setContentType(String txt): 设置当前页面响应的 内容形式。
resp.setContentType("application/json;charaset=utf-8");
resp.setContentType("img/jpeg");

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值