servlet

来源:互联网 发布:淘宝买周大福可靠吗 编辑:程序博客网 时间:2024/06/08 10:24

servlet概述(一)

1.servlet 产生背景

  servlet 技术的出现,是由于web的应用和发展,从刚开始的静态html页面,到实现动态交互的JavaScript页面,以上的实现都在浏览器端,如果某个浏览器不支持某种脚本语言,那么功能就不能实现,在此情况下,就提出web服务器动态生成html页面。servlet技术由此诞生。

2.servlet 规范

  servlet的诞生刚开始主要为了解决web服务器(特定厂商或者组织研发)和web应用程序(商业机构(java程序员开发))之间的访问问题。访问的标准由谁来顶呢?当然是当时比较牛逼的sun公司制定,sun公司制定出了统一的java 接口(统称位java servlet API)。sun公司把这一系列的java 标准接口 API 和规范统称为 ——servlet 规范。

3. servlet

  狭义的Servlet是指Java语言实现的一个接口(servlet 规范),广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

4.servlet 相关接口

这里写图片描述

4.1 ServletContext 接口

    ServletContext 是Servlet 与Servlet容器之间直接通信的接口。ServletContext的对象是application是在项目初始化时被创建的。故servletContext随着应用初始化而被创建,随着应用的结束而被销毁。

4.2 ServletConfig

    在应用初始化的时候,Web容器在创建Servlet对象时会自动将web.xml中的servlet配置这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。所以我们可以通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

4.3 servlet 接口

    servlet 初始化有两种情况:

    一、随应用初始化时初始化,即在web.xml中设置参数,参数为整数值并且大于0,而且值越少,优先级越高。在springmvc项目中经常会用到这个配置

    二、在应用运行中时,servlet被客户端请求时初始化。

    servlet销毁:

    servlet自身调用destroy()方法、servlet容器停止运行、项目停止运行都会销毁该servlet实例。

 ### 4.4 ServletRequest

    ServletRequest的对象是request,其生命周期为request域,一个请求结束,则request对象结束。

4.5 ServletResponse

    ServletResponse的对象是response,一次响应结束,则response对象结束。

4.6 HttpServlet和HttpServletRequest、HttpServletResponse

    他们之间的关系就好像Servlet和ServletRequest、ServletResponse之间的关系一样,只不过做了少部分封装而已。


Servlet生命周期

1.javaWeb生命周期

  javaWeb的生命周期包括三个阶段:启动阶段,运行阶段,终止阶段。

  1.1:启动阶段

    servlet在启动Web应用的时候,会完成如下步骤。

    (1)把web.xml文件加载到内存中。

    (2)为javaWeb应用创建一个ServletContex 对象。

    (3)对所有过滤器(Filter)初始化。

    (4)对那些在Web应用启动时就要初始化的Servlet进行初始化。(参考servlet生命周期)。

  1.2:运行阶段

    这个阶段是JavaWeb应用最主要的生命阶段。这个阶段中,相关初始化的Servlet都处于待命状态,随时响应客户端的请求。如果客户端请求的Servlet不存在,则初始化后调用其Service()方法提供服务。

  1.3:终止阶段

    终止阶段会完成如下步骤

    (1)销毁javaWeb应用所有处于运行状态的servlet。

    (2)销毁javaWeb应用所有的过滤器(Filter)。

    (3)销毁JavaWeb应用相关对象,如ServletContext 对象等。

2.Servlet生命周期

  servlet的生命周期由servlet容器控制。

  servlet生命周期分为三个阶段:初始化阶段,运行阶段,销毁阶段。

  2.1 初始化阶段

    servlet初始化条件

    (1)javaWeb应用在运行阶段,首次访问servlet,servlet都会被初始化。

    (2)如果在web.xml文件中为servlet设置了元素,那么servlet在javaWe应用启动的时候就会初始化。

    servlet初始化阶段包括如下四个步骤。

    (1)servlet容器加载servlet类的.class文件到内存中.

    (2)servlet容器创建ServletConfig对象。(ServletConfig 对象包含特定servlet的配置信息,如初始化参数。此外,servlet容器还会将创建的ServletConfig对象与ServletContext 对象关联)。

    (3)Servlet容器创建Servlet对象。

    (4)Servlet容器调用Servlet的init(ServletConfig servletConfig)方法。

  2.2运行阶段

    这是servlet生命周期中最重要的阶段。在这个阶段,servlet会随时响应客户端的请求。servlet容器接受到客户端的请求然后创建,servletRequest对象和servletResponse对象,然后调用对应servlet类的service方法,service()方法从serveletRequest方法中获取请求数据,处理完成后通过servletResponse对象返回结果。

  2.3销毁阶段

    当javaWeb应用被终止时,servlet容器会首先调用javaWeb应用中所有运行状态的servlet类的destroy()方法,然后在销毁这些servlet对象。
    


servlet监听器

1.什么是servlet监听器?

  servlet监听器也叫web监听器。是servlet中一种特殊类。能够帮助开发者监听web应用中的特定事件。比如ServletContext,ServletSession,ServletRequest的创建和销毁,变量的创建和销毁等。

2 监听器常用的用途

  通常使用Web监听器做以下的内容:

  统计在线人数,利用HttpSessionLisener

  加载初始化信息:利用ServletContextListener

  统计网站访问量

  实现访问监控

3.监听器的分类

  根据servlet对象可以将监听器划分为三种:ServletContext,ServletSession,ServletRequest。

4监听器的应用

  ##4.1 ServletContex :对应监控application内置对象的创建和销毁。

  当web容器开启时,执行contextInitialized方法;当容器关闭或重启时,执行contextDestroyed方法。

package com.learn;import javax.servlet.ServletContext;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import java.io.*;/** * Created by Administrator on 2017/09/23. */public class MyServletContextListener implements ServletContextListener {    @Override    public void contextInitialized(ServletContextEvent sce) {        System.out.println("Webapp initital.......");        ServletContext servletContext = sce.getServletContext();       InputStreamReader inputStreamReader = new InputStreamReader(servletContext.getResourceAsStream("/count/count.txt"));        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);        try {            int icount = Integer.parseInt(bufferedReader.readLine());            icount++;            servletContext.setAttribute("count",icount);            System.out.println("Webapp initital success");        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void contextDestroyed(ServletContextEvent sce) {        System.out.println("webApp destroyed ........");        ServletContext servletContext = sce.getServletContext();        Integer count = (Integer) servletContext.getAttribute("count");        if(count != null){            count ++;            String filePath = servletContext.getRealPath("/count");            filePath = filePath+"/count.txt";            try {                PrintWriter printWriter = new PrintWriter(filePath);                printWriter.write(count);                printWriter.close();                System.out.println("webApp desdroyed success ");            } catch (FileNotFoundException e) {                e.printStackTrace();            }        }    }}

  4.2HttpSession监控:对应监控session内置对象的创建和销毁。

  当打开一个新的页面时,开启一个session会话,执行sessionCreated方法;当页面关闭session过期时,或者容器关闭销毁时,执行sessionDestroyed方法。

  实现方式:直接实现HttpSessionListener接口:
  

package com.learn;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;/** * Created by Administrator on 2017/09/23. */public class MySessionListener implements HttpSessionListener{    @Override    public void sessionCreated(HttpSessionEvent se) {        HttpSession session = se.getSession();        System.out.println("新建session,sessionId:"+session.getId());    }    @Override    public void sessionDestroyed(HttpSessionEvent se) {        HttpSession session = se.getSession();        System.out.println("销毁session,sessionId:"+session.getId());    }}

 4.3ServletRequest监控:对应监控request内置对象的创建和销毁。

  当访问某个页面时,出发一个request请求,执行requestInitialized方法;当页面关闭时,执行requestDestroyed方法。

  实现方式,直接实现ServletRequestListener接口:

package com.learn;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpServletRequest;/** * Created by Administrator on 2017/09/23. */public class MyRequestListener implements ServletRequestListener {    @Override    public void requestDestroyed(ServletRequestEvent sre) {        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();        Long date =   System.currentTimeMillis()-(Long) (request.getAttribute("dateCreated"));        System.out.println("消耗时间:"+date);    }    @Override    public void requestInitialized(ServletRequestEvent sre) {        HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();        String uri = request.getRequestURI();        uri = request.getQueryString() == null ? uri : (uri + "?" + request.getQueryString());        request.setAttribute("dateCreated", System.currentTimeMillis());        System.out.println("IP:"+request.getRemoteAddr()+"URI:"+uri);    }}

 5监听器web.xml的配置

<listener>     <listener-class>com.learn.MyServletContextListener</listener-class>    </listener>    <listener>        <listener-class>com.learn.MySessionListener</listener-class>    </listener>    <listener>        <listener-class>com.learn.MyRequestListener</listener-class>    </listener>

servlelt上传文件

1.servlet上传文件

  servlet上传文件就是将客户端的文件上传到服务器端。

  向服务器发送数据时,客户端发送的http请求正文采用“multipart/form-data”数据类型,他表示复杂的多个子部分的复合表单。

  为了简化“multipart/form-data”数据的处理过程。可以使用Apache组织提供是的两个开源包来来实现上传。

    fileupload软件包(commons-fileupload-1.2.1.jar),负责文件上传的软件包。

    io软件包(commons-io-1.4.jar)负责输入输出的软件包。

2.servlet上传文件相关类

  2.1fileupload软件包把请求正文包含的复合表单的每个子部分看做FileItem对象。FileItem对象分为两种类型。

    (1)formFiled:普通表单域类型,如表单中的文本和按钮等。

    (2)非formFiled:上传文件类型,表单中的文件域就是这种类型。

  2.2FileItemFactory接口和FileItem接口

     FileItemFactory 是创建FileItem 对象的工厂。

     DiskFileItemFactory 实现了FileItemFactory接口,DiskFileItemFactory用于创建DiskFileItem对象。

     DiskFileItem对象用于把客户端上传的文件保存在客户端。

  2.3ServletFileUpload 类

    ServletFileUpload为文件上传处理器。和DiskFileItemFactory对象关联。

3.上传文件案例

  上传文件页面(upload.html)
  

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><form action="upload" enctype="multipart/form-data" method="POST">    <input name="username" size="30">    <input type="file" name="file1" size="30">    <input type="file" name="file2" size="30">    <input type="submit" name="submit" value="upload"></form></body></html>

上传文件的servlet类

package com.learn;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.poi.common.usermodel.LineStyle;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import java.util.Iterator;import java.util.List;public class ServletUpload extends HttpServlet {    private String  filePath;    private String  tempFilePath;    @Override    public void init(ServletConfig config) throws ServletException {        super.init(config);        //获取类文件路径初始化值        filePath = config.getInitParameter("filePath");        tempFilePath = config.getInitParameter("tempFilePath");        System.out.println("init filepath:"+filePath);        System.out.println("tempFilePath:"+tempFilePath);        //获取文件路径真实值        filePath = config.getServletContext().getRealPath(filePath);        tempFilePath = config.getServletContext().getRealPath(tempFilePath);        System.out.println("realPath:"+filePath);        System.out.println("tempFilePath"+tempFilePath);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        super.doPost(req, resp);        //设置返回内容为纯文字内容        resp.setContentType("text/plain");        resp.setCharacterEncoding("UTF-8");        //获取输出对象        PrintWriter out =  resp.getWriter();        //创建一个基于硬盘的FileItem工厂        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();        //设置向硬盘写数据的缓冲区大小,这里为4k        diskFileItemFactory.setSizeThreshold(4*1024);        //设置临时目录        diskFileItemFactory.setRepository(new File(tempFilePath));        //创建一个文件上传处理器        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);        //设置文件上传的大小        servletFileUpload.setSizeMax(4*1024*1024);        //获取参数        try {            //获取表单参数           List list =  servletFileUpload.parseRequest(req);           //获取迭代器           Iterator iterator = list.iterator();           //迭代列表            while(iterator.hasNext()){                //将参数转型为FileItem类型                FileItem fileItem = (FileItem) iterator.next();                if(fileItem.isFormField()){                    System.out.println("处理表单非文件类型数据");                    processFormFiled(fileItem,out);                } else {                    System.out.println("处理吧表单文件类型数据");                    processUploadFile( fileItem,out);                }            }            System.out.println("关闭输出流");            out.close();        } catch (FileUploadException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }    }    private  void processFormFiled(FileItem fileItem,PrintWriter printWriter){        //获取表单域的名称        String name = fileItem.getName();        //获取表单域的值        String value = fileItem.getString();        printWriter.print("name:"+name+"value:"+value);    }    private  void processUploadFile(FileItem fileItem,PrintWriter printWriter) throws Exception {       //获取文件名称        String fileName = fileItem.getName();        int i = fileName.lastIndexOf("\\");        fileName = fileName.substring(i+1,fileName.length());        //获取文件大小        long fileSize = fileItem.getSize();        System.out.println("fileName:"+fileName+"| fileSize:"+fileSize);        if("".equals(fileName) && fileSize == 0)            return;        //将文件写入指定位置        File upload = new File(filePath+File.separator+fileName);        fileItem.write(upload);        //输出结果        printWriter.print(fileName+"is saved");        System.out.println("处理完毕");        printWriter.print("the size of "+fileName+" is "+fileSize);    }}

3.web.xml配置

<servlet>        <servlet-name>upload</servlet-name>        <servlet-class>com.learn.ServletUpload</servlet-class>        <init-param>            <param-name>filePath</param-name>            <param-value>file</param-value>        </init-param>        <init-param>            <param-name>tempFilePath</param-name>            <param-value>temp</param-value>        </init-param>    </servlet>    <servlet-mapping>        <servlet-name>upload</servlet-name>        <url-pattern>/upload</url-pattern>    </servlet-mapping>

servlet下载文件

1.servlet下载文件

  servlet下载文件就是将服务器端的文件传输到客户端。

2案例

下载文件servlet类

package com.learn;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;/** * Created by Administrator on 2017/09/24. */public class DownLoadServlet extends HttpServlet {    private String filePath;    @Override    public void init(ServletConfig config) throws ServletException {        super.init(config);        filePath = config.getInitParameter("filePath");        //初始化路径        //filePath = config.getServletContext().getRealPath(filePath);        System.out.println("初始化文件路径:"+filePath);    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        OutputStream out; //输出流        InputStream in; //输入流        String fileName = req.getParameter("fileName");        System.out.println("文件名称:"+fileName);        //如果把文件名为null则提示用户        if(fileName == null){            out = resp.getOutputStream();            out.write("please input fileName".getBytes());            out.close();        }        //获取文件流        in = getServletContext().getResourceAsStream(filePath+ File.separator+fileName);        System.out.println(in==null?true:false);        int length = in.available();        //设置返回消息头部信息        resp.setContentType("application/force-download");        resp.setHeader("Content-Length",String.valueOf(length));        resp.setHeader("content-disposition","attachment;filename=\""+fileName+"\"");        //输出文件到客户端        out = resp.getOutputStream();        int bytesend = 0 ;        byte[] buff = new byte[512];        while ((bytesend = in.read(buff))!= -1){            out.write(buff,0,bytesend);        }        in.close();        out.close();    }}

web.xml配置

<servlet>    <servlet-name>download</servlet-name>    <servlet-class>com.learn.DownLoadServlet</servlet-class>    <init-param>        <param-name>filePath</param-name>        <param-value>file</param-value>    </init-param> </servlet> <servlet-mapping>    <servlet-name>download</servlet-name>    <url-pattern>/download</url-pattern> </servlet-mapping>

servlet Cookie的使用

1.cookie介绍

  Cookie,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。(可以叫做浏览器缓存)

2.cookie案例

  servlet 源码

package com.learn;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** *  */public class CookieServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        //cookie引用        Cookie cookie = null;        //设置返回类型为文本类型        resp.setContentType("text/plain");        //获取输出对象        PrintWriter out = resp.getWriter();        //从请求参数中获取cookies        Cookie[]  cookies = req.getCookies();        if(cookies != null){            for (int i = 0; i < cookies.length ; i++) {                out.println("name:"+cookies[i].getName());                out.println("value:"+cookies[i].getValue());                //如果cookie值为user,则赋值给cookie                if(cookies[i].getName().equals("user")){                    cookie = cookies[i];                }            }        } else {            out.print("no cookie");        }        if(cookie == null){            cookie = new Cookie("user","tom");            //设置cookie最大值为60分钟            cookie.setMaxAge(60*60);            resp.addCookie(cookie);        } else if(cookie.getValue().equals("tom")){            cookie.setValue("jack");            resp.addCookie(cookie);        } else if(cookie.getValue().equals("jack")){            cookie.setMaxAge(0);            resp.addCookie(cookie);        }       out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        super.doPost(req, resp);    }}

web,xml配置

<servlet>        <servlet-name>cookie</servlet-name>        <servlet-class>com.learn.CookieServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>cookie</servlet-name>        <url-pattern>/cookie</url-pattern>    </servlet-mapping>

servlet 转发,包含

1.什么是servlet转发?

  servlet将用户的请求通过一组servlet来处理,每个servlet都有自己特定的职责,当该servlet完成自己的工作后将请求转发到下一个servlet来处理,这种通过不同servelet相互转发请求来完成对某个请求的处理过程就叫做servlet转发。

2.什么是servlet包含?

  servlet包含就是源servlet将其他web组件(servlet,html,jsp),生成的结果包含到自己的结果中。

3.为什么需要servlet转发和包含?

  servlet对象是由Servlet容器创建,Servlet对象的Service()方法是由servlet容器调用,servlet之间是不允许相互调用(servlet API 2.1以前版本可以)。但是我们又需要通过多个servlet组件协调完成任务,同时方便代码维护管理,提高开发效率。这样就可以需要servlet转发和包含的技术支持。

4、转发和包含的相同点

  (1)都是对同一个请求对象处理,源组件和目标组件共享同一个ServletRequest对象和ServletResponse对象。

  (2)目标组件都可以是servlet,jsp,html。

  (3)都依赖javax,servlet.RequestDispatcher 接口。

5.RequestDIspatcher 对象

  该接口表示请求分发器

  (1)获取RequestDispatcher对象方法

    调用ServletContext的getRequestDispather(String path)方法获得。

    调用ServletRequest的getRequestDispather(String path)方法获得。

  (2)两种方法的区别

    ServletContext调用方法的参数必须为绝对路径,而ServletRequest调用方法参数可以是绝对路径也可以是相对路径。

6.请求转发案例

CheckServlet 类用于处理用户请求参数。

package com.learn;import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by Administrator on 2017/09/26. */public class CheckServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String userName = req.getParameter("name");        String message = "";        if(userName == null){            message = "please input your name";        } else {            message = userName;        }        req.setAttribute("mess",message);        RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher("/out");        PrintWriter out = resp.getWriter();        out.print("before forward ");        System.out.println("before forward");        requestDispatcher.forward(req,resp);        out.print("after forward");        System.out.println("after forward");        out.close();    }}

OutServlet 用于输出处理结果

package com.learn;import org.json.HTTP;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by Administrator on 2017/09/26. */public class OutServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String message = (String) req.getAttribute("mess");        PrintWriter printWriter = resp.getWriter();        printWriter.print(message);        printWriter.close();    }}

注意: 1.在转发之前不要提交响应结果。

    2.转发过程中,源组件的响应结果不会返回,只会返回目标组件的响应结果。

web.xml配置

<servlet>        <servlet-name>check</servlet-name>        <servlet-class>com.learn.CheckServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>check</servlet-name>        <url-pattern>/check</url-pattern>    </servlet-mapping>    <servlet>        <servlet-name>out</servlet-name>        <servlet-class>com.learn.OutServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>out</servlet-name>        <url-pattern>/out</url-pattern>    </servlet-mapping>

7.包含(include)案例 

MainServlet 用于包含其他组件,并返回响应结果

package com.learn;import javax.servlet.RequestDispatcher;import javax.servlet.Servlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by Administrator on 2017/09/26. */public class MainServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setContentType("text/html");        PrintWriter out = resp.getWriter();        out.println("<html><head><title>mainServlet</title></head>");        out.println("<body>");        ServletContext servletContext = getServletContext();        RequestDispatcher headDisPatcher = servletContext.getRequestDispatcher("/header.html");        RequestDispatcher greetDisPatcher = servletContext.getRequestDispatcher("/greet");        RequestDispatcher footeDisPatcher = servletContext.getRequestDispatcher("/footer.html");        headDisPatcher.include(req,resp);        greetDisPatcher.include(req,resp);        footeDisPatcher.include(req,resp);        out.print("</body></html>");        out.close();    }}

header.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>header</title></head><body><font size="6">Welcome to ab</font></body></html>

GreetServlet

package com.learn;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by Administrator on 2017/09/26. */public class GreetServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        PrintWriter out = resp.getWriter();        out.print("hi! "+req.getParameter("name")+", <p>");        out.close();    }}

footer.html

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>footer</title></head><body><span>Thanks for stopping</span></body></html>

web.xm配置

<servlet>        <servlet-name>main</servlet-name>        <servlet-class>com.learn.MainServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>main</servlet-name>        <url-pattern>/main</url-pattern>    </servlet-mapping>    <servlet>        <servlet-name>greet</servlet-name>        <servlet-class>com.learn.GreetServlet</servlet-class>    </servlet>    <servlet-mapping>        <servlet-name>greet</servlet-name>        <url-pattern>/greet</url-pattern>    </servlet-mapping>

servlet 重定向

1.重定向是什么?

  这里说的重定向是由http协议规定的一种机制。其工作流程如下所述。

  (1)客户端发起http请求,访问服务器端组件。

  (2)服务器端返回一个状态代码为302的响应结果。该代码的意思是让浏览器再访问另一个组件,响应结果中包含着访问新组件的url地址。新的访问组件可能在同一个应用中也可能不在同一个应用中。

  (3)当浏览器接受到这种结果,会自动访问新的url.

  (4)浏览器端接受新的url返回结果。

2.实现

  重定向通过Servlet API 中HttpServletReponse接口提供的 sendRedirect(String location)方法完成。

3.重定向特点

  3.1 servlet源组件的响应结果不会返回到客户端。

  3.2 servlet源组件和目标组件不会共享同一个ServletRequest对象。

  3.3 如果源组件在进行重定向前提前提交响应结果,会报异常。

   3.4 重定向的地址不必是同一个服务器的应用。

4.案例

Check1Servlet 第一次请求的类

package com.learn;import javax.servlet.RequestDispatcher;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** * Created by Administrator on 2017/09/28. */public class Check1Servlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String userName = req.getParameter("name");        String message = "";        if(userName == null){            message = "please input your name";        } else {            message = userName;        }        req.setAttribute("mess",message);        PrintWriter out = resp.getWriter();        out.print("before redirect ");        System.out.println("before redirect");        resp.sendRedirect("out1?mess="+message);        out.print("after redirect");        System.out.println("after redirect");        out.close();    }}

Out1Servlet 重定向的类

package com.learn;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;/** 1. Created by Administrator on 2017/09/28. */public class Out1Servlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String mess = (String) req.getAttribute("mess");        System.out.println("请求范围内的数据:"+mess);        mess = req.getParameter("mess");        System.out.println("请求参数中的:"+mess);        PrintWriter out = resp.getWriter();        out.write(mess);        out.close();    }}

页面输出结果:
这里写图片描述
控制台输出结果:

这里写图片描述