servlet快速实战

Servlet技术

什么事Servlet

  1. Servlet是JavaEE规范之一。规范就是接口
  2. Servlet是JavaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器
  3. Servlet试运行在服务器上的一个java小程序,他可以接后客户端发送过来的请求,并响应数据给客户端

手动实现Servlet接口

  1. idea创建项目准备
    请添加图片描述
    请添加图片描述

点击左上角 + 选择 local Tomcat
请添加图片描述
配置项目工程名
请添加图片描述
引入jar包
请添加图片描述

  1. 手动实现Servlet程序
  • 编写一个类去实现Servlet接口
  • 重写service方法,处理请求,并响应数据
  • 到web.xml中去配置servlet程序的访问地址
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 {
        System.out.println("hello servlet");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--  servlet 标签给Tomcat配置的Servlet程序  -->
    <servlet>
        <!--    servlet-name 标签 servlet程序起一个别名(一般是类名)    -->
        <servlet-name>HelloServlet</servlet-name>
        <!--    servlet-class 是  servlet程序全类名  -->
        <servlet-class>com.zhj.controller.HelloServlet</servlet-class>
    </servlet>

    <!--  servlet-mapping 标签 给servlet程序配置访问地址  -->
    <servlet-mapping>
        <!--    当前配置地址给那个servlet程序使用    -->
        <servlet-name>HelloServlet</servlet-name>
        <!--
            url-pattern 配置标签访问地址
            / 在服务器解析的时候,表示地址为 :http://ip:port/工程名
            /hello                     : http://ip:port/工程名/hello
        -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>



</web-app>

Servlet的生命周期

  1. 执行Servlet构造方法
  2. 执行init初始化方法
    第一步,第二步,是在第一次访问的时候servlet程序会调用
  3. 执行service方法
    第三步,每次访问的时候都会调用
  4. 执行destroy销毁方法
    第四步,在web工程停止的时候调用

请求分发 Get 与 Post

在service方法中加判断

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 {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        if (httpServletRequest.getMethod().equals("GET")) {
            doGet();
        }
         if (httpServletRequest.getMethod().equals("POST")) {
            doPost();
        }


    }

    private void doPost() {
        System.out.println("post 请求 ------");
    }

    private void doGet() {
        System.out.println("get 请求 ------");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

在web目录下创建 a.html,
访问 http://localhost:8080/my_servlet/a.html 测试

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<form action="http://localhost:8080/my_servlet/hello" method="get">
<!--<form action="http://localhost:8080/my_servlet/hello" method="post">-->
    <input type="submit" value="提交">
</form>
</body>
</html>

手动集成HttpServlet接口

  1. 编写一个类继承 HttpServlet 类
  2. 根据业务需要重写 doGet 或 doPost 方法
  3. 到web.xml中配置 Servlet 程序的访问地址
public class Hello2Servlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get 方法 ----");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post 方法 ----");
    }
}
 <servlet>
        <servlet-name>Hello2Servlet</servlet-name>
        <servlet-class>com.zhj.controller.Hello2Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello2Servlet</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

测试

<form action="http://localhost:8080/my_servlet/hello2" method="get">
    <input type="submit" value="get 提交">
</form>

<form action="http://localhost:8080/my_servlet/hello" method="post">
<input type="submit" value="post 提交">

IDEA中快速创建Servlet方式

请添加图片描述

Servlet的继承体系

请添加图片描述

ServletConfig类

ServletConfig类从类名上来看,就知道是servlet程序的配置信息类
Servlet程序和ServletConfig对象都是Tomcat负责创建,我们负责使用
Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建是,就创建一个对应的ServletConfig

ServletConfig类三大作用

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
//        1. 可以获取Servlet程序的别名 servlet-name 的值
        System.out.println(servletConfig.getServletName());
//        2. 获取初始化参数 init-param
        System.out.println(servletConfig.getInitParameter("user"));
        System.out.println(servletConfig.getInitParameter("password"));
//        3. 获取 ServletContext 对象
        System.out.println(servletConfig.getServletContext());
    }
 <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.zhj.controller.HelloServlet</servlet-class>

        <init-param>
            <param-name>user</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>password</param-name>
            <param-value>1234</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

细节说明

  • 在一个Servlet程序中,任意地方都可以获取 servletConfig对象: getServletConfig()
  • 如果重新 init的方法,必须调用一下 父类 super.init(config);

ServletContext类

什么是ServletContext?

  1. ServletContext是一个接口,他表示 Servlet 上下文对象
  2. 一个web工程,只有一个ServletContext对象实例
  3. ServletContext对象是一个域对象
  4. ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁
    什么是域对象?
    域对象,是可以想Map一样存取数据的对象,叫做域对象
    这里的域指存取数据的操作范围
    域对象 setAttribute() getAttribute() removeAttribute()

ServletContext类的四个作用

  1. 获取web.xml中配置的上下文参数 context-param
  2. 获取当前工程路径,格式: /工程路径
  3. 获取工程部署后在服务器硬盘上的绝对位置
  4. 像Map一样存取数据
public class Hello4Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取 ServletContext 对象
//        ServletContext servletContext = getServletConfig().getServletContext();
        ServletContext servletContext = getServletContext();
//        1. 获取web.xml中配置的上下文参数 context-param
        System.out.println(servletContext.getInitParameter("name"));
        System.out.println(servletContext.getInitParameter("password"));

//        2. 获取当前工程路径,格式: /工程路径
        System.out.println(servletContext.getContextPath());
//        3. 获取工程部署后在服务器硬盘上的绝对位置
        /**
         *  / 斜杠被服务器解析地址为 http://ip:port/工程名/
         *    映射到IDEA代码的web目录
         */
        System.out.println(servletContext.getRealPath("/"));
        System.out.println(servletContext.getRealPath("/css"));
//        4. 像Map一样存取数据
        servletContext.setAttribute("zhangsan",333);
        System.out.println(servletContext.getAttribute("zhangsan"));
    }
}

    <context-param>
        <param-name>name</param-name>
        <param-value>user</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>root</param-value>
    </context-param>
    <servlet>
        <servlet-name>Hello4Servlet</servlet-name>
        <servlet-class>com.zhj.controller.Hello4Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello4Servlet</servlet-name>
        <url-pattern>/hello4</url-pattern>
    </servlet-mapping>

HTTP协议

什么是HTTP协议

什么是协议?
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
所谓的HTTP协议,就是指,客户端与服务器通信时,发送的数据需要遵守的规则,叫做HTTP协议。HTTP协议中的数据又叫报文

GET请求

请添加图片描述

POST请求

请添加图片描述

常用请求头说明

Accept: 表示客户端可以接收的数据类型
Accept-Language: 表示客户端可以接收的语言类型
User-Agent : 表示客户端浏览器的信息
Host : 表示请求时的服务器IP和端口号

HTTP响应

请添加图片描述

常用响应码说明

200 表示请求成功
302 表示请求重定向
404 表示请求服务器已经收到了,数据不存在
500 服务器错误

MIME类型的说明

请添加图片描述

HttpServletRequest类

HttpServletRequest类的作用

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet或者doPost中给我们使用,我们可以通过HttpServletRequest对象,获取所有请求的信息)

HttpServlet类的常用方法

  1. getRequestURI() 获取请求资源路径
  2. getRequestURL() 获取请求绝对路径
  3. getRemoteHost() 获取IP
  4. getHeader() 获取请求头信息
  5. getParameter() 获取请求参数
  6. getParameterValues() 获取请求多个参数
  7. getMethod() 获取请求方式
  8. setAttribute() 设置域值
  9. getAttribute() 获取域值
  10. getRequestDispatcher() 获取请求转发对象
public class Hello5Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        5. getParameter() 获取请求参数
//        6. getParameterValues() 获取请求多个参数
        // 保证post请求中文不乱码
        request.setCharacterEncoding("UTF-8");
        System.out.println("用户名: "+request.getParameter("username"));
        System.out.println("密码: "+request.getParameter("password"));
        System.out.println("爱好: "+ Arrays.asList(request.getParameterValues("hobby")));
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1. getRequestURI() 获取请求资源路径
        System.out.println("获取请求资源路径 " + request.getRequestURI());
//        2. getRequestURL() 获取请求绝对路径
        System.out.println("获取请求绝对路径 " + request.getRequestURL());
//        3. getRemoteHost() 获取IP
        System.out.println("获取IP "+request.getRemoteHost());
//        4. getHeader() 获取请求头信息
        System.out.println("获取请求头信息 Accept " + request.getHeader("Accept"));
//        7. getMethod() 获取请求方式
        System.out.println("获取请求方式 "+request.getMethod());


    }
}

<form action="http://localhost:8080/my_servlet/hello5" method="post">
    用户名: <input type="text" name="username">
    密码 : <input type="password" name="password">
    爱好:
        <input type="checkbox" name="hobby" value="篮球">
        <input type="checkbox" name="hobby" value="足球">
        <input type="checkbox" name="hobby" value="乒乓球">
    <input type="submit" value="提交">
</form>

请求转发

请添加图片描述
特点:

  1. 浏览器地址没有发生改变
  2. 他们是一次请求
  3. 它们共享Request域中的数据
  4. 可以转发到WEB-INF目录下(浏览器上面是无法访问的)
  5. 不可以访问工程以外的资源
public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("name","zhangsan");
        // 注意 必须加 / , 因为 / 表示: http://ip:port/项目名/ 
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
        requestDispatcher.forward(req,resp);
    }

}
public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(req.getAttribute("name"));
    }

}

bash标签的作用

页面相对路径工作时参照的地址
	href 属性就是参数的地址值

请添加图片描述

web 中 / 的不同意义

在web中 / 是一种绝对路径。

  1. / 如果被浏览器解析,得到的地址 是 :http://ip:port/
	<a href="/"> 斜杠</a>
  1. / 如果被服务器解析,得到的地址是: http://ip:port/工程路径
	<url-pattern>/servlet1</url-pattern>
	RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
	servletContext.getRealPath("/")
	
  1. 特殊情况:response.sendRedirect(“/”) ;
    把斜杠发送给浏览器解析: http://ip:port/

HttpServletResponse类

HttpServletResponse类的作用

HttpServletResponse类和HttpServletRequest类一样。每次请求进来,tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse表示所有响应信息

两个输出流的说明

字节流: getOutputStream(); 常用于下载(传递二进制数据)
字符流: getWriter(); 常用于回传字符串(常用)
注意: 两个流同时只能使用一个,否则 报错

乱码问题解决

方式一

	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 方式一
         */
        // 设置服务器端
        resp.setCharacterEncoding("UTF-8");

        // 设置浏览器端
        resp.setHeader("Content-Type","text/html;charset=UTF-8");
        resp.getWriter().write("中国你好");
    }

方式二

	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 方式二 : 此方法需要在获取流之前
         */
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("中国你好");
    }

重定向

请添加图片描述

  1. 方案一
    resp.setStatus(302);
    resp.setHeader(“Location”,“http://localhost:8080”);
  2. 方案二
    response.sendRedirect(“http://localhost:8080”) ;

会话追踪技术

  • 会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,绘画结束,再一次会话中可以包含多次请求与响应(可以理解为打开一次浏览器)
  • 会话追踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
  • Http协议是无状态的,每次浏览器想服务器请求时,服务器多会将该请求视为新的请求,因此我们需要会话跟踪技术来实现来实现会话内数据共享
  • 实现方式
    1. 客户端会话追踪技术:Cookie
    2. 服务端会话追踪技术: Sessioin

Cookie

Cookie的基本使用

  • Cookie : 客户端会话追踪技术,以后每次请求都携带Cookie数据进行访问
  • Cookie的基本使用:
  1. 创建Cookie对象,设置数据

Cookie cookie = new Cookie(“key”,“value”);

  1. 发送Cookie到客户端: 使用Response对象

response.addCookie(cookie);


  1. 获取客户端携带的所有Cookie,使用request对象

Cookie[] cookies = request.getCookies();

  1. 遍历数组,获取每个Cookie对象:for
  2. 使用Cookie对象方法获取数据

    cookie.getName()
    cookie.getValue()

Cookie原理

Cookie的实现是基于HTTP协议的

  • 响应头: set-cookie
  • 请求头: cookie
    请添加图片描述

Cookie使用细节

  • Cookie存活时间
    默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁

    但是
    可以通过setMaxAge(int seconds) 设置Cookie存活时间

    1. 正数:将Cookie写在浏览器所在电脑的硬盘,持久化存储。到时间后自动删除
    2. 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie别销毁
    3. 零: 删除对应的Cookie
  • Cookie存储中文
    Cookie 不能直接存储中文
    但是
    如果需要存储,则需要进行转码: URL编码

Session

服务端会话跟踪技术:将数据保存到服务器
JavaEE提供了HttpSession接口,来实现一次会话的多次请求间数据共享功能

Session基本使用

  1. 获取Session对象
    HttpSession session = new HttpSession();
  2. Session对象的功能
    setAttribute()
    getAttribute()
    removeAttribute()

Session是基于Cookie实现的

请添加图片描述

Session的使用细节

  • Session钝化、活化
    服务器重启后,Session中的数据是否存在?存在
    钝化:在服务器正常关闭后,Tomcat会自动将Session数据写到硬盘的文件中
    活化:再从启动服务器后,从文件加载数据到Session
  • Session销毁
    默认情况下,无操作,30分钟自动销毁
    在web.xml中可配置
<session-config>
	<session-timeout>30</session-timeout>
</session-config>

或者主动调用 Session对象的invalidate()方法销毁

Cookie与Session的区别

Cookie和Session都是来完成一次会话多次请求间数据共享的
区别:

  1. 存储位置:Cookie是将数据存储在客户端,Session是将数据存储在服务器
  2. 安全性:Cookie不安全,Session相对安全
  3. 数据大小: Cookie最大3KB,Session无大小限制
  4. 存储时间: Cookie可以长期存储,Session默认30分钟
  5. 服务器性能: Cookie不占服务器资源,Sessino占用服务器资源

Filter

  • 概念:Filter表示过滤器,是JavaWeb三大组件(Servlet,Filter,Listener)之一
  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能请添加图片描述

Filter快速入门

  1. 定义类,实现Filter接口,并重写其所有方法
  2. 配置Filter拦截资源的路径:在类定义@WebFilter注解
  3. 在doFilter方法中输出一句话,并放行
	@WebFilter("/*")
public class FilterDemo implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 放行前逻辑
        System.out.println("Filter 被执行了");
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        // 放行后逻辑
        System.out.println("Filter 返回");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}

Filter执行流程

请添加图片描述

Filter拦截路径配置

Filter可以根据需求,配置不同的拦截资源路径

@WebFilter(“/*”)
public class FilterDemo

  • 拦截具体资源: /index.jsp : 只有访问index.jsp时才被拦截
  • 目录拦截: /user/* :访问/user下的所有资源,都会被拦截
  • 后缀名拦截: *.jsp : 访问后缀名为jsp的资源,都会被拦截
  • 拦截所有: /* : 访问所有资源都会被拦截

过滤器链

请添加图片描述

监听器

  • 概念:Listener 表示监听器,是JavaWeb三大组件(Servlet、Filter、Listener)之一
  • 监听器可以监听到就是在application、sessoin、request三个对象创建、销毁或者往里面添加修改删除属性时自动执行代码的功能组件
  • Listener分类: javaWeb提供了8个监听器请添加图片描述

ServletContextListener使用

  1. 定义类,实现ServletContextListener接口
  2. 在类上添加@WebListener注解
@WebListener
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("servlet 容器 创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("servlet 容器 销毁");

    }
}

JSP

  • 概念: JAVA Server Pages. Java服务端页面
  • 一种动态的页面技术,其中既可以定义HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容
  • JSP = HTML + JAVA

JSP快速入门

  1. 导入JSP坐标
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

  1. 创建JSP文件

  2. 编写HTML标签和JAVA代码

<h1>hello world</h1>
<%
    System.out.println("hello world");
%>

EL表达式

  • Expression Lanuage表达式语言,用于简化JSP页面的Java代码
  • 主要功能:获取数据
  • 语法:${expression}
  • JavaWeb的四大域对象:
    page : 当前页面有效
    request: 当前请求有效
    session : 当前会话有效
    application: 当前应用有效
    el表达式获取数据,会依次从这四个域中寻找,直到找到为止
    请添加图片描述

JSTL快速入门

  1. 导入坐标
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

  1. 引入JSP标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  1. 使用
    <c:if>

报错:
无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]

的错误

通过百度搜索到,需要如下操作:

把jstl-1.2.jar和standard.jar两个jar包拷贝到tomcat目录的lib目录下,因为tomcat没有这两个jar包

Servlet 统一异常处理

异常处理: 参考
异常处理: 参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值