java servlet

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文件或者内存中删除,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 简书 賈小強转载请注明原创出处,谢谢! Servlet是一种允许响应请求的Java类。虽然Servlet可以响应任...
    賈小強阅读 10,607评论 1 44
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,138评论 11 349
  • 一、基础知识学习Servlet技术,首先需要有一个Servlet运行环境,也就是需要有一个Servlet容器,本书...
    汪梓文阅读 245评论 0 2
  • 一 servlet概述 狭义的Servlet指javax.servlet包中的一个接口,而广义的Servlet则是...
    静慎独阅读 441评论 0 0
  • servlet容器加载顺序 当 Servlet 容器(比如 Apache Tomcat )启动后,会部署和加载所有...
    进击的诺基亚阅读 803评论 0 2