【JavaWeb】Servlet

Servlet

文章目录

  • Servlet
  • 一、简介
  • 二、开发流程
  • 三、生命周期
  • 四、ServletConfig和ServletContext
  • 五、HttpServletRequest常见API
  • 六、HttpServletResponse常见API
  • 七、请求转发和响应重定向
    • 7.1 概述
    • 7.2 请求转发
    • 7.3 响应重定向
  • 八、请求与响应乱码问题
    • 8.1 GET与POST请求乱码
    • 8.2 响应乱码问题
  • 九、MVC架构模式

一、简介

Servlet (server applet) 是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口

  • 用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中,Servlet主要负责接收处理请求、协同调度功能以及响应数据。我们可以把Servlet称为Web应用中的控制器
  • 不是所有的JAVA类都能用于处理客户端请求,能处理客户端请求并做出响应的一套技术标准就是Servlet
  • Servlet是运行在服务端的,所以 Servlet必须在WEB项目中开发且在Tomcat这样的服务容器中运行

请求响应与HttpServletRequest和HttpServletResponse之间的对应关系:

在这里插入图片描述

二、开发流程

  1. 参照上一篇内容,创建一个web类型的module
  2. 新建一个Servlet类,继承HttpServlet,重写service或doMeth方法(doGet、doPost等方法)
    • Servlet对象的生命周期(创建,初始化,处理服务,销毁)是由tomcat管理的,无需我们自己new
    • HttpServletRequest 代表请求对象,是由请求报文经过tomcat转换而来的,通过该对象可以获取请求中的信息
    • HttpServletResponse 代表响应对象,该对象会被tomcat转换为响应的报文,通过该对象可以设置响应中的信息
  3. web.xml 为自定义的Servlet配置请求的映射路径,配置 servletservlet-mapping

步骤2

public class UserServlet extends HttpServlet {@Overridepublic void service(ServletRequest request, ServletResponse response) throws IOException {String username = request.getParameter("username");if (username != null && !username.isEmpty()) {response.getWriter().println("参数获取成功:" + username);} else {response.getWriter().println("参数获取失败");}}
}

步骤3

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"version="6.0"><servlet><servlet-name>userServlet</servlet-name><servlet-class>servlet.UserServlet</servlet-class></servlet><servlet-mapping><servlet-name>userServlet</servlet-name><url-pattern>/userServlet</url-pattern></servlet-mapping>
</web-app>

三、生命周期

Servlet对象是Servlet容器创建的,生命周期方法都是由容器(目前我们使用的是Tomcat)调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。

生命周期对应方法执行时机执行次数
构造对象构造器第一次请求或者容器启动1
初始化init()构造完毕后1
处理服务service(HttpServletRequest req,HttpServletResponse resp)每次请求多次
销毁destory()容器关闭1
  • Servlet对象在容器中是单例的
  • 容器是可以处理并发的用户请求的,每个请求在容器中都会开启一个线程

load-on-startup :当值为0或者大于0时,代表容器启动时加载该servlet。正数的值越小,启动时加载该servlet的优先级越高。如果为负数,则容器启动时不会加载该servlet,只有该servlet被选择时才会加载。

  • 如果数字重复了,容器会自行解决实例化顺序问题,但是应该避免重复

  • Tomcat容器中已经定义了一些随系统启动实例化的servlet,我们自定义的servlet的load-on-startup尽量不要占用数字1-5

四、ServletConfig和ServletContext

ServletConfig:ServletConfig为Servlet提供初始配置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象。容器会为每个Servlet实例化一个ServletConfig对象,并通过Servlet生命周期的init方法传入给Servlet作为属性。可通过该对象迭代获取servlet初始化配置参数。

方法名作用
getServletName()获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称
getServletContext()获取ServletContext对象
getInitParameter()获取配置Servlet时设置的『初始化参数』,根据名字获取值
getInitParameterNames()获取所有初始化参数名组成的Enumeration对象

ServletContext:ServletContext对象有称呼为上下文对象,或者叫应用域对象容器会为每个app创建一个独立的唯一的ServletContext对象。通过该对象可获取静态资源的真实路径以及项目的上下文路径

域对象:一些用于存储数据和传递数据的对象,传递数据不同的范围为不同的域。

  • ServletContext代表应用,所以ServletContext域也叫作应用域,是webapp中最大的域,可以在应用内实现数据的共享和传递
  • webapp中的三大域对象,分别是应用域,会话域,请求域
  • 三大域对象都具有的API如下
API功能解释
void setAttribute(String key,Object value);向域中存储/修改数据
Object getAttribute(String key);获得域中的数据
void removeAttribute(String key);移除域中的数据

五、HttpServletRequest常见API

  • 获取请求行信息相关(方式,请求的url,协议及版本)
API功能解释
StringBuffer getRequestURL();获取客户端请求的url
String getRequestURI();获取客户端请求项目中的具体资源
int getServerPort();获取客户端发送请求时的端口
int getLocalPort();获取本应用在所在容器的端口
int getRemotePort();获取客户端程序的端口
String getScheme();获取请求协议
String getProtocol();获取请求协议及版本号
String getMethod();获取请求方式
  • 获得请求头信息相关
API功能解释
String getHeader(String headerName);根据头名称获取请求头
Enumeration getHeaderNames();获取所有的请求头名字
String getContentType();获取content-type请求头
  • 获得请求参数相关
API功能解释
String getParameter(String parameterName);根据请求参数名获取请求单个参数值
String[] getParameterValues(String parameterName);根据请求参数名获取请求多个参数值数组
Enumeration getParameterNames();获取所有请求参数名
Map<String, String[]> getParameterMap();获取所有请求参数的键值对集合
BufferedReader getReader() throws IOException;获取读取请求体的字符输入流
ServletInputStream getInputStream() throws IOException;获取读取请求体的字节输入流
int getContentLength();获得请求体长度的字节数
  • 其他API
API功能解释
String getServletPath();获取请求的Servlet的映射路径
ServletContext getServletContext();获取ServletContext对象
Cookie[] getCookies();获取请求中的所有cookie
HttpSession getSession();获取Session对象
void setCharacterEncoding(String encoding) ;设置请求体字符集

六、HttpServletResponse常见API

  • 设置响应行相关
API功能解释
void setStatus(int code);设置响应状态码
  • 设置响应头相关
API功能解释
void setHeader(String headerName, String headerValue);设置/修改响应头键值对
void setContentType(String contentType);设置content-type响应头及响应字符集(设置MIME类型)
  • 设置响应体相关
API功能解释
PrintWriter getWriter() throws IOException;获得向响应体放入信息的字符输出流
ServletOutputStream getOutputStream() throws IOException;获得向响应体放入信息的字节输出流
void setContentLength(int length);设置响应体的字节长度,其实就是在设置content-length响应头
  • 其他API
API功能解释
void sendError(int code, String message) throws IOException;向客户端响应错误信息的方法,需要指定响应码和响应信息
void addCookie(Cookie cookie);向响应体中增加cookie
void setCharacterEncoding(String encoding);设置响应体字符集

七、请求转发和响应重定向

7.1 概述

  • 请求转发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段
  • 请求转发通过HttpServletRequest实现,响应重定向通过HttpServletResponse实现

7.2 请求转发

在这里插入图片描述

  • 请求转发通过HttpServletRequest对象获取请求转发器实现
  • 请求转发是服务器内部的行为,对客户端是屏蔽的
  • 客户端只发送了一次请求,客户端地址栏不变
  • 服务端只产生了一对请求和响应对象,这一对请求和响应对象会继续传递给下一个资源
  • 因为全程只有一个HttpServletRequset对象,所以请求参数可以传递,请求域中的数据也可以传递
  • 请求转发可以转发给其他Servlet动态资源,也可以转发给一些静态资源以实现页面跳转
  • 请求转发可以转发给WEB-INF下受保护的资源
  • 请求转发不能转发到本项目以外的外部资源
@WebServlet("/servletA")
public class ServletA extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//  获取请求转发器//  转发给servlet  okRequestDispatcher  requestDispatcher = req.getRequestDispatcher("servletB");//  转发给一个视图资源 ok//RequestDispatcher requestDispatcher = req.getRequestDispatcher("welcome.html");//  转发给WEB-INF下的资源  ok//RequestDispatcher requestDispatcher = req.getRequestDispatcher("WEB-INF/views/view1.html");//  转发给外部资源   no//RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.baidu.com");//  获取请求参数String username = req.getParameter("username");System.out.println(username);//  向请求域中添加数据req.setAttribute("reqKey","requestMessage");//  做出转发动作requestDispatcher.forward(req,resp);}
}

7.3 响应重定向

在这里插入图片描述

  • 响应重定向通过HttpServletResponse对象的sendRedirect方法实现
  • 响应重定向是服务端通过302响应码和路径,告诉客户端自己去找其他资源,是在服务端提示下的客户端的行为
  • 客户端至少发送了两次请求,客户端地址栏是要变化的
  • 服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源
  • 因为全程产生了多个HttpServletRequset对象,所以请求参数不可以传递,请求域中的数据也不可以传递
  • 重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转
  • 重定向不可以到给WEB-INF下受保护的资源
  • 重定向可以到本项目以外的外部资源
@WebServlet("/servletA")
public class ServletA extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//  获取请求参数String username = req.getParameter("username");System.out.println(username);//  向请求域中添加数据req.setAttribute("reqKey","requestMessage");//  响应重定向// 重定向到servlet动态资源 OKresp.sendRedirect("servletB");// 重定向到视图静态资源 OK//resp.sendRedirect("welcome.html");// 重定向到WEB-INF下的资源 NO//resp.sendRedirect("WEB-INF/views/view1");// 重定向到外部资源//resp.sendRedirect("http://www.baidu.com");}
}

八、请求与响应乱码问题

8.1 GET与POST请求乱码

  • HTML中的 <meta charset='字符集'/> 影响了GET和POST方式提交参数的编码
  • tomcat 10.1 的URI编码默认为 UTF-8

解决方案:

  • 方式1:修改<meta charset='字符集'/>编码和 Tomcat10.1 的URI默认解析编码一致即可 (推荐)
  • GET请求方式2:修改 Tomcat10.1 的URI解析字符集。修改conf/server.xml中 Connecter 添加 URIEncoding=“GBK” (不推荐)
  • POST请求方式2:修改请求解析体使用的字符集与前端保持一致,调用 req.setCharacterEncoding 方法 (不推荐)

8.2 响应乱码问题

  • 在Tomcat10.1.7中,向响应体中放入的数据默认使用了工程编码 UTF-8
  • 浏览器在接收响应信息时,使用了不同的字符集或者是不支持中文的字符集就会出现乱码

解决方案:

  • 方式一:客户手动设定浏览器对本次响应体解析时使用的字符集(不推荐)
  • 方式二:后端通过设置响应体的字符集和浏览器解析响应体的默认字符集一致,调用 resp.setCharacterEncoding 方法(不推荐)
  • 方式三:通过设置content-type响应头,告诉浏览器以指定的字符集解析响应体(推荐)
// 告诉浏览器以指定的MIME类型和字符集解析响应体
resp.setContentType("text/html;charset=UTF-8")

MIME类型

  • MIME类型,可以理解为文档类型,用户表示传递的数据是属于什么类型的文档
  • 浏览器可以根据MIME类型决定该用什么样的方式解析接收到的响应体数据
  • 可以这样理解: 前后端交互数据时,告诉对方发给对方的是 html/css/js/图片/声音/视频/… …
  • tomcat/conf/web.xml中配置了常见文件的拓展名和MIMIE类型的对应关系
  • 常见的MIME类型举例如下
文件拓展名MIME类型
.htmltext/html
.csstext/css
.jsapplication/javascript
.png /.jpeg/.jpg/… …image/jpeg
.mp3/.mpe/.mpeg/ … …audio/mpeg
.mp4video/mp4
.m1v/.m1v/.m2v/.mpe/… …video/mpeg

九、MVC架构模式

MVC(Model View Controller)是软件工程中的一种 软件架构模式,它把软件系统分为 模型视图控制器 三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

  • M:Model 模型层,具体功能如下
    1. 存放和数据库对象的实体类以及一些用于存储非数据库表完整相关的VO对象
    2. 存放一些对数据进行逻辑运算操作的的一些业务处理代码
  • V:View 视图层,具体功能如下
    1. 存放一些视图文件相关的代码 html css js等
    2. 在前后端分离的项目中,后端已经没有视图文件,该层次已经衍化成独立的前端项目
  • C:Controller 控制层,具体功能如下
    1. 接收客户端请求,获得请求数据
    2. 将准备好的数据响应给客户端

MVC模式下,项目中的常见包

  • M:

    1. 实体类包(pojo /entity /bean) 专门存放和数据库对应的实体类和一些VO对象
    2. 数据库访问包(dao/mapper) 专门存放对数据库不同表格CURD方法封装的一些类
    3. 服务包(service) 专门存放对数据进行业务逻辑运算的一些类
  • C:

    1. 控制层包(controller)
  • V:

    1. web目录下的视图资源 html css js img 等
    2. 前端工程化后,在后端项目中已经不存在了

非前后端分离的MVC

在这里插入图片描述

前后端分离的MVC

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/174236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内网穿透的应用-Jupyter Notbook+cpolar内网穿透实现公共互联网访问使用数据分析工作

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…

五、Lua流程控制与函数

一、流程控制 &#xff08;一&#xff09;含义 Lua 编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码&#xff0c;在条件为 false 时执行其他指定代码。 &#xff08;二&#xff09;原型 if (成立) then执行体1else执行体2 end…

字符串入门算法题!

概述 字符串和数组一样算是比较简单的题目&#xff0c;正适合打算法基础&#xff0c;一定要认真对待&#xff01;&#xff01;&#xff01; 字符串类型的算法问题可以分为简单、中等和困难的难度级别&#xff0c;基础类型一些基本的字符串处理问题&#xff0c;如字符串的拼接…

自动化部署 扩容openGauss —— Ansible for openGauss

前言 大家好&#xff0c;今天我们为大家推荐一套基于Ansible开发的&#xff0c;自动化部署及扩容openGauss的脚本工具&#xff1a;Ansible for openGauss&#xff08;以下简称 AFO&#xff09;。 通过AFO&#xff0c;我们只需简单修改一些配置文件&#xff0c;即可快速部署多种…

数智赋能 锦江汽车携手苏州金龙打造高质量盛会服务

作为一家老牌客运公司&#xff0c;成立于1956年的上海锦江汽车服务有限公司&#xff08;以下简称锦江汽车&#xff09;&#xff0c;拥有1200多辆大巴和5000多辆轿车&#xff0c;是上海乃至长三角地区规模最大的专业旅游客运公司。面对客运市场的持续萎缩&#xff0c;锦江汽车坚…

王道数据结构课后代码题p19 第14题请设计一个尽可能高效的算法,计算并输出所有可能的三元组(a,b,c) 中的最小距离。(c语言代码实现)

本题其实就是找a到c的最小值 有讲解p19 第14题 c语言实现王道数据结构课后代码题_哔哩哔哩_bilibili 下方有图&#xff1a; 本题代码如下 int abs(int a)//计算绝对值 {if (a < 0)return -a;elsereturn a; } int min(int a, int b, int c)//a是否为三个数中的最小值 {if …

基于xml配置的AOP

目录 xml方式AOP快速入门 xml方式AOP配置详解 xml方式AOP快速入门 xml方式配置AOP的步骤 导入AOP相关坐标 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></de…

二叉树题目:结点与其祖先之间的最大差值

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;结点与其祖先之间的最大差值 出处&#xff1a;1026. 结点与其祖先之间的最大差值 难度 5 级 题目描述 要求 给…

无人售货奶柜:方便快捷,新鲜畅享

无人售货奶柜&#xff1a;方便快捷&#xff0c;新鲜畅享 无人售货奶柜&#xff0c;便捷、多样、实时监控。随时选择您喜爱的奶制品和饮料&#xff0c;快速支付&#xff0c;满足个性口味。24小时全天候运营&#xff0c;无时间限制&#xff0c;随时满足您的购物需求。借助先进的技…

在Rust中编写自动化测试

1.摘要 Rust中的测试函数是用来验证非测试代码是否是按照期望的方式运行的, 测试函数体通常需要执行三种操作:1.设置任何所需的数据或状态;2.运行需要测试的代码;3.断言其结果是我们所期望的。本篇文章主要探讨了Rust自动化测试的几种常见场景。 2.测试函数详解 在Rust项目工…

使用Python编写数独游戏Sudoku教程

数独是各种应用程序中流行的益智类拼图游戏。数独板是一个99的网格&#xff0c;玩家必须在每行、每列和33的子网格中放置一次数字1到9&#xff0c;并且只能放置一次。游戏开始时&#xff0c;有几个空格已经用数字填充&#xff0c;称为givens。一个好的数独谜题应该只有一个可能…

Linux MeterSphere一站式开源持续测试平台远程访问

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…

计算机毕业设计 基于SpringBoot的智能停车场计费系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

linux下的工具---yum

一、什么是yum yum是Linux下的软件包管理器 二、什么是软件包管理器 1、在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 2、但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在…

IDEA中Tomcat启动web项目

1.首先【Run】-->【Edit Configurations】&#xff0c;进入对应功能界面 2.点击左上角【】&#xff0c;选择Tomcat Server -->Local 3.Name输入自己中意的&#xff0c;下面两个port&#xff0c;保证没被占用就行 4.切到【Deployment】页签&#xff0c;点击【】&#xff…

(十三)Flask之特殊装饰器详解

目录&#xff1a; Flask中用作装饰器的特殊的函数第一部分&#xff1a;before_request和after_request一、 before_request装饰器&#xff1a;二、after_request装饰器&#xff1a;三、多个before_request和after_request执行流程分析&#xff1a; 首先—理论讲解&#xff1a;然…

Python3 面向对象

面向对象技术简介 类&#xff08;Class&#xff09;&#xff1a;用来描述具有相同属性的方法和对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法&#xff1a;类中定义的函数类变量&#xff1a;类变量在整个实例化的对象中是公用的。类变量定义在…

微软Azure AI新增Phi、Jais等,40种新大模型

微软在官方宣布在Azure AI云开发平台中&#xff0c;新增了Falcon、Phi、Jais、Code Llama、CLIP、Whisper V3、Stable Diffusion等40个新模型&#xff0c;涵盖文本、图像、代码、语音等内容生成。 开发人员只需要通过API或SDK就能快速将模型集成在应用程序中&#xff0c;同时支…

Java EE 进程线程

JavaEE 进程&线程 文章目录 JavaEE 进程&线程1. 进程1.1 概念1.2 进程管理1.3 PCB (Process Control Block) 2. 线程2.1 概念2.1 线程与进程的区别2.3 创建线程 1. 进程 1.1 概念 什么是进程&#xff1f; 进程是操作系统对一个正在执行的程序的一种抽象 我们可以打开…

Python编程基础

Python是一种简单易学的编程语言&#xff0c;广泛应用于Web开发、数据分析、人工智能等领域。无论您是初学者还是有一定编程经验的人士&#xff0c;都可以从Python的基础知识开始建立自己的编程技能。 目录 理论Python语言的发展程序设计语言的分类静态语言与脚本语言的区别 代…