JSP-06Servlet

8 篇文章 0 订阅

一、学习目标

  1. 理解Servlet的工作原理
  2. 理解Servlet的生命周期
  3. 掌握常用的Servlet API
  4. 会使用Servlet处理用户的请求
  5. 会通过注解配置Servlet

二、Servlet和Servlet容器

JavaWeb程序,运行于服务器端、运行时需要Servlet容器支持

Servlet

  1. 一个基于Java技术的Web组件
  2. 用于处理Web请求,生成动态内容
  3. 运行于服务器端,由Servlet容器创建并调用

Servlet容器

用于管理Servlet,包括加载、实例化和销毁Servlet

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OJQcVMqX-1657339953338)(E:\BDQN\BCSP\课件笔记\JSP\jsp 05.assets\1655705398558.png)]


三、Servlet与JSP之间的关系

创建index.jsp文件,输出 “这是我的JSP页面!”

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head><title>测试JSP</title><head>
    <body>这是我的JSP页面!<br></body>
</html>

启动项目,访问index.jsp,生成index_jsp.java文件

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
               implements// 省略部分代码{
      out.write("<html>\n");
      out.write("  <head>\n");
      out.write("    <title>测试JSP</title>\n");
      out.write("  </head>\n");
      out.write("  <body>\n");
      out.write("这是我的JSP页面!<br>\n");
      out.write("  </body>\n");
      out.write("</html>\n");
	// 省略部分代码
}

结论: JSP就是Servlet

JSP在运行时,Web容器会将其翻译成一个Servlet类,执行这个Servlet类中的方法,向浏览器动态响应内容。


四、Servlet体系结构

4.1Servlet结构图

在这里插入图片描述

4.2Servlet 4.0.1 API的两个包

1、javax.servlet包

定义并描述Servlet组件和运行环境之间的协定
通用的不依赖协议的Servlet API定义在此包中

主要包括ServletServletRequestServletResponseServletConfigServletContext接口及抽象类 GenericServlet

2、javax.servlet.http

支持HTTP协议的Servlet API定义在此包中
主要包括 HttpServlet、HttpServletRequest、 HttpServletResponse等

4.3Servlet接口

Servlet接口中定义了Servlet对象必须实现的方法

目录说明
void init(ServletConfig config)Servlet对象的初始化方法 由Servlet容器调用
void service(ServletRequest request, ServletResponse response)处理客户端的请求 由Servlet容器调用
void destroy()释放Servlet对象所使用的资源 由Servlet容器调用
ServletConfig getServletConfig()返回传递给init()方法的ServletConfig对象,该对象包含此Servlet的初始化和启动参数
String getServletInfo()返回字符串文本形式的Servlet相关信息

4.4GenericServlet抽象类

提供了Servlet与ServletConfig接口方法的默认实现,但不包括service()方法

目录说明
public void init(ServletConfig config)实现Servlet接口中init(ServletConfig config)方法将ServletConfig实例进行保存以备用
public void init()用于在子类中重写,以实现用户订制的初始化工作
public String getInitParameter(String name)返回web.xml中名称为name的初始化参数的值
public ServletContext getServletContext()返回ServletContext对象的引用

4.5HttpServlet抽象类

针对HTTP协议提供了相关的支持,我们创建Servlet都是继承自HttpServlet

目录说明
public void service(ServletRequest request,ServletResponse response)实现GenericServlet抽象类中的service()方法,根据请求方法的类型调用相应的doGet()或doPost方法
protected void service(HttpServletRequest request, HttpServletResponse response)接收HTTP请求,并将它们分发给此类中定义的一系列doXxx()方法
protected void doXxx(HttpServletRequest request,HttpServletResponse response)根据请求方式的不同分别调用的相应处理方法,如doGet()、doPost()等

4.6ServletContext接口

ServletContext接口主要用于获取Web应用上下文,与Servlet容器进行通信,application内置对象即为ServletContext实例。

目录说明
String getInitParameter(String name)获取应用范围中名为name的初始化参数值,在web.xml中使用<context-param>元素定义
void setAttribute(String name, Object object)设置名称为name的属性
Object getAttribute(String name)获取名称为name的属性
void removeAttribute(String name)从Servlet上下文中删除指定名称的属性
String getRealPath(String path)返回参数所代表目录的真实路径
void log(String message)记录一般日志信息

4.5请求响应相关结构

在这里插入图片描述

4.6ServletRequest接口

ServletRequest接口主要用于获取客户端请求数据

目录说明
Object getAttribute(String name) 获取请求域中名称为name的属性值
void setAttribute(String name, Object object)在请求域中保存名称为name的属性
void removeAttribute(String name) 清除请求域中名字为name的属性
String getCharacterEncoding()返回请求体所使用的字符编码
void setCharacterEncoding(String charset)设置请求体的字符编码
String getParameter(String name)返回指定请求参数的值
String [ ] getParameterValues(String name)返回指定请求参数的全部值
RequestDispatcher getRequestDispatcher(String path)返回指向指定路径的请求分发对象

4.7HttpServletRequest接口

HttpServletRequest接口继承ServletRequest接口中的方法,增加了用于读取HTTP请求信息的方法

目录说明
String getContextPath()返回请求的上下文路径,上下文路径是请求URI的开始部分
Cookie [ ] getCookies()返回客户端在此次请求中发送的Cookie对象
HttpSession getSession()返回和此次请求相关联的session对象,若没有为客户端分配session对象,则创建一个新的
String getMethod()返回此次请求所使用的HTTP方法的名字,如GET、POST
String getHeader(String name)获取指定的请求头信息

4.8ServletResponse接口

ServletResponse接口中设置响应参数和向客户端发送响应数据

目录说明
PrintWriter getWriter()返回用于向客户端发送文本的PrintWrite对象
String getCharacterEncoding()返回发送响应正文所使用的字符编码
void setCharacterEncoding(String charset)为即将发送到客户端的响应设置字符编码
void setContentType(String type)设置发送到客户端的响应的内容类型
ServletOutputStream getOutputStream()返回适合于在响应中写入二进制数据的ServletOutputStream对象

4.9HttpServletResponse接口

HttpServletResponse接口继承ServletResponse接口中的方法,增加了适用于HTTP响应的新方法

目录说明
void addCookie(Cookie cookie)向响应中增加一个cookie 多次调用,可设置多个cookie
void addHeader(String name, String value)向响应中添加一个名称为name、值为value的响应报头
void sendRedirect(String location)向客户端发送一个临时的重定向响应,以便客户端访问新的URL
void encodeRedirectURL(String url)使用session ID对用于重定向的URL进行编码

五、Servlet生命周期

Servlet生命周期包含四个阶段

在这里插入图片描述

Servlet生命周期演示

观察Servlet中各方法什么时候触发执行,和执行的顺序

创建一个Servlet,继承HttpServlet接口

@WebServlet("/helloServlet")
public class HelloServlet extends HttpServlet {
	//省略部分代码...
}

重写init()方法

/**初始化方法*/
@Override
public void init() throws ServletException {
    System.out.println("初始化时,执行init()方法!");
}

重写doGet()、doPost()方法

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("处理请求时,执行doGet()方法!");
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("处理请求时,执行doPost()方法!");
}

重写destroy()方法

@Override
public void destroy() {
    System.out.println("释放系统资源时,执行destroy()方法!");
}

测试访问:

第1次访问http://localhost:8080/jsp06/helloServlet 控制台运行结果:

在这里插入图片描述

第2次访问http://localhost:8080/jsp06/helloServlet 控制台运行结果:

在这里插入图片描述

点击停止服务按钮后控制台输出结果

在这里插入图片描述

在这里插入图片描述


六、Servlet的使用

需求: 使用Servlet作为控制器实现用户登录功能

分析:

1. 创建LoginServlet
2. 继承HttpServlet类
3. 重写doGet()和doPost()方法
4. 创建login.jsp页面
5. 设计登录表单
6. 配置Servlet

步骤: 1.创建LoginServlet——>2.继承HttpServlet类——>3.重写doGet()和doPost()方法

package com.bookshop.servlet;

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;
import java.io.PrintWriter;

/**
 * 登录控制器
 * @author Aiden
 */
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = -3922210057279156283L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        String loginId = request.getParameter("loginId");
        String loginPwd = request.getParameter("loginPwd");
        if ("admin".equals(loginId) && "123456".equals(loginPwd)) {
            response.sendRedirect("index.jsp");
        }else{
            out.print("<script>alert('账号或密码错误');location.href='login.jsp';</script>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //doGet() 和doPost()方法分别用于处理不同类型的请求,但由于其业务代码基本相同,实际开发中可以使用一个方法调用另一个
        doGet(req,resp);
    }
}

步骤4创建login.jsp页面;步骤5设计登录表单

<form id="login" action="LoginServlet" method="post">
    <p>账号:<input type="text" id="loginId" name="loginId"></p>
    <p>密码:<input type="text" id="loginPwd" name="loginPwd"></p>
    <p><input type="submit" value="登录" name="btnLogin"></p>
</form>

form表单的action属性对应Servlet的访问路径

web.xml文件中的<url-pattern>

@WebServlet注解的urlPatterns属性

input标签中定义的参数,可从HttpServletRequest对象中获取

步骤6配置Servlet
方式1:通过部署描述文件(web.xml)配置Servlet

<!--配置Servlet-->
<servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.bookshop.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>

方式2:通过注解配置Servlet

/**
 * 登录控制器
 * 1.创建Servlet
 * 2.添加注解 @WebServlet
 * 3.继承HttpServlet
 * 4.重写 doGet / doPost
 * @author Aiden
 */
@WebServlet(name="LoginServlet",urlPatterns = {"/LoginServlet"},loadOnStartup = -1)
public class LoginServlet extends HttpServlet {
    //省略doGet、doPost方法实现
}

@WebServlet注解常用属性

目录数据类型说明
nameString指定Servlet名称,默认为类的全限定名
urlPatternsString []指定一组Servlet的URL匹配模式
loadOnStartupint指定Servlet的加载顺序
initParamsWebInitParam []指定一组Servlet初始化参数

七、获取Servlet初始化参数

使用注解定义初始化参数

@WebServlet(name="LoginServlet",urlPatterns = {"/LoginServlet"}, loadOnStartup = -1,initParams = {@WebInitParam(name="loginId",value="admin"),@WebInitParam(name="loginPwd",value="admin")})
public class LoginServlet extends HttpServlet {
    // 省略部分代码… 
}

获取初始化参数,使用PrintWriter对象输出参数内容到页面

PrintWriter out = resp.getWriter();
ServletConfig servletConfig = this.getServletConfig();
out.append("loginId:"  + servletConfig.getInitParameter("loginId")+<br>");
out.append("loginPwd:" + servletConfig.getInitParameter("loginPwd");
out.flush(); // 输出内容到页面
out.close();

访问当前Servlet,测试调用

loginId:admin
loginpwd:admin

动态获取初始化参数

获取所有初始化参数名

ServletConfig servletConfig = this.getServletConfig();
Enumeration<String> paramNames = servletConfig.getInitParameterNames();

遍历初始化参数名数组,获取初始化参数值

while (paramNames.hasMoreElements()) {
    String paramName = paramNames.nextElement();
    String value = servletConfig.getInitParameter(paramName);
}

经验: 使用getInitParameterNames() 方法可以在未知参数名的情况下获取到所有初始化参数,减少硬编码


八、访问应用上下文

web.xml中添加如下配置:

语法说明:
<context-param>元素声明Web应用的全局范围参数 <param-name>:参数名<param-value>:参数值

<context-param>
    <param-name>adminEmail</param-name>
    <param-value>admin@hotmail.com</param-value>
</context-param>

获取初始化参数,输出到页面

PrintWriter out = resp.getWriter();
ServletConfig servletConfig = this.getServletConfig();
String adminEmail = this.getServletContext().getInitParameter("adminEmail");
out.println("站内管理员邮箱:" + adminEmail);
// 省略部分代码 …

运行结果:

站内管理员邮箱:admin@hotmail.com

九、JSP对比Servlet

JSP:在HTML页面嵌入Java代码和JSP标记

1.便于表现层开发
2.前后端代码混乱,不利于代码重用和模块化开发

Servlet:在Java类中输出HTML代码

1.便于代码重用和模块化开发
2.不利于开发表现层功能、开发效率低

总结对比:

JSP便于开发表示层组件,而Servlet适合编写流程控制代码。针对两者特点,开发Web应用时,通常会将其结合使用。


十、使用Servlet实现控制器

10.1Servlet的职责

1. 充当控制器的角色,接受请求
2. 负责实例化JavaBean对象处理业务逻辑
3. 为JSP页面准备封装数据的JavaBean对象
4. 将请求分发给适当的JSP页面来产生响应

在这里插入图片描述

10.2使用Servlet改造第三波书店系统

创建Servlet

@WebServlet(name = "BookServlet", urlPatterns = "/BookServlet")
public class BookServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {
        //操作类型
        String action = request.getParameter("action");
        if("select".equals(action)) {//查询所有图书列表...
        }else if("details".equals(action)){//查询单本图书信息... 
        }else if("insert".equals(action)){//新增图书信息...
        }else if("toUpdate".equals(action)){//跳转至修改图书页面...
        }else if("update".equals(action)){//修改图书信息...
        }else if("delete".equals(action)){//删除图书信息...
        }
   }

修改页面链接

<a href="BookServlet?action=select">查询所有图书</a>
<a href="BookServlet?action=details&bookId=1">查询所有图书</a>

总结

思维导图

在这里插入图片描述
学习讨论群: 617530501

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

众生云海,一念初见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值