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"后:

 
        index   《----- 根据servlet name  第三步
        test.index  
         《----- 查到test.index servlet类  第四步
    
    
        index   《----- 得到servlet name  第二步
        /index    《----- 遍历url   第一步
    

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 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 ");
    }
    
    -----
     
        index  //getServletName()
        test.index
           //增加一项
            key  
            hello world  //getInitParameter("key")
        
        1
        //表示初始化在容器启动时,0代表为第一次请求时
    
    
    -----
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 params=getServletConfig().getInitParameterNames();
       while (params.hasMoreElements()){
           System.out.println(params.nextElement());
        }
        resp.getWriter().print("welcome ");
---
//增加一行参数:
...
 
            name
            mylife
  
  ...
----
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项目的初始化参数
  
        feat
        plapla
    

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

    String getInitParameter(String var1);
    Enumeration 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信息:


java servlet_第1张图片
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;


java servlet_第2张图片
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。形象描述为:


java servlet_第3张图片
image

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

    Object getAttribute(String var1);
 Enumeration getAttributeNames();

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

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

   
        60  //设置存在时间为60分钟
    

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)