javaEE初阶—Servlet

javaEE初阶—ServletJavaServlet 是运行在 Web 服务器或应用服务器上的程序 它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层

大家好,欢迎来到IT知识分享网。

一 : Servlet的定义

Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app. 

Java Servlet 是运行在 Web服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页 .

Servlet用于开发动态页面 , 根据用户输入内容的不同 , 来返回出不同的页面结果 .

什么是动态页面 , 什么是静态页面呢 ?

  • 静态页面也就是内容始终固定的页面. 即使用户不同/时间不同/输入的参数不同 , 页面内容也不会发生 ;
    变化. (除非网站的开发人员修改源代码, 否则页面内容始终不变).
  • 动态页面指的就是 用户不同/时间不同/输入的参数不同, 页面内容会发生变化 .

在这里插入图片描述

在这里插入图片描述

二 : Servlet的任务

  1. 允许程序猿注册一个类, 在 Tomcat 收到某个特定的 HTTP 请求的时候, 执行这个类中的一些代码.
  2. 帮助程序猿解析 HTTP 请求, 把 HTTP 请求从一个字符串解析成一个 HttpRequest 对象.
  3. 帮助程序猿构造 HTTP 响应. 程序猿只要给指定的 HttpResponse 对象填写一些属性字段, Servlet就会自动安装 HTTP 协议的方式构造出一个 HTTP 响应字符串, 并通过 Socket 写回给客户端.
  4. 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
  5. 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

三 : 写一个简单的Servlet程序

一共需要七大步骤 . 

2.1创建项目

在这里插入图片描述

maven叫做”构建工具” , 针对代码进行依赖管理 , 编译 , 打包 , 验证 , 部署等功能 , 可以视为是针对复杂项目进行管理的一个解决方案 .

maven自身的功能是很多的 , 我们主要使用 :

  1. 管理依赖 : 想使用某个第三方库,就使用maven把这个库下载下来并导入到项目中 .
  2. 打包 : 把代码编译好,把.class 文件打成压缩包(.jar 或者.war) .

在这里插入图片描述

2.2 引入依赖

此处谈到的依赖 , 是编写Servlet程序所需要的依赖(Servlet的jar包) , 需要把这个jar下载导入到项目中 .

下载步骤 :

  1. 打开 Maven的中央仓库
  2. 找到我们所需要的内容 :

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 把这段文字 , 粘贴到pom.xml里面 .

在这里插入图片描述
注意 : 首次使用 , 会标红 , 这是因为在首次使用时 , maven会从中央视仓库下载对应的jar包 , 这需要一定的时间 . 你也可是点击刷新 , 主动触发下载 !

在这里插入图片描述
在这里插入图片描述

2.3 创建目录

在这里插入图片描述
将下面的内容复制粘贴到web.xml中 .

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app> 

webapp 目录就是未来部署到 Tomcat 中的一个重要的目录. 当前我们可以往 webapp 中放一些静态资源, 比如 html , css 等.

在这个目录中还有一个重要的文件 web.xml. Tomcat 找到这个文件才能正确处理 webapp 中的动态资源.

2.4编写代码

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("/hello") public class HelloServet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("hello world"); resp.getWriter().write("hello world"); } } 

在这里插入图片描述

doGet()方法不是咱们自己手动调用的 , 而是Tomcat自动调用的 , Tomcat 会自动的识别出合适的时机,来自动调用doGet方法 , —定是通过GET请求触发的!!! doGet做的工作,就是Tomcat收到请求之后,到返回响应之前,中间的过程 !

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


@WebServlet属于类级别的注解,标注在继承了 HttpServlet 的类之上。常用的写法是将 Servlet 的相对请求路径(即 value)直接写在注解内 .

上述代码没有main方法 , 不能单独执行,main方法在Tomcat内 , 上述代码需要部署到Tomcat中,由Tomcat进行调用.main好比汽车的发动机 , 我们写的Servlet代码就是车厢 . 只有个车头 , 可以自己跑 ; 但是车厢直接不能跑 , 得挂在车头上 .

在这里插入图片描述

2.5 打包

借助maven , 一键式完成 ! 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再次双击package进行打包 !



在这里插入图片描述

2.6 部署

把刚才得到的war包 , 拷贝到Tomcat的webapps目录中 ! 

在这里插入图片描述

2.7 验证

让浏览器构造一个HTTP Get请求 ! 

在这里插入图片描述
注意目录结构:
在这里插入图片描述

总结 :

在这里插入图片描述

注意 : Spring Boot可以简化这里的流程 , 现在先介绍一种中间的方案 , 即借助IDEA中的一个插件 , Smart Tomcat , 来简化打包和部署 .

在这里插入图片描述
在这里插入图片描述

smart tomcat不是tomcat , 其功能就是能够在IDEA中调用tomcat , 我们就无需手动双击tomcat的启动脚本来运行 , 而是直接在IDEA中一点就能运行tomcat了 .

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击运行, 会在IDEA中显示tomcat的日志 .


在这里插入图片描述

此处中文也不再乱码了 !

在这里插入图片描述

smart tomcat的工作原理 , 和前面的手动拷贝部署不太一样 , 是让tomcat直接加载了我们代码中的webapp目录 , 这时候就跳过了打包 + 拷贝的过程 , 但是也起到了部署的效果 !

常见错误集合 :

  1. 404 : 大概率是URL写错了 , 也可能是webapp未正确加载(比如web.xml写错了) .
  2. 405 : method not allowed , 发送GET请求但未实现doGet() , 或实现了doGet() , 但未把super.doGet这个代码删掉 ;
  3. 505 : 服务器内部错误 , 即服务器挂了 , 这说明你的代码中抛出了异常 .
  4. 返回空白页面 , 大概率是未执行write()方法 .
  5. 无法访问此网站 , 大概率是tomcat没有正确启动 .

Tomcat 的定位

上面的实现是在tomcat的基础上实现的 .

HTTP 协议作为一个应用层协议, 需要底层协议栈来支持工作. 如下图所示 :

在这里插入图片描述
更详细的交互过程见下图 :

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四 : Servlet API 详解

重点关注三个类 ! 

在这里插入图片描述

4.1HttpServlet

4.1.1核心方法

在这里插入图片描述

  • init只会在该Servlet类第一次被使用的时候调用到 , 相当于是用来初始化 ;
  • destroy是在Servlet对象被销毁的时候才会调用到 , 仅调用一次 , 相当于收尾工作 . 这个方法不一定能执行到 , 仅在tomcat是通过8005端口进行关闭时会执行destroy , 如果是直接杀死tomcat进程 , 则不会调用 .
  • service在每次收到请求(无论什么方法)时都会调用到service , 默认父类的service里面就会根据方法调用doGet/doPost .

最常用的 : doXXX系列!!!

这些方法的调用时机, 就称为 “Servlet 生命周期”. (也就是描述了一个 Servlet 实例从生到死的过程).

在这里插入图片描述

4.1.2构造POST请求

前面我们通过在浏览器里输入url构造了GET请求 , 那POST请求该如何构造呢 ?

form可以支持get和post , 在此处我们可以使用ajax .

在这里插入图片描述
在这里插入图片描述

加载 : jQuery

在这里插入图片描述

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("/hello") public class HelloServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doGet!"); resp.getWriter().write("doGet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doPost!"); resp.getWriter().write("doPost!"); } } 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <script> $.ajax({ 
      type:'post', url:'hello', //url:'/hello_servlet/hello', success:function(body){ 
      console.log(body); } }); </script> </body> </html> 

在这里插入图片描述

此处我们只在控制台看到了响应 , 在控制台打印了”doPost!” , 这是因为ajax拿到的响应数据,是根据回调函数的方法处理的 , 可以显示 , 也可以不显示 ; 而直接通过浏览器输入url得到的响应内容是直接被浏览器渲染到页面上的 .

路径问题

如何把内容打印到页面上呢 ?

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("/hello") public class HelloServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doGet!"); resp.getWriter().write("doGet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doPost!"); resp.getWriter().write("doPost!"); } } 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .one{ 
      font-size: 50px; color: aqua; } </style> </head> <body> <div class="one"></div> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <script> $.ajax({ 
      type:'post', url:'hello', success:function(body){ 
      //console.log(body); let div = document.querySelector('.one'); div.innerHTML = body; } }); </script> </body> </html> 

在这里插入图片描述

根据当前的请求”doPost” , 决定调用我们自己代码中的doGet方法!!!

在进行这部分操作时 , 一开始出现了下面的问题 , 显示报错信息为 :

无法在地址[localhost]和端口[8005]上创建服务器关闭套接字(基本端口[8005]和偏移量[0]).

经过查阅资料 , 发现这是端口占用导致的问题 . 解决方案如下 :

  1. 查看端口占用
    在windows命令行窗口下执行:netstat -aon|findstr “8080”

在这里插入图片描述
端口“8080”被PID(进程号)为16160的进程占用 .

  1. 查看端口“8080”被哪个应用占用,,继续执行下面命令:tasklist|findstr “16160”

在这里插入图片描述

3.关闭进程(此处按进程名关闭进程) : taskkill /im java.exe

在这里插入图片描述

扩展 : 关闭进程的方式 :

  1. 按进程号关闭进程 taskkill /pid 2152
    多个时格式为:taskkill /pid 2152 /pid 1284 / …
  2. 按进程名关闭进程 如要关闭notepad.exe,格式为:taskkill /im notepad.exe
    指定多个时格式为:taskkill /im notepad.exe /im iexplorer.exe / im…
    如果是要关闭所有的,则使用通配符*,即:taskkill /im *.exe

  3. 有提示的关闭进程 taskkill /t /im notepad.exe
    taskkill /t /pid 2152
    这个效果是提示后在使用者确定后关闭,有提示框。

  4. 强行终止进程 taskkill /f /im notepad.exe
    taskkill /f /pid 2152

被拒绝时 , 尝试使用命令行 taskkill /f /t /im java.exe,可以关闭,亲测可用 .

通过按钮触发ajax请求的发送 :

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("/hello") public class HelloServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doGet!"); resp.getWriter().write("doGet!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doPost!"); resp.getWriter().write("doPost!"); } @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doPut!"); resp.getWriter().write("doPut!"); } @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    System.out.println("doDelete!"); resp.getWriter().write("doDelete!"); } } 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .one{ 
      font-size: 50px; color: aqua; } </style> </head> <body> <div class="one"></div> <button id="doGet">get</button> <button id="doPost">post</button> <button id="doPut">put</button> <button id="doDelete">delete</button> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <script> let doGetBtn = document.querySelector('#doGet'); doGetBtn.onclick = function(){ 
      $.ajax({ 
      type:'get', url:'hello', success:function(body){ 
      let div = document.querySelector('.one'); div.innerHTML = body; } }); } let doPostBtn = document.querySelector('#doPost'); doPostBtn.onclick = function(){ 
      $.ajax({ 
      type:'post', url:'hello', success:function(body){ 
      //console.log(body); let div = document.querySelector('.one'); div.innerHTML = body; } }); } let doPutBtn = document.querySelector('#doPut'); doPutBtn.onclick = function(){ 
      $.ajax({ 
      type:'put', url:'hello', success:function(body){ 
      //console.log(body); let div = document.querySelector('.one'); div.innerHTML = body; } }); } let doDeleteBtn = document.querySelector('#doDelete'); doDeleteBtn.onclick = function(){ 
      $.ajax({ 
      type:'delete', url:'hello', success:function(body){ 
      //console.log(body); let div = document.querySelector('.one'); div.innerHTML = body; } }); } </script> </body> </html> 

在这里插入图片描述

注意文件位置 :

在这里插入图片描述

Q : 当前使用ajax构造出了上述几种请求.但是还是比较麻烦.毕竟要写代码 . 是否有办法,不写代码,也能构造出任意的http请求呢?

A : 此处还可以使用第三方工具,来构造HTTP请求. (类似功能的工具种类繁多),咱们在工作中一个非常常用的,叫做 PostMan(各种请求都能构造 , 真香) . Postman本来是chrome的一个插件.现在已经是独立的程序了 . 可以去官网下载安装 !

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
简单演示用法 :

在这里插入图片描述

在这里插入图片描述

Q : 面试题 : 谈谈HttpServlet的生命周期 ?

A :

  1. 首次使用 , 先调用一次init ;
  2. 每次收到请求 , 调用service , 在service内部通过具体方法来决定调用哪个doXXX代码 ;
  3. 销毁之前调用destroy .

4.2 HttpServletRequest

在这里插入图片描述

这个类就提供了一组方法 , 让我们能够获取到HTTP请求中的这些信息 .

4.2.1 核心方法

在这里插入图片描述
在这里插入图片描述

4.2.2实例

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.util.Enumeration; @WebServlet("/requestServlet") public class RequestServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append(req.getProtocol());//返回请求协议的名称和版本 stringBuilder.append("<br>"); stringBuilder.append(req.getMethod());//返回请求的HTTP方法的名称 stringBuilder.append("<br>"); stringBuilder.append(req.getRequestURI());//返回请求的URL的一部分 stringBuilder.append("<br>"); stringBuilder.append(req.getQueryString());//返回包含在路径后的请求URL中的查询字符串 stringBuilder.append("<br>"); Enumeration<String> headersnames = req.getHeaderNames(); while(headersnames.hasMoreElements()){ 
    String name = headersnames.nextElement(); stringBuilder.append(name+":"+req.getHeader(name)); stringBuilder.append("<br>"); } //设置Content Type resp.setContentType("test/html;charset=utf8"); resp.getWriter().write(stringBuilder.toString()); } } 

在这里插入图片描述

更多的情况下 , 需要通过API拿到请求中传来的必要的参数 !!! 假如教务系统上 , 需要获取某个同学的信息 , 给服务器发个请求 :

 /studentInfo?classId=368&studentId=20 

此时服务器就需要知道传过来的信息是什么 .

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; class Student{ 
    public int classId; public int studentId; } @WebServlet("/studentInfo") public class StudentInofoServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    // 假设客户端发来的请求形如 /studentInfo?classId=368&studentId=20 // 就可以通过 getParameter 方法来拿到这两个 id 的值. resp.setContentType("text/html,charset=utf8"); String queryString = req.getQueryString(); System.out.println(queryString); String classId = req.getParameter("classId"); String studentId = req.getParameter("studentId"); System.out.println("classId: " + classId + "studentId: " + studentId); resp.getWriter().write("classId: " + classId + "studentId: " + studentId); } } 

在这里插入图片描述

在这里插入图片描述

getParameter的效果就是拿到query string中的键值对 , 根据key获取value(key和value都是String类型的) .

前端除了通过query string来传参 , 还有其他的传参方式 , 比如可以通过post请求 , 通过body来传参到服务器 .

在这里插入图片描述

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.util.function.DoublePredicate; class Student{ 
    public int classId; public int studentId; } @WebServlet("/studentInfo") public class StudentInofoServlet extends HttpServlet { 
    @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    // 约定 body 使用 application/x-www-form-urlencoded 这种格式来传参. // 这个格式就形如 classId=368&studentId=05 // 这个格式和 query string 相同!!! 只是数据是在 body 中! // 针对这种格式, 获取到值的方式, 仍然是 getParameter !!!! resp.setContentType("text/html,charset=utf8"); String queryString = req.getQueryString(); System.out.println(queryString); String classId = req.getParameter("classId"); String studentId = req.getParameter("studentId"); System.out.println("classId: " + classId + " studentId: " + studentId); resp.getWriter().write("classId: " + classId + " studentId: " + studentId); } } 

通过Postman构造POST请求 :

在这里插入图片描述

使用Fiddler抓包的结果 :

在这里插入图片描述
还可以通过form构造请求 :

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>通过form构造请求</title> </head> <body> <form action="studentInfo" method="post"> <input type="text" name="classId"> <input type="text" name="studentId"> <input type="submit" name="提交"> </form> </body> </html> 

在这里插入图片描述
如果 POST 请求中的 body 是按照 JSON 的格式来传递, 那么获取参数的代码就要发生调整.

在这里插入图片描述
结果是这样的 :

在这里插入图片描述
显然我们没法正确解析 .

如果我们自己写代码按照字符串解析的方式获取到这里的键值对 , 是很费劲的 , 所以我们选择使用第三方库 . Java世界中有很多处理Json的第三方库 , 此处我们使用Jackson . (Spring官方推荐使用且内部集成了) .

打开 maven中央仓库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将依赖下载到本地 : (点击刷新)

在这里插入图片描述
在这里插入图片描述

此时 , maven就把这个库给下载到了本地 .

在这里插入图片描述

对于jackson , 只需要掌握两个操作 :

  • 把json格式的字符串转化为Java对象 ;
  • 把Java对象转成json字符串 .

对应到一个类ObjectMapper .

import com.fasterxml.jackson.databind.ObjectMapper; 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.util.function.DoublePredicate; class Student{ 
    public int classId; public int studentId; } @WebServlet("/studentInfo") public class StudentInofoServlet extends HttpServlet { 
    @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    //处理json格式的请求 ObjectMapper objectMapper = new ObjectMapper(); //使用readValue把json字符串转成Java对象 Student student = objectMapper.readValue(req.getInputStream(),Student.class); System.out.println(student.classId+","+student.studentId); resp.getWriter().write(student.classId+","+student.studentId); } } 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

加入json中的key和类里的属性不一致, 会发生什么?

在这里插入图片描述

此时出现内部服务器错误 .

4.3 HttpServletResponse

4.3.1 核心方法

在这里插入图片描述

注意 : Request是get系列的方法, Response则是一些set系列的方法. 

在这里插入图片描述
简单演示上述API :

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("/status") public class StatusCodeServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    //设置相应的状态码 resp.setStatus(500); } } 

在这里插入图片描述

代码示例 : 自动刷新

给响应报文header设置Refresh属性 , 跟上的value表示让浏览N秒之后刷新 .

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("/refresh") public class RefreshServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setHeader("Refresh","1"); resp.getWriter().write(System.currentTimeMillis()+""); } } 

在这里插入图片描述
显示时间戳, 每隔1秒刷新一次 .

实际运用: 文字直播 .

在这里插入图片描述

代码示例: 重定向

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("/redirect") public class RedirectServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setStatus(302);//3xx表示重定向, 默认用302 resp.setHeader("Location","https://www.baidu.com"); /* 另一种简单的写法 resp.sendRedirect("https://www.baidu.com"); */ } } 

在这里插入图片描述

五 :应用—留言板

效果回顾 :

在这里插入图片描述

当前这些数据只是在浏览器的内存中保存着 , 一旦浏览器重启或刷新页面 , 数据就消失了 .

解决方案就是把数据保存在服务器上 .

5.1准备工作

  1. 创建好项目 ;
  2. 构建好目录 ;
  3. 引入依赖 ;
  4. 把留言板项目拷贝到项目中 .

在这里插入图片描述
这个html应该放在webapp目录下 .

此时我们就可以换一种打开方式了 .

javaEE初阶---Servlet

5.2 约定好前后端交换的接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.3 实现提交数据

在这里插入图片描述

编写前端请求代码(第3部分)

 //5.[新步骤]需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器! let messageJson = { 
    "from" : from, "to" : to, "message" : message }; $.ajax({ 
    type:"post", url:'message',//或者写url='/MessageWall/message' contentType:"application/json;charset=utf8", data:JSON.stringify(messageJson), success:function(body){ 
    alert("提交成功!"); }, error:function(){ 
   //在服务器返回的状态码不是2xx时触发这个error alert("提交失败!"); } }); 

在这里插入图片描述

整体代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>留言板</title> <style> * { 
      padding: 0; margin: 0; box-sizing: border-box; } .container { 
      width : 800px; margin : 10 px auto; } .container h2 { 
      text-align: center; margin: 30px 0px; } .row { 
      height: 50px; display: flex; justify-content: center; margin-top: 5px; line-height: 50px; } .row span { 
      height: 50px; width: 100px; line-height: 50px; } .row input { 
      height: 50px; width: 300px; line-height: 40px; font-size: 30px; color: cadetblue; } .row button { 
      width: 400px; height: 50px; color: #000; background-color: aquamarine; border: none; border-radius: 10px; } .row button:active { 
      background-color: grey; } </style> </head> <body> <!--这是一个顶层容器,放其他元素--> <div class="container"> <h2>留言板</h2> <div class="row"> <span></span> <input type="text" id="from"> </div> <div class="row"> <span>对谁</span> <input type="text" id="to"> </div> <div class="row"> <span>说什么</span> <input type="text" id="message"> </div> <div class="row"> <button>提交</button> </div> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <script> let container = document.querySelector('.container'); let fromInput = document.querySelector('#from'); let toInput = document.querySelector('#to'); let messageInput = document.querySelector('#message'); let button = document.querySelector('button'); button.onclick = function() { 
      //1.把用户输入的内容获取到 let from = fromInput.value; let to = toInput.value; let message = messageInput.value; if(from == '' || to == '' || message == ''){ 
      return; } //2.构造一个div,把这个div插入到.container的末尾 let newDiv = document.createElement('div'); newDiv.className = 'row'; newDiv.innerHTML = from + "对" + to + "说" + message; //3.把div挂在container里面 container.appendChild(newDiv); //4.把之前输入框中的内容清空 fromInput.value = ''; toInput.value = ''; messageInput.value = ''; //5.[新步骤]需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器! let messageJson = { 
      "from" : from, "to" : to, "message" : message }; $.ajax({ 
      type: 'post', contentType: 'application/json;charset=utf8', url: 'message',// 绝对路径的写法url: '/MessageWall/message', data: JSON.stringify(messageJson), success: function(body) { 
      alert("提交成功!"); }, error: function() { 
     // 会在服务器返回的状态码不是 2xx 的时候触发这个 error.  alert("提交失败!"); } }); } </script> </body> </html> 

编写后端响应代码(第4部分)

在这里插入图片描述

import com.fasterxml.jackson.databind.ObjectMapper; 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.util.ArrayList; import java.util.List; //对应前端传来的请求body //保证这几个属性的名字都和json里的key对应 class Message{ 
    public String from; public String to; public String message; @Override public String toString() { 
    return "Message{" + "from='" + from + '\'' + ", to='" + to + '\'' + ", message='" + message + '\'' + '}'; } } @WebServlet("/message") public class MessageServlet extends HttpServlet { 
    private ObjectMapper objectMapper = new ObjectMapper(); private List<Message> messageList = new ArrayList<>(); //负责实现让客户端提交数据给服务器 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    //1.把body的json数据解析出来 Message message = objectMapper.readValue(req.getInputStream(),Message.class); //2.把这个对象保存起来,最简单的方法,就是存到内存中. messageList.add(message); System.out.println("message : " + message); //3.返回保存成功的响应 resp.setContentType("application/json;charset=utf8"); resp.getWriter().write("{\"ok\" : 1}"); } //负责实现让客户端从服务器拿到数据 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    } } 

使用Fiddler , 来查看结果 :

在这里插入图片描述

编写后端请求代码(第1部分)

在这里插入图片描述

 //负责实现让客户端从服务器拿到数据 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setContentType("application/json;charset=utf8"); //把对象转成json格式的字符串,此处messageList是一个List,直接被转成json数组 String respString = objectMapper.writeValueAsString(messageList); resp.getWriter().write(respString); } 

整体代码

import com.fasterxml.jackson.databind.ObjectMapper; 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.util.ArrayList; import java.util.List; //对应前端传来的请求body //保证这几个属性的名字都和json里的key对应 class Message{ 
    public String from; public String to; public String message; @Override public String toString() { 
    return "Message{" + "from='" + from + '\'' + ", to='" + to + '\'' + ", message='" + message + '\'' + '}'; } } @WebServlet("/message") public class MessageServlet extends HttpServlet { 
    private ObjectMapper objectMapper = new ObjectMapper(); private List<Message> messageList = new ArrayList<>(); //负责实现让客户端提交数据给服务器 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    //1.把body的json数据解析出来 Message message = objectMapper.readValue(req.getInputStream(),Message.class); //2.把这个对象保存起来,最简单的方法,就是存到内存中. messageList.add(message); System.out.println("message : " + message); //3.返回保存成功的响应 resp.setContentType("application/json;charset=utf8"); resp.getWriter().write("{\"ok\" : 1}"); } //负责实现让客户端从服务器拿到数据 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setContentType("application/json;charset=utf8"); //把对象转成json格式的字符串,此处messageList是一个List,直接被转成json数组 String respString = objectMapper.writeValueAsString(messageList); resp.getWriter().write(respString); } } 

编写前端响应代码(第2部分)在这里插入图片描述

 /* 这个函数在页面加载时,从服务器获取到当前的消息列表 并显示到页面上 */ function load(){ 
    $.ajax({ 
    type:'get', url:'message', success:function(body){ 
    /* 此处得到的body是一个js对象的数组了 本来服务器返回的是JSON格式的字符串,ajax会自动根据 Content-Type对响应的body进行解析,解析成js对象 */ let container = document.querySelector('.container'); for(let message of body){ 
    let newDiv = document.createElement('div'); newDiv.className = 'row'; newDiv.innerHTML = message.from + "对" + message.to + "说" + message.message; container.appendChild(newDiv); } } }); 

整体代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>留言板</title> <style> * { 
      padding: 0; margin: 0; box-sizing: border-box; } .container { 
      width : 800px; margin : 10 px auto; } .container h2 { 
      text-align: center; margin: 30px 0px; } .row { 
      height: 50px; display: flex; justify-content: center; margin-top: 5px; line-height: 50px; } .row span { 
      height: 50px; width: 100px; line-height: 50px; } .row input { 
      height: 50px; width: 300px; line-height: 40px; font-size: 30px; color: cadetblue; } .row button { 
      width: 400px; height: 50px; color: #000; background-color: aquamarine; border: none; border-radius: 10px; } .row button:active { 
      background-color: grey; } </style> </head> <body> <!--这是一个顶层容器,放其他元素--> <div class="container"> <h2>留言板</h2> <div class="row"> <span></span> <input type="text" id="from"> </div> <div class="row"> <span>对谁</span> <input type="text" id="to"> </div> <div class="row"> <span>说什么</span> <input type="text" id="message"> </div> <div class="row"> <button>提交</button> </div> <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script> <script> let container = document.querySelector('.container'); let fromInput = document.querySelector('#from'); let toInput = document.querySelector('#to'); let messageInput = document.querySelector('#message'); let button = document.querySelector('button'); button.onclick = function() { 
      //1.把用户输入的内容获取到 let from = fromInput.value; let to = toInput.value; let message = messageInput.value; if(from == '' || to == '' || message == ''){ 
      return; } //2.构造一个div,把这个div插入到.container的末尾 let newDiv = document.createElement('div'); newDiv.className = 'row'; newDiv.innerHTML = from + "对" + to + "说" + message; //3.把div挂在container里面 container.appendChild(newDiv); //4.把之前输入框中的内容清空 fromInput.value = ''; toInput.value = ''; messageInput.value = ''; //5.[新步骤]需要把刚才输入框里取到的数据, 构造成 POST 请求, 交给后端服务器! let messageJson = { 
      "from" : from, "to" : to, "message" : message }; $.ajax({ 
      type: 'post', contentType: 'application/json;charset=utf8', url: 'message',// 绝对路径的写法url: '/MessageWall/message', data: JSON.stringify(messageJson), success: function(body) { 
      alert("提交成功!"); }, error: function() { 
     // 会在服务器返回的状态码不是 2xx 的时候触发这个 error.  alert("提交失败!"); } }); } /* 这个函数在页面加载时,从服务器获取到当前的消息列表 并显示到页面上 */ function load(){ 
      $.ajax({ 
      type:'get', url:'message', success:function(body){ 
      /* 此处得到的body是一个js对象的数组了 本来服务器返回的是JSON格式的字符串,ajax会自动根据 Content-Type对响应的body进行解析,解析成js对象 */ let container = document.querySelector('.container'); for(let message of body){ 
      let newDiv = document.createElement('div'); newDiv.className = 'row'; newDiv.innerHTML = message.from + "对" + message.to + "说" + message.message; container.appendChild(newDiv); } } }); } //函数调用写在这里,表示在页面加载时进行执行 load(); </script> </body> </html> 

在这里插入图片描述
执行一下!!!

1.一开始加载页面 .

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

过程解释 :

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接下来的问题是 , 当服务器从重启时 , List里的内容就会丢失 ! 如何解决这个问题呢 ?

  1. 存文件 , 使用IO流来读文件/写文件 .
  2. 数据库 , 使用MySQL + JDBC编程 .

此处我们让服务器把数据保存在MySQL服务器上 .

5.4将数据保存在MySQL服务器上

1.引入MySQL依赖 .

在这里插入图片描述

从中央仓库导入即可 .

  1. 创建数据库数据表 .

在这里插入图片描述

可以把上述操作写到一个单独的文件中 , 以备后用 .

在这里插入图片描述

  1. 调整后端代码 .
    a. 和数据库建立连接 , 单独搞一个DBUtil类 , 来实现数据库的建立连接 ;
    b. 封装数据库操作 , 通过JDBC来完成数据库的操作 .

DBUtil.java

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import javax.sql.DataSource; import javax.swing.*; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; / * 期望通过这个类来完成数据库建立连接的过程 * 建立连接需要使用DataSource,且一个程序有一个DDataSource实例即可. */ public class DBUtil { 
    private static DataSource dataSource = null; private static DataSource getDataSource() throws SQLException { 
    if(dataSource == null){ 
    dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL("jdbc:mysql:://127.0.0.1:3306/MessageWall?characterEncoding=utf8&useSSL=false"); ((MysqlDataSource)dataSource).setUser("root"); ((MysqlDataSource)dataSource).setPassword(""); } return dataSource; } public static Connection getConnection() throws SQLException{ 
    return getDataSource().getConnection(); } public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){ 
    if(resultSet != null){ 
    try { 
    resultSet.close(); } catch (SQLException e) { 
    throw new RuntimeException(e); } } if(statement != null){ 
    try { 
    statement.close(); } catch (SQLException e) { 
    throw new RuntimeException(e); } } if(connection != null){ 
    try { 
    connection.close(); } catch (SQLException e) { 
    throw new RuntimeException(e); } } } } 

MessageServletl.java

import com.fasterxml.jackson.databind.ObjectMapper; 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.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; //对应前端传来的请求body //保证这几个属性的名字都和json里的key对应 class Message{ 
    public String from; public String to; public String message; @Override public String toString() { 
    return "Message{" + "from='" + from + '\'' + ", to='" + to + '\'' + ", message='" + message + '\'' + '}'; } } @WebServlet("/message") public class MessageServlet extends HttpServlet { 
    private ObjectMapper objectMapper = new ObjectMapper(); //private List<Message> messageList = new ArrayList<>(); //负责实现让客户端提交数据给服务器 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    //1.把body的json数据解析出来 Message message = objectMapper.readValue(req.getInputStream(),Message.class); //2.把这个对象保存起来,最简单的方法,就是存到内存中. //messageList.add(message); save(message); System.out.println("message : " + message); //3.返回保存成功的响应 resp.setContentType("application/json;charset=utf8"); resp.getWriter().write("{\"ok\" : 1}"); } //负责实现让客户端从服务器拿到数据 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setContentType("application/json;charset=utf8"); //把对象转成json格式的字符串,此处messageList是一个List,直接被转成json数组 List<Message> messageList = load(); String respString = objectMapper.writeValueAsString(messageList); resp.getWriter().write(respString); } / * 把当前的消息保存到数据库中 * */ private void save(Message message){ 
    Connection connection = null; PreparedStatement statement = null; try { 
    //1.和数据库建立连接 connection = DBUtil.getConnection(); //2.构造SQL语句 String sql = "insert into walldata values(?,?,?)"; statement = connection.prepareStatement(sql); statement.setString(1,message.from); statement.setString(2,message.to); statement.setString(3,message.message); //3.执行SQL语句 int ret = statement.executeUpdate(); if(ret != 1){ 
    System.out.println("插入失败!"); } else { 
    System.out.println("插入成功!"); } } catch (SQLException e) { 
    e.printStackTrace(); } finally { 
    //4.关闭连接 DBUtil.close(connection,statement,null); } } / * 从数据库查询到记录 */ private List<Message> load(){ 
    Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; List<Message> messageList = new ArrayList<>(); try { 
    //1.建立连接 connection = DBUtil.getConnection(); //2.构造SQL String sql = "select * from walldata"; statement = connection.prepareStatement(sql); //3.执行SQL resultSet = statement.executeQuery(); //4.遍历结果集 while(resultSet.next()){ 
    Message message = new Message(); message.from = resultSet.getString("from"); message.to = resultSet.getString("to"); message.message = resultSet.getString("message"); messageList.add(message); } } catch (SQLException e) { 
    e.printStackTrace(); } finally { 
    //5.释放资源 DBUtil.close(connection,statement,resultSet); } return messageList; } } 

允许效果如下 :

在这里插入图片描述

在这里插入图片描述
内容任然存在 !

中断程序的运行 , 并再次启动 :

在这里插入图片描述

在这里插入图片描述

再次刷新页面 ,内容仍然存在 !

在这里插入图片描述

在这里插入图片描述

如果你发现结果不符合预期 , 怎么办 ?

起手式–抓包 !!!

1.一个是抓页面加载,看看GET /message方法请求和响应是啥样的 .

  1. 如果请求没问题,响应有问题,说明是后端问题 .
  2. 如果请求有问题,响应没问题,说明是前端问题.(检查发送ajax的代码)
  3. 如果请求响应都没问题,但是页面不能正确显示,还是前端问题~~(检查ajax的回调)

2.还可以再抓包POST看看有没有问题 .

3.还可以看看数据库里有没有正确数据.

如果数据库有数据,说明大概率是GET的时候出问题了.如果数据库没数据,说明大概率是POST的时候出问题了!!!

顺便记录一下笔者在这里出现的问题 :

1.没有加载jQuery .

在这里插入图片描述
2. 数据库密码写错了 .

在这里插入图片描述

你可能会问了 , 你这数据库密码不就泄露了吗 ?

我只能说 , 银行卡里没有余额,那掩盖密码也是无用的 .

六 : Cookie和Session

6.1 工作方式回顾

Cookie是浏览器给HTTP协议提供的一个持久化存储数据的方案. 

在这里插入图片描述

典型应用 : 保存用户的身份信息 !

在这里插入图片描述
在这里插入图片描述

注意 : Cookie是在客户端存的 , Session是在服务器存的 , Sessionid是在客户端和服务器都存了 .

在这里插入图片描述

注意 : 实现登录和身份验证是Cookie的一种典型的应用 , 此时需要Cookie和Session搭配工作 , 其他场景则不一定需要搭配Session . Cookie里是可以存多个键值对的 , 具体存什么 , 是程序猿自己约定的 . 比如你想存登录的时间 , 就可以以LoginTime为key , 以登录的时间戳为value .

6.2 Servlet对Cookie和Session提供的API

6.2.1 HttpServletRequest 类中的相关方法

在这里插入图片描述

6.2.2 HttpServletResponse 类中的相关方法

在这里插入图片描述

6.2.3 HttpSession 类中的相关方法

一个 HttpSession 对象里面包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息. 

在这里插入图片描述

6.2.4 Cookie 类中的相关方法

每个 Cookie 对象是一个键值对 

在这里插入图片描述

6.3 代码示例—实现用户登录

在这里插入图片描述

功能 : 登录页可输入用户名和密码 , 服务器验证正确性 . 如果正确跳转到主页 , 并在主页中显示出当前用户的身份信息 , 且显示出当前用户的登录的访问次数 . (当用户第一次登录成功后 , 就无须重新登录了) .

主页代码 : IndexServlet.java

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 javax.servlet.http.HttpSession; import java.io.IOException; //用这个Servlet返回主页信息 @WebServlet("/index") public class IndexServlet extends HttpServlet { 
    @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    HttpSession session = req.getSession(false); if(session == null){ 
    //用户未登录,跳转到登录页面,要去用户重新登录 resp.sendRedirect("login.html"); return; } //已经成功登录 String username = (String) session.getAttribute("username"); Integer visitCount = (Integer) session.getAttribute("visitCount"); visitCount = visitCount + 1; session.setAttribute("visitCount",visitCount); resp.setContentType("text/html;charset=utf8"); resp.getWriter().write("当前用户为: " + username + "访问次数 :" + visitCount); } } 

登录页代码 LoginServlet.java

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 javax.servlet.http.HttpSession; import java.io.IOException; //用来处理登录请求 @WebServlet("/login") public class LoginServlet extends HttpServlet { 
    @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    resp.setContentType("text/html;charset=utf8"); //读取请求中的参数,判定当前用户信息是否正确 String username = req.getParameter("username"); String password = req.getParameter("password"); if(username == null || username.equals("") || password == null || password.equals("") ){ 
    //返回提示 resp.getWriter().write("用户名或密码不完整!登录失败"); return; } if(!username.equals("baizong") || !password.equals("")){ 
    resp.getWriter().write("用户名或密码错误!登录失败!"); return; } //登录成功,创建一个会话,把用户信息填写到session里 HttpSession session = req.getSession(true); session.setAttribute("username","baizong"); Integer visitCount = (Integer) session.getAttribute("visitCount"); if(visitCount == null){ 
    session.setAttribute("visitCount",0); } resp.sendRedirect("index"); } } 

login.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录页</title> </head> <body> <form action="login" method="post"> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="提交"> </form> </body> </html> 

实现效果 :

在这里插入图片描述

存储结构 :

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述



七 : 上传文件

在这里插入图片描述

import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.IOException; @MultipartConfig @WebServlet("/upload") public class UploadServlet extends HttpServlet { 
    @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    Part part = req.getPart("MyFile"); //获取到文件的真实名字 System.out.println(part.getSubmittedFileName()); //获取文件大小 System.out.println(part.getSize()); //获取文件的类型 System.out.println(part.getContentType());. //把文件写入服务器这边的磁盘中 part.write("C:\\Users\\86177\\Desktop\\result.jpg"); resp.getWriter().write("upload ok!"); } } 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>upload</title> </head> <body> <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="MyFile"> <input type="submit" value="上传"> </form> </body> </html> 

在这里插入图片描述

最终效果 :

在这里插入图片描述

至此 , Servlet及其API全部介绍完毕 !

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126062.html

(0)
上一篇 2025-09-21 20:26
下一篇 2025-09-21 20:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信