JavaWeb——Servlet

          • 请求转发是一次转发
          • 请求转发URL地址不会发生变化,会保留当前Servlet的资源访问路径
          • 共享同一个Request作用域,可用于多页面之间传递数据
    • getServletContext()
      • 返回一个ServletContext()对象
    • 获取请求头信息
      • getHeader(String key)根据key获取value
        • 例如 request.getHeader("User-Agent")
      • getHeaderNames()获取所有请求头名称
        • 返回一个Enumeration<String>对象
          • 类似集合迭代器的对象
            • hasMoreElements()
              • 返回boolean值
              • 判断是否有下一个元素
            • nextElement()
              • 返回下一个元素
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();Enumeration<String> headerNames = request.getHeaderNames();out.println("<h2>");//Enumeration是一个类似集合迭代器的对象,可以存放多个数据,需要循环获取每个元素对象while (headerNames.hasMoreElements()) {String head = headerNames.nextElement();out.println( head + "=" + request.getHeader(head) + "<br>");}out.println("</h2>");
}
    • 获取请求网络数据
      • getMethod()
        • 获取网络请求的请求方式
      • getProtocol()
        • 获取网络协议
      • getLocalPort()
        • 获取请求的端口
      • getServletPath()
        • 获取请求资源的路径
        • 如:/servlet
      • getRequestURI()
        • 获取请求的资源路径,包括应用上下文访问路径+请求的资源路径
        • 应用上下文访问路径/请求资源的路径
        • /web01/servlet
      • getRequestURL()
        • 获取请求的URL(SetvletURL)
        • 协议+ip+端口+应用上下文访问路径+请求资源的路径
        • http://localhost:8080/web01/servlet
      • getContextPath()
        • 获取应用上下文访问路径
        • /web01
        • 在请求资源路径之前动态获取应用上下文访问路径,避免因为应用上下文访问路径问题导致资源无法访问
          • <a href = "<%=request.getContextPath()%>/servlet">超链接</a>
//获取请求方式
String method = request.getMethod();
out.println("请求方式 =" + method + "<br>");//请求方式 =GET
//获取请求协议
String protocol = request.getProtocol();
out.println("请求协议 =" + protocol + "<br>");//请求协议 =HTTP/1.1
//获取请求资源的路径
String servletPath = request.getServletPath();
out.println("servletPath = " + servletPath + "<br>");//servletPath = /servlet
//获取请求URI 包括应用上下文对象+请求的资源路径
String requestURI = request.getRequestURI();
out.println("URI =" + requestURI + "<br>");//URI =/web01/servlet
//获取请求URL地址栏完整路径 包括 协议+ip+端口+应用上下文访问路径+请求的资源路径
StringBuffer requestURL = request.getRequestURL();
out.println("URL =" + requestURL + "<br>");//URL =http://localhost:8080/web01/servlet
//获取请求的应用上下文访问路径
String contextPath = request.getContextPath();
out.println("contextPath = " + contextPath);//contextPath = /web01

HttpServletResponse用户响应对象

  • 常用方法
    • setCharacterEncoding(String charSet)设置输出编码格式
      • 传入一个String类型的编码格式
    • setContextType("text/html;charset=UTF-8")
      • 设置响应数据的数据类型为html字符串,编码格式为UTF-8
    • getWriter() 返回一个Writer类型的字符输出流对象,利用该对象可以向页面输出文本或Html
      • 不推荐Servlet中进行数据输出,Servlet主要负责逻辑处理
    • setContentLength()
      • 设置响应时的响应数据大小
    • 设置响应头
      • 不支持中文
      • setHeader(String key,String value)
      • setDateHeader(String key,Date value)
      • setIntHeader(String key,int value)
    • sendRedirect(String url)重定向
      • 可以跳转到某url
      • 重定向是2次请求,地址栏会保留重定向的资源地址,不会共享同一个Request Scope(请求作用域)
      • 可以写uri,但是可能会出问题,建议使用url

请求转发与重定向

  • 区别
    • 转发地址栏不变,转发请求1次,转发时不写工程虚拟路径
      • 地址栏不变可防止重复发送请求
    • 重定向地址栏变化,请求2次,重定向要写工程虚拟路径
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//请求转发request.getRequestDispatcher("/servlet03");
}@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//重定向resp.sendRedirect(req.getContextPath() + "/servlet03");
}
  • 应用场景
    • 重定向
      • 登录、购物车结算
    • 请求转发
      • 其余
  • setHeader("Content-Disposition","attachment;filename=" + file.getName())
    • 设置响应头,请求以下载的方式处理,以及下载文件时的默认文件名称
  • response.setContentLength((int)file.length());
    • 设置响应时的响应数据大小(利用文件大小设置)
  • Servlet与JSP的跳转
    • jsp跳Servlet
      • a标签
      • js(location.href='xxx')
      • form表单action属性
    • Servlet跳jsp
      • 重定向:response.sendRedirect(String url)
      • 请求转发: request.getRequestDispatcher(String uri).forward(request,response)
    • servlet跳servlet
      • 推荐重定向

下载功能的实现

    @Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置响应输出编码格式,避免文件名中文乱码response.setContentType("text/html;charset=UTF-8");//获取输入流//获取响应输出流BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());File file =new  File(request.getServletContext().getRealPath("/images/img.png"));//获取输入流BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));//设置响应头,请求以下载的方式处理,以及下载文件时的默认文件名称response.setHeader("Content-Disposition","attachment;filename=" + file.getName());//设置响应时的响应数据大小(利用文件大小设置)response.setContentLength((int)file.length());byte[] bytes = new byte[1024];int length = 0;while ((length = bis.read(bytes)) != -1) {bos.write(bytes, 0,length);}//刷新缓存,数据推送bos.flush();}

图片验证码的实现

  • 引入的包
    • Hutool
<!--hutool工具类-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version>
</dependency>
  • 后端
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//定义图形验证码的父接口ICaptcha lineCaptcha = null;/**创建一个图形验证码对象* param1:宽度* param2:高度* param3:字符数量* param4:干扰线条数量*/lineCaptcha = new LineCaptcha(200,80,5,3);//验证码生成lineCaptcha.createCode();//获取验证码信息//后期我们应该将这个数据存入Session或其他某些其他容器中等待与用户输入的验证码校验String code = lineCaptcha.getCode();//使用输出流输出验证码图片到浏览器response.setContentType("text/html;UTF-8");ServletOutputStream sos = response.getOutputStream();lineCaptcha.write(sos);sos.close();
}
  • 前端

<body>
<form method="post" action="servlet">用户名:<input type="text" name="username"><br>密&nbsp;&nbsp;码&nbsp;:<input type="password" name="pw"><br>验证码:<%--利用JSP脚本表达式,在请求资源路径之前通过动态获取应用上下文对象,避免通过应用上下文对象访问路径问题导致资源无法访问--%><a id="reset" href="javascript:void(0)"><img src="<%= request.getContextPath() %>/servlet"  id="myImg"><br>看不清,换一张</a><input type="submit" value="get">
</form></body>
<script type="text/javascript">window.onload = function () {document.getElementById("reset").addEventListener("click",function () {//添加单击事件修改img路径,但是链接必须发生变化,因此使用时间戳          document.getElementById("myImg").src = "<%= request.getContextPath() %>/servlet?timeStemp=" + new Date().getTime()})}
/*    var reset = function() {}*/
</script>
  • 细节:
    • get请求重新执行要求链接不同,可通过添加时间戳实现

ServletConfig 初始化参数对象

  • 常用方法
    • getInitParameter(String key)
      • 获取xml文件或注解中的初始化参数,返回String
  • 在非init方法中取得ServletConfig对象
    • this.getServletConfig()

ServletContext

  • 常用方法
    • getRealPath(String uri)
      • 获取uri指向资源的绝对路径
        • servletContext().getRealPath("/")
          • 获取根目录真实路径
        • servletContext().getRealPath("/images/img.png")
          • 获取根目录下/images/img.png文件的真实目录

生命周期

  • 注意:
    • 单例模式,整个Tomcat生命周期中,每个Servlet只会被创建一次

a. init()初始化

    • Servlet对象创建完成后被调用,因为Servlet是单例的,所以整个Tomcat生命周期中只会被调用一次
    • 可与初始化参数配合使用,为Servlet类添加成员变量
    • 必须调用super.init(),否则无法为当前类中的init()属性进行赋值,无法调用init方法以外的其他方法获取config对象
    @Overridepublic void init(ServletConfig config) throws ServletException {//调用super.init(config)当前类中的config属性赋值super.init(config);name = config.getInitParameter("name");age = config.getInitParameter("age");}

b. service()请求进入时

    • 每次请求进入Servlet都会执行一次这个方法,用于分析请求是get还是post,根据请求方式帮助我们调用doGet或doPost方法
    • 注意:必须利用super调用父类中的service方法,否则不会进入doGet或doPost()

c. destroy()销毁

    • Servlet销毁时执行,,因为Servlet是单例的,所以整个Tomcat生命周期中只会被调用一次
    • Servlet销毁的时机是Tomcat容器关闭时,用于释放一些资源

d. 初始化参数

ⅰ. 基于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><servlet-name>servelet</servlet-name><servlet-class>com.wry.servlet.Servlet</servlet-class><init-param><param-name>i</param-name><param-value>1</param-value></init-param><init-param><param-name>j</param-name><param-value>100</param-value></init-param></servlet><servlet-mapping><servlet-name>servelet</servlet-name><url-pattern>/servlet</url-pattern></servlet-mapping>
</web-app>
ⅱ. 取得初始化参数的值
  • 通过成员变量共享属性值
    • Servlet的init方法只会执行一次,Servlet是单例的。非线程安全的,当出现并发访问,共享数据无法保证一致性.在使用Servlet不要定义共享成员变量.
public class Servlet extends HttpServlet {private String name;private String age;@Overridepublic void init(ServletConfig config) throws ServletException {name = config.getInitParameter("name");age = config.getInitParameter("age");}
}
  • 通过在方法中获取ServletConfig对象获取初始化参数的值
    • 必须在init()方法中调用super.init(config),否则GennericServlet类中的config属性为null,无法获取到ServletConig对象
    • 利用这种方法,既可以获取初始化参数,又可以避免线程安全问题
public class Servlet extends HttpServlet {@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);}/*** 用于处理get请求* @param request* @param response* @throws ServletException* @throws IOException*/@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setCharacterEncoding("UTF-8");//利用用户响应对象获取输出流PrintWriter out = response.getWriter();out.print(("<h1>收到一个get请求</h1>"));//获取ServletConfig对象ServletConfig config = this.getServletConfig();//获取name属性值String name1 = config.getInitParameter("name");out.println(name1);}
}
ⅲ. 设置Servlet值的初始化时机
  • 通过<Servlet>中的<load-on-startup>标签指定创建实值
    • 只要该标签值大于等于1即可在Tomcat启动时创建Servlet对象
    • 如果有多个Servlet需要在启动时创建,可以利用这个数值决定创建顺序,如果数值相同则按照名称排序决定加载顺序
  • 如果是基于注解配置Servlet则需要在@WebServlet注解中指定loadOnStartup来指定Servlet创建时机值,取值为整数类型
<servlet><servlet-name>servelet</servlet-name><servlet-class>com.wry.servlet.Servlet</servlet-class><init-param><param-name>name</param-name><param-value>Zhangsan</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>

  • JSP和Servlet的对比

Servlet中虽然可以写标签、css样式等,但使用起来没有在jsp或者html中书写方便。JSP可以做的事情,Servlet同样可以完成,只不过两者侧重点不同:JSP多用于数据展示,Servlet多用于逻辑控制。

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

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

相关文章

Element UI el-dialog自由拖动功能

1.创建drag .js文件 /*** 拖拽移动* param {elementObjct} bar 鼠标点击控制拖拽的元素* param {elementObjct} target 移动的元素* param {function} callback 移动后的回调*/ export function startDrag(bar, target, callback) {var params {top: 0,left: 0,currentX: …

学习资料记录

http://interview.wzcu.com/Golang/%E4%BB%A3%E7%A0%81%E8%80%83%E9%A2%98.html map底层 https://zhuanlan.zhihu.com/p/616979764 go修养 https://www.yuque.com/aceld/golang/ga6pb1#4b19dba5 https://golang.dbwu.tech/performance/map_pre_alloc/ https://juejin.cn/pos…

C++11新特性:sizeof... 运算符

在 C11 及其后续版本中&#xff0c;引入了一项新的语言特性——sizeof...运算符&#xff0c;这是一个与模板编程紧密相关的特性。 你没看错&#xff0c;sizeof 后面是三个点&#xff1a;sizeof... sizeof...运算符用于计算变参模板&#xff08;variadic template&#xff09;…

考研数学基础差,跟宋浩?

宋浩老师的课程我大一的时候听过&#xff0c;是我大一高数的救命恩人&#xff01; 不过&#xff0c;考研的针对性很强&#xff0c;基础差听宋浩老师的课程不如直接听汤家凤老师的课程&#xff0c;因为汤家凤老师的课程是专门为考研数学设计的&#xff0c;针对性很强。 汤家凤老…

K8S之DaemonSet控制器

DaemonSet控制器 概念、原理解读、应用场景概述工作原理典型的应用场景介绍DaemonSet 与 Deployment 的区别 解读资源清单文件实践案例 概念、原理解读、应用场景 概述 DaemonSet控制器能够确保K8S集群所有的节点都分别运行一个相同的pod副本&#xff1b; 当集群中增加node节…

Django之Celery篇(一)

一、介绍 Celery是由Python开发、简单、灵活、可靠的分布式任务队列,是一个处理异步任务的框架,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。 Celery侧重于实时操作,但对调度支持也很好,其每天可以处理数以百万计的任务。特点: 简单:熟悉…

监控系统Prometheus--入门

文章目录 Prometheus特点易于管理监控服务的内部运行状态强大的数据模型强大的查询语言PromQL高效可扩展易于集成可视化开放性 Prometheus架构Prometheus 生态圈组件架构理解 Prometheus的安装安装Prometheus Server上传安装包解压安装包修改配置文件 prometheus.yml 安装Pushg…

Halcon 3D 平面拟合(区域采样、Z值过滤、平面拟合、平面移动)

Halcon 3D 平面拟合(区域采样、Z值过滤、平面拟合、平面移动) 链接:https://pan.baidu.com/s/1UfFyZ6y-EFq9jy0T_DTJGA 提取码:ewdi * 1.读取图片 ****************

ThreadLocal的主要特点:

ThreadLocal的主要特点&#xff1a; ThreadLocal是Java中的一个类&#xff0c;它提供了线程局部变量的实现机制。ThreadLocal的实例可以为每个使用该变量的线程提供单独的变量副本&#xff0c;每个线程可以独立地改变自己的副本&#xff0c;而不会影响其他线程的副本。这种机制…

面试问答:能聊一聊MySQL聚簇索引和非聚簇索引吗?

文章目录 &#x1f412;个人主页&#xff1a;信计2102罗铠威&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;啥叫聚簇索引和非聚簇索引&#xff1f;&#x1f415;如果按特点来说&#xff1a;&#x1f415;如果按存储引擎来说&#xff1a; &#x1f415…

【CSS】实现文字描边

通过 -webkit-text-stroke 即可实现文字描边&#xff0c;这个复合属性接收两个参数&#xff0c;分别为描边宽度&#xff0c;以及描边颜色。 需要注意的是&#xff0c;-webkit-text-stroke是一个非标准属性&#xff0c;兼容性会出现问题。 <!DOCTYPE html> <html lang…

安卓Java面试题 196- 200

196. 简述Android Window的更新过程 ?说到Window的更新过程,个人认为其实也就是Window里面View的更新过程了,和创建/删除过程一样,最后照样也是到了WindowManagerGlobal里 面执行具体的操作了,具体来讲的话就是执行updateViewLayout方法了, 这个方法里面做了以下几件事:…

What is case-based reasoning (CBR)? 基于案例的推理

这个方向其实挺小众的&#xff0c;然后其实也很直觉&#xff0c;所以你可能其实一直在用这个技术&#xff0c;只不过你不知道这个技术有一个专业的名字《基于案例的推理》而已。 有人说&#xff0c;不知道名字有啥的&#xff0c;反正大家都会用&#xff0c;不需要学它叫什么名…

数组三(冒泡排序、二分查找)

目录 冒泡排序算法 冒泡排序的基础算法 冒泡排序的优化算法 二分法查找 冒泡排序算法 冒泡排序是最常用的排序算法&#xff0c;在笔试中也非常常见&#xff0c;能手写出冒泡排序算法可以说是 基本的素养。 冒泡排序的基础算法 冒泡排序算法重复地走访过要排序的数列&#…

eUICC鉴权的一般步骤

eUICC&#xff08;嵌入式通用集成电路卡&#xff09;的鉴权过程涉及多个步骤&#xff0c;主要目的是确保eUICC的安全操作和用户的身份验证。以下是eUICC鉴权过程的一般步骤&#xff1a; 1. **初始化**&#xff1a;当用户启动设备或尝试连接到移动网络时&#xff0c;eUICC会开始…

2024-03-22 问AI: 介绍一下深度学习中的 sigmoid函数

文心一言 Sigmoid函数是深度学习中常用的一种激活函数&#xff0c;主要用于将神经元的输出值压缩到0和1之间。这种特性使得sigmoid函数在二分类问题中特别有用&#xff0c;因为输出值可以被解释为属于某个类别的概率。 sigmoid函数的数学表达式为&#xff1a; σ(x) 1 / (1…

Pytorch CUDA Reflect Padding 算子实现详解

CUDA 简介 CUDA&#xff08;Compute Unified Device Architecture&#xff09;是由NVIDIA开发的一种并行计算平台和应用编程接口&#xff08;API&#xff09;&#xff0c;允许软件开发者和软件工程师使用NVIDIA的图形处理单元&#xff08;GPU&#xff09;进行通用计算。自2007…

为什么守护网络安全需要用高防IP

在数字化浪潮中&#xff0c;网络安全问题日益凸显&#xff0c;网络攻击事件频发&#xff0c;给企业的业务发展带来了严重威胁。面对这一挑战&#xff0c;高防IP应运而生&#xff0c;以其强大的防护能力和稳定的性能&#xff0c;成为企业网络安全的重要守护神。 高防IP&#xf…

NodeJS 集群模块: 为App创建集群实例

NodeJS 集群模块: 为App创建集群实例 目录 NodeJS 集群模块: 为App创建集群实例Node.js 集群介绍:终极扩展策略使用集群模块开始扩展 Node.js扩展 Node.js 的两种集群策略使用集群受益的 Node.js 应用程序示例没有集群的 Node.js:不可伸缩的原则集群操作:一个扩展的 Node.js…

Redis 配置与优化

目录 一、Redis 介绍 1.1、关系数据库与非关系型数据库 1&#xff09;关系型数据库 2&#xff09;非关系型数据库 3&#xff09;非关系型数据库产生背景 1.2、Redis 基础 1&#xff09;Redis 简介 2&#xff09;Redis 安装部署 3&#xff09;配置参数 1.3、Redi…