Servlet学习小结

Servlet学习小结


Servlet 概念

1.servlet 是JavaEE规范之一。规范就是接口。

2.servlet是JavaWeb三大组件之一。三大组件分布是:servelet程序、Filter过滤器、Listener监听器。

3.servlet是运行在服务器上的一个Java小程序, 它可以接受客户端发送过来的请求,并响应数据给客户端

手动实现Servlet

1. 编写一个类实现servlet 接口 (实际开发中应该使用HttpServlet)

2. 实现接口中service方法,处理请求,响应数据。

3. 配置web.xml中servlet的响应地址。

import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {}

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
          //当被访问时,该方法被执行
          Sytem.out.println("hello..");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() { }
}

在这里插入图片描述

Note : url-pattern 需要以 '/'开始


在Servlet3.0中引入注解来配置,不需要在web.xml在进行配置。

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 引用注解 WebServlet进行配置
 */
@WebServlet(name = "HelloServlet",urlPatterns = {"/hello","/helloServlet"})
public class HelloServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

Servlet 生命周期

从Servlet其定义的方法init(),service(),destroy()中可以了解到。

1.执行Servlet构造函数
2.执行Servlet中 init() 方法。
以上1.2步骤仅在第一次访问Servlet时进行(也说明了servlet为单例对象)
3.执行service方法。 (以后每次访问servlet,都执行该方法)
4.当关闭web工程时,执行destroy()方法

Servlet 继承体系

在这里插入图片描述

Get和Post请求分发处理

HttpServlet在service中利用requset.getMethod()的值进行请求分发,其源码如下:

 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;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    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);
        }

    }


ServletConfig类

Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个Servlet 程序创建时,就创建一个对应的ServletConfig 对象。

ServletConfig的作用

  1. 可以获取Servlet程序别名 (即配置文件中 servlet-name的值)
  2. 获取配置文件中定义的init-param的初始化参数
  3. 获取servletContext对象


SevletContext类

ServletContext是一个接口,表示Servlet上下文对象。一个Web工程仅只有一个ServletContext对象。 该对象为一个域对象。在web工程启动时ServletContext对象被创建,在web工程停止时,该对象会为销毁。


域对象:像Map一样存储数据的对象叫域对象。域指的是存取数据的操作范围,这里值的是整个web工程。

ServletContext的作用

1.获取web.xml配置文件中的context-param的值 。
2.获取当前工程路径:getContextPath()
3.获取工程部署在服务器上的决定路径:getRealPath()
4.像Map 一样存取数据

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
		// 1、获取web.xml 中配置的context-param的参数
		ServletContext context = getServletConfig().getServletContext();
		String value1= context.getInitParameter("key1");  //value1
		
		//2.获取工程路径
		String contextPath =  context.getContextPath();
		//3.获取项目绝对路径
		String realPath = context.getRealPath();
		//4. 存取数据。
		context.setAttribute("key",object);
        Object value = context.getAttribute("key");
		}
		

<!--context-param 是上下文参数(它属于整个web 工程)-->
	<context-param>
		<param-name>key1</param-name>
		<param-value>value1</param-value>
	</context-param>
<!--context-param 是上下文参数(它属于整个web 工程)-->
	<context-param>
		<param-name>key2</param-name>
		<param-value>value2</param-value>
	</context-param>

HttpServletRequest类常用方法

获取请求参数值
request.getParameter(String) : String

获取请求参数值 (当该参数值为多个时使用)
request.getParameterValues(String) : String[]

获取请求参数字典
request.getParameterMap(): Map<String,String[]>

获取请求头
request.getHeader(String) :  String

获取请求方法
request.getMethod() : String

获取HttpSession
request.getSession() : HttpSession

设置request域数据
request.setAttribute(String , Object ): void

获取request域数据
request.getAttribute(String) : Object

获取request分发器
request.getRequestDispatcher(String) : RequestDispatcher

获取URI和URL
request.getRequestURI(): String
request.getRequestURL() : String

中文乱码问题

tomcat 默认使用字符集为 ISO-8859-1,无法对中文进行解析(出现乱码),需要重新设置字符集。

	     //分别对request和response中的字符集进行设置,设置字符集为utf-8
  		req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

请求的转发

使用方法:request.getRequestDispatcher(String).forward(ServletRequest , ServletResponse );
请求的转发是指,当服务器收到请求后,从一个资源跳转到另外一个资源(使用同一个HttpServletRequest和HttpServletResponse)。属于一次请求, 其浏览器地址栏没有发送变化。


web中 '/' 的意义

在web中 '/' 被解析为: http://ip:port/

	<a href ="/">web中的斜杠<a/>

在服务器中 ,’/’ 被解析为 : http://ip:port/工程路径/

      <url-pattern>/helloServlet</url-pattern>
     servletContext.getRealPath("/");
     request.getRequestDispatcher("/");

HttpServletResponse 类

HttpServletResponse有两个输出流 getOutputSteam() 和 getWriter()。两个流同时只能使用一个。同时使用会报错。
在这里插入图片描述

请求重定向: resp.sendRedirect(String)


文件的上传与下载

在表单中method为post, form标签中的encType属性值设置为 multipart/form-data, 将input的type属性改为file,最后编写servlet程序进行接受上次的数据。
encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼
接,然后以二进制流的形式发送给服务器
引注第三方jar包: 1.commons-fileupload-1.3.2.jar
2.commons-io-2.5.jar

Servlet上传文件代码

Servlet下载文件
在这里插入图片描述

在这里插入图片描述

Filter过滤器

1、Filter 过滤器它是JavaWeb 的三大组件之一。三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器
2、Filter 过滤器它是JavaEE 的规范。也就是接口
3、Filter 过滤器它的作用是:拦截请求,过滤响应。

public interface Filter {
    void init(FilterConfig var1) throws ServletException;
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    void destroy();
}

实现Filter

1.编写一个自定义类实现Filter接口。
2.实现接口中的doFilter方法
3.在web.xml中进行配置

<!--filter 标签用于配置一个Filter 过滤器-->
	<filter>
<!--给filter 起一个别名-->
		<filter-name>HelloFilter</filter-name>
<!--配置filter 的全类名-->
		<filter-class>com.study.filter.HelloFilter</filter-class>
</filter>
<!--filter-mapping 配置Filter 过滤器的拦截路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个filter 使用-->
		<filter-name>HelloFilter</filter-name>
<!--url-pattern 配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到IDEA 的web 目录
/hello/* 表示请求地址为:http://ip:port/工程路径/hello/*
-->
		<url-pattern>/hello/*</url-pattern>
</filter-mapping>

在Sevlet3.0中也可以使用@WebFilter注解进行配置。

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(filterName = "ManagerFilter", urlPatterns ={"/pages/manager/*","/manager/*"} )
public class ManagerFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
     chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
    }
}

Filter的生命周期

Filter 的生命周期包含几个方法
1、构造器方法
2、init 初始化方法
第1,2 步,在web 工程启动的时候执行(Filter 已经创建)
3、doFilter 过滤方法
第3 步,每次拦截到请求,就会执行
4、destroy 销毁
第4 步,停止web 工程的时候,就会执行(停止web 工程,也会销毁Filter 过滤器)

FilterConfig类

FilterConfig 是Filter 过滤器的配置文件类。Tomcat 每次创建Filter 的时候,也会同时创建一个FilterConfig 类,这里包含了Filter 配置文件的配置信息。
FilterConfig 类的作用是获取filter 过滤器的配置内容
1、获取Filter 的名称filter-name 的内容
2、获取在Filter 中配置的init-param 初始化参数
3、获取ServletContext 对象

FilterChain 过滤器链

如下图举例,存在两个过滤器F1和F2,其工作流程如下所示。

ClientFilter1Filter2Target执行F1.doFilter前置代码进行拦截,直接返回到客户端执行F2.doFilter前置代码alt[进行拦截][放行,执行doFilter()方法]进行拦截,先经过Filter1中的doFilter后置代码,然后返回到客户端访问目前资源alt[进行拦截][放行,执行doFilter()方法]经过F1和F2的doFilter后置代码,返回到客户端ClientFilter1Filter2Target

1.该访问过程处于同一线程内,其HttpServletRequest为同一对象。
2.FilterChain.doFilter()方法的作用为:不进行拦截,继续向后执行。(当存在多个Filter时,其过滤顺序由web.xml中从上到下配置顺序来决定。

Filter拦截路径

Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!

--精确匹配
<url-pattern>/target.jsp</url-pattern>
--目录匹配
<url-pattern>/targetDirectory/*</url-pattern>
--后缀匹配
<url-pattern>/*.html</url-pattern>
<url-pattern>/*.action</url-pattern>
<url-pattern>/*.do</url-pattern>

版权声明:本文为jasd1996原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。