java servlet

作者: 谁吃了我的薯条 | 来源:发表于2017-11-08 15:00 被阅读0次

    Servlet编程需要使用到javax.servletjavax.servlet.http两个包下面的类和接口,在所有的类和接口中,javax.servlet.servlet接口最为重要。所有的servlet程序都必须实现该接口或者继承实现了该接口的类。

    javax.servlet.ServletConfig;
    javax.servlet.ServletException;
    javax.servlet.http.HttpServlet;
    javax.servlet.http.HttpServletRequest;
    javax.servlet.http.HttpServletResponse;
    javax.servlet.http.HttpSession;
    javax.servlet.http.Cookie;
    javax.servlet.ServletContext;
    javax.servlet.GenericServlet;
    

    以上是Servlet的主要类和接口

    Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。对这句话再做点解释,比如HttpServlet类继承自Servlet类,可以利用继承HttpServlet来实现Http请求,当不是Http请求的时候,也可以定义其他形式的Servlet。

    servlet 部署到Tomcatweb容器中,浏览器发送一个Http请求(或者别的请求)后,web容器会自动分配这些请求到特定的servlet类实例(若没有,通过反射由web容器进行创建一个)。servlet其实是一个java对象,它其中包含了一系列处理Http请求的方法。web容器内包含多个servlet,访问哪一个由web容器中配置文件web.xml来决定;

    [图片上传中...(image.png-14d6ab-1510124505627-0)]

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

    1、浏览器发送出Http请求;
    2、web容器解析请求,将其向下转型为HttpServlet请求;
    3、web容器建立对应的servlet实例;
    4、调用init()方法对servlet实例进行初始化(只执行一次);
    5、调用service()方法,其包根据其请求类型调用doget(),dopost()方法(需要根据请求进行复写);
    6、然后输出response响应,通过容器发送;
    7、服务器关闭或者web容器关闭,会调用dstory()方法;

      public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request = (HttpServletRequest)req;
                response = (HttpServletResponse)res;
            } catch (ClassCastException var6) {
                throw new ServletException("non-HTTP request or response");
            }
    
            this.service(request, response);
        }
    
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    ...
    } 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);
    ...
    //其实是做了一系列的比较,跳转至对象请求处理方法。
    
    public abstract class GenericServlet implements Servlet, ServletConfig, Serializable{...
     private transient ServletConfig config;
    public void init(ServletConfig config) throws ServletException {
            this.config = config;
            this.init();
        }
    
        public void init() throws ServletException {
        }
        
         public ServletConfig getServletConfig() {
            return this.config;
        }
         public ServletContext getServletContext() {
            return this.getServletConfig().getServletContext();
        }
        ...}
    

    读取配置,当浏览器输入"/index"后:

     <servlet>
            <servlet-name>index</servlet-name>   《----- 根据servlet name  第三步
            <servlet-class>test.index</servlet-class>  
             《----- 查到test.index servlet类  第四步
        </servlet>
        <servlet-mapping>
            <servlet-name>index</servlet-name>   《----- 得到servlet name  第二步
            <url-pattern>/index</url-pattern>    《----- 遍历url   第一步
        </servlet-mapping>
    
    
    package test;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class index extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doget ...");
            System.out.println(getServletConfig().getInitParameter("key"));
            resp.getWriter().print("welcome ");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("dopost ....");
        }
    
        @Override
        public void destroy() {
            System.out.println("destory 。。。");
        }
    
        @Override
        public void init() throws ServletException {
            System.out.println("init start...");
        }
    }
    
    ----
    init start...
    doget ...
    doget ...
    
    
    
    

    结果:
    [图片上传失败...(image-a08a62-1510124430937)]
    当配置该servlet
    web.xml中配置load-on-startup=1,代表容器启动时就会初始化该对象,而不是第一次请求时;

    下面是load-on-startup=1的运行结果

    init start...
    [2017-11-08 11:32:37,825] Artifact untitled:war exploded: Artifact is deployed successfully
    [2017-11-08 11:32:37,825] Artifact untitled:war exploded: Deploy took 446 milliseconds
    doget ...
    doget ...
    
    

    而destory()方法是在服务器关闭或者重启的情况下,开始执行

    十一月 08, 2017 11:37:28 上午 org.apache.catalina.core.StandardService stopInternal
    信息: Stopping service Catalina
    destory 。。。
    

    下面看一下,servlet的几个重要对象:

    1、javax.servlet.ServletConfig;
    通过调用 GenericServlet中的 getServletConfig()得到

    它为一个接口,包含四个方法:

    import java.util.Enumeration;
    
    public interface ServletConfig {
        String getServletName();
    
        ServletContext getServletContext();
    
        String getInitParameter(String var1);
    
        Enumeration<String> getInitParameterNames();
    }
    

    1.1、getServletName():
    我们修改doget方法和web.xml文件:

      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doget ...");
            // System.out.println(getServletConfig().getInitParameter("key"));
            System.out.println("servlet的名字为:"+getServletConfig().getServletName());
            //获取servlet的名称,也就是我们在web.xml中配置的servlet-name
            resp.getWriter().print("welcome ");
        }
        
        -----
         <servlet>
            <servlet-name>index</servlet-name>  //getServletName()
            <servlet-class>test.index</servlet-class>
            <init-param>   //增加一项
                <param-name>key</param-name>  
                <param-value>hello world</param-value>  //getInitParameter("key")
            </init-param>
            <load-on-startup>1</load-on-startup>
            //表示初始化在容器启动时,0代表为第一次请求时
        </servlet>
        
        -----
    doget ...
    servlet的名字为:index
    doget ...
    servlet的名字为:index
    

    从上面结果可以看出,获取的是当前servlet对象的名字;

    1.2、getInitParameter(String var1)
    其实可以从名字上看出,其得到的事初始化参数,下面进行验证:
    在doget()方法中增加一项:

    System.out.println("servlet的初始化参数为:"+getServletConfig().getInitParameter("key"));
    -------
    doget ...
    servlet的初始化参数为:hello world
    servlet的名字为:index
    

    bingo~

    1、3 getInitParameterNames()
    返回的是一个枚举类型的参数名称集;

     Enumeration<String> params=getServletConfig().getInitParameterNames();
           while (params.hasMoreElements()){
               System.out.println(params.nextElement());
            }
            resp.getWriter().print("welcome ");
    ---
    //增加一行参数:
    ...
     <init-param>
                <param-name>name</param-name>
                <param-value>mylife</param-value>
      </init-param>
      ...
    ----
    doget ...
    name
    key
    

    1、4 getServletContext()

    得到ServletContext接口对象;不过一般不使用此方法,一般采用GenericServletpublic ServletContext getServletContext()方法,来获取servletContext对象;

    2、javax.servlet.ServletContext;

    tomcat为每个web项目都创建一个ServletContext实例,tomcat在启动时创建,服务器关闭时销毁,在一个web项目中共享数据,管理web项目资源,为整个web配置公共信息等,通俗点讲,就是一个web项目,就存在一个ServletContext实例,每个Servlet读可以访问到它。

    为web.xml增加一项配置:

    //相当于全局(整个web项目)变量,配置整个web项目的初始化参数
    <context-param>  
            <param-name>feat</param-name>
            <param-value>plapla</param-value>
        </context-param>
    

    提供下面方法,来获取它,使用方法与上面相同,不在重复:

        String getInitParameter(String var1);
        Enumeration<String> getInitParameterNames();
    

    它还有几个重要的方法,用于页面之间的传参:

        setAttribute(String var1, Object var2);
        //在web项目范围内存放内容,以便让在web项目中所有;
        removeAttribute(String var1);
        //通过指定名称获得内容
        getAttribute(String name)
        // 通过指定名称移除内容
    

    看一个例子:
    新建两个类,fuck 和 test

    
    ------
       @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("test.doget start...");
            System.out.println(getServletContext().getAttribute("content"));
    
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("fuck.doget start...");
            System.out.println(getServletContext().getAttribute("content"));
    
        }
    
    //运行结果...
    doget ...
    test.init() start...
    test.doget start...
    helloworld
    fuck.init() start...
    fuck.doget start...
    helloworld
    

    用于回去资源路径的方法:

      String getRealPath(String var1);
    

    使用方法,也很简单:

      System.out.println("该项目位于:"+getServletContext().getRealPath("/"));
      ----
      doget ...
      该项目位于:D:\IdeaProjects\study\out\artifacts\untitled_war_exploded\
    

    3、javax.servlet.http.HttpServletRequest;

    request信息:


    request
    
    Accept:image/webp,image/apng,image/*,*/*;q=0.8
    Accept-Encoding:gzip, deflate, br
    Accept-Language:zh-CN,zh;q=0.8
    Connection:keep-alive
    Cookie:BAIDUID=FFB31BBED298FFFA711C8E2FE416214E:FG=1; BIDUPSID=FFB31BBED298FFFA711C8E2FE416214E; PSTM=1499983389; __cfduid=d49ab908a5a4d3ca5789b9de975db3feb1505744478; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; PSINO=2; H_PS_PSSID=1448_22534_21097_17001_24880_20928
    Host:sp0.baidu.com   
    Referer:https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=servletconfig&oq=servletconfig&rsv_pq=b995eb8400028783&rsv_t=6cc3Xb6Dn%2BSyOjvExboNaM4ieI%2FD5bm00jWcd9klEP2y2TWdMxUIVgfWOL0&rqlang=cn&rsv_enter=0
    
    

    常用的方法:

    HttpSession getSession();
    Cookie[] getCookies();
    
    //继承的方法
    void setAttribute(String var1, Object var2);  //页面之间进行传值
    void removeAttribute(String var1); 
    Object getAttribute(String var1);  
    String getParameter(String var1); //获取参数 
    String[] getParameterValues(String var1);//用于同一参数名的所有参数值获取
    String[] getParameterValues(String var1);
    /*转发,表示浏览器中url不会改变,也就是浏览器不知道服务器做了什么,是服务器帮我们跳转页面并且在转发后的页面,能够继续使用原先的request,因为是原先的request,所以request域中的属性都可以继续获取到。作用域见 jsp;
    */
    RequestDispatcher getRequestDispatcher(String var1);
    //获取 servletContext对象
    ServletContext getServletContext();
    
    
    System.out.println("获取统一资源标记符"+req.getRequestURI());//获取统一资源标记符
    System.out.println("获取统一资源定位符"+req.getRequestURL());//获取统一资源定位符
    System.out.println("域名"+req.getServerName());
    
    -----
    doget ...
    获取统一资源标记符/untitled/index
    获取统一资源定位符http://localhost:8070/untitled/index
    域名localhost
    

    4、javax.servlet.http.HttpServletResponse;


    response

    第一部分:状态行,由HTTP协议版本号, 状态码(200), 状态消息(OK) 三部分组成。
    第二部分:消息报头,用来说明客户端要使用的一些附加信息
    第二行和第三行为消息报头,
    Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
    第三部分:空行,消息报头后面的空行是必须的
    第四部分:响应正文,服务器返回给客户端的文本信息。空行后面的html部分为响应正文。
    响应状态码:
    1xx:指示信息--表示请求已接收,继续处理
    2xx:成功--表示请求已被成功接收、理解、接受
    3xx:重定向--要完成请求必须进行更进一步的操作
    4xx:客户端错误--请求有语法错误或请求无法实现
    5xx:服务器端错误--服务器未能实现合法的请求
    主要方法为:

    //重定向
    void sendRedirect(String var1) throws IOException;
    //手动重定向
    void setStatus(int var1, String var2);
    void setHeader(String var1, String var2);
    
    response.setStatus(302);  //状态码302就代表重定向
    response.setHeader("location","url....");
    
    /*
     重定向没有任何局限,可以重定向web项目内的任何路径,也可以访问别的web项目中的路径,并且这里就用"/"区分开来,如果使用了"/"开头,就说明我要重新开始定位了,不访问刚才的web项目,自己写项目名,如果没有使用"/"开始,那么就知道是访问刚才那个web项目下的servlet,就可以省略项目名了。就是这样来区别。
     */
    

    5、javax.servlet.http.HttpSession;

    Session是服务器端技术,利用这个技术,服务器在运行时,为每一个用户创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

    当用户打开浏览器,访问某个网站操作session时,服务器就会在服务器的内存为该浏览器分配一个session对象,该session对象被这个浏览器独占。
    session可以作为一个容器,存储一些对象,他有默认的存在时间一般为30min。形象描述为:


    image

    它主要用于一下几个方面:
    1、禁止访问某些界面(比如说未登陆时);
    2、网上商城中的购物车
    3、保存登录用户的信息
    4、将某些数据放入到Session中,供同一用户的各个页面使用
    它的主要方法有:

        Object getAttribute(String var1);
     Enumeration<String> getAttributeNames();
    
        /** @deprecated */
        String[] getValueNames();
        void setAttribute(String var1, Object var2); //在session中存储或更新元素
        void removeAttribute(String var1); //删除某个存储对象
    

    可以通过web.xml设置其存在时间:注意该时间为发呆时间,即从最后一次使用开始计时;
    若将其存在时间设为-1,代表其永不过期,但是服务器重启后还是会失效;

       <session-config>
            <session-timeout>60</session-timeout>  //设置存在时间为60分钟
        </session-config>
    

    6、javax.servlet.http.Cookie;

    cookie机制则是在客户端保持状态的方案,cookie又叫会话跟踪机制;
    cookie:
    1.cookie是在服务端创建的
    2.cookie是保存在浏览器这端的
    3.cookie的生命周期可以通过cookie.setMaxAge();如果不设置,关闭浏览器就destroy了

    CookiemaxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。
    如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。

    Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie
    cookie.setMaxAge(Integer.MAX_VALUE);           // 设置生命周期为MAX_VALUE
    response.addCookie(cookie);                    // 输出到客户端
    

    如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。Cookie默认的maxAge值为–1。
    如果maxAge为0,则表示删除该CookieCookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,

    相关文章

      网友评论

        本文标题:java servlet

        本文链接:https://www.haomeiwen.com/subject/fsfymxtx.html