(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例

这篇具有很好参考价值的文章主要介绍了(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前面说过,Servlet就是Tomcat这个HTTP服务器提供给Java的一组API,来完成构建动态页面等任务。Servlet中涉及的API非常多,这里我们只关注以下三个即可,其余的可在工作中获得遇到具体场景再学习使用

  • HttpServlet
  • HttpServletRequest
  • HttpServletResponse

一:HttpServlet

HttpServlet:它提供了处理基于HTTP协议的请求和响应的功能,为开发人员提供了一组用于处理HTTP请求的方法,其中最常用的是doGet()doPost()方法。这些方法可以被子类重写以实现具体的业务逻辑。HttpServlet功能包括

  • 解析HTTP请求:HttpServlet类负责解析来自客户端的HTTP请求,并提供了与请求相关的方法,如获取请求方法、获取请求参数、获取请求头等
  • 处理HTTP请求:HttpServlet类定义了doGet()、doPost()等方法,用于处理GET和POST请求。开发人员可以根据业务需求重写这些方法,并在其中实现相应的业务逻辑
  • 生成HTTP响应:HttpServlet类提供了一组用于生成HTTP响应的方法,如设置响应状态码、设置响应头、写入响应内容等
  • 会话管理:HttpServlet类支持会话管理,可以通过getSession()方法获取会话对象,进行会话跟踪和管理
  • 错误处理:HttpServlet类提供了对HTTP错误的处理机制,可以重写相应的方法来自定义错误页面或错误处理逻辑

其核心方法如下,常用方法是后三个,前三个经常在相关面试中出现

方法名称 调用时机
init HttpServlet实例化后被调用一次
destory HttpServlet不再使用后被调用一次(正常关闭Tomcat
service 收到HTTP请求时候调用
doGet 收到GET请求的时候调用(由service方法调用)
doPost 收到POST请求的时候调用(由service方法调用)
doPut/doDelete/doOptions/... 收到其他请求的时候调用((由service方法调用))

这些方法的调用时机就称为“Servlet的生命周期”

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

二:HttpServletRequest

(1)介绍

HttpServletRequest:继承自ServletRequest接口,并提供了访问HTTP请求的方法和属性。HttpServletRequest对象包含了客户端发送到服务器的HTTP请求的信息,开发人员可以使用该对象获取请求的参数、请求头、请求方法等信息

其核心方法如下(都是get系列)

方法名称 调用时机
String getProrocol() 返回请求协议的名称和版本
String getMehtod() 返回请求方法名称
String getRequestURI() 从协议名称直到HTTP请求的第一行查询字符串中,返回该请求的URL的一部分
String getContexPath() 返回指示请求上下文的URI部分
Eunmeration getParameterNames() 返回一个String对象的美剧,包含在该请求中包含的参数的名称
String getParameter(String name) 以字符串形式返回请求参数的值,如果参数不存在则返回null
String[] getParameterValues(String name) 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在返回null
Enumeration getHeaderNames() 返回一个枚举,包含在该请求中包含的所有的头名
String getHeader(String name) 以字符串形式返回指定的请求头的值
String getCharacterEncoding() 返回请求主体中使用的字符编码名称
String getHeader(String name) 以字符串形式返回指定的请求头的值
String getContentType() 返回请求主体的MIME类型,如果不知道类型则返回null
int getContentLength 以字节为单位返回请求主体的长度,并提供输入流,如果长度未知则返回-1
InputStream getInputStream() 用于读取去请求的body内容,返回一个InputStream对象

(2)示例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;  
import java.util.Enumeration;  
  
@WebServlet("/showRequest")  
public class ShowRequestServlet extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        //把API执行的结果,放到stringBuilder中  
        StringBuilder stringBuilder=new StringBuilder();  

		// 声明响应boyd是html结构数据  
		resp.setContentType("text/html");
  
        stringBuilder.append("<h3>首行部分</h3>");  
        stringBuilder.append(req.getProtocol());  
        stringBuilder.append("<br>");  
        stringBuilder.append(req.getMethod());  
        stringBuilder.append("<br>");  
        stringBuilder.append(req.getRequestURI());  
        stringBuilder.append("<br>");  
        stringBuilder.append(req.getContextPath());  
        stringBuilder.append("<br>");  
        stringBuilder.append(req.getQueryString());  
        stringBuilder.append("<br>");  
        stringBuilder.append("<h3>header部分</h3>");  
        Enumeration<String> headerNames=req.getHeaderNames();  
        while (headerNames.hasMoreElements()) {  
            String headerName= headerNames.nextElement();  
            String headerValue=req.getHeader(headerName);  
            stringBuilder.append(headerName+":"+headerValue+"<br>");  
        }  
        resp.setContentType("text/html;charset=utf8");  
        resp.getWriter().write(stringBuilder.toString());  
  
    }  
}

在浏览器中输入http://localhost:8080/HelloServlet/showRequest?a=10&b=20&c=30,效果如下

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(3)示例2:获取Get请求参数

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("/getparameter")  
public class GetParameter extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 获取 query string 中的键值对  
        String studentId = req.getParameter("studentId");  
        String studentName = req.getParameter("studentName");  
        System.out.println(studentId);  
        System.out.println(studentName);  
  
        // 告诉浏览器类型和编码,让浏览器正常显示  
        resp.setContentType("text/html; charset=utf-8");  
        resp.getWriter().write("studentId: " + studentId + ", " + "studentName: " + studentName);  
    }  
}

在浏览器中输入http://localhost:8080/GetParameter/getparameter?studentId=22123213&studentName=张三,效果如下

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(3)实例3:获取Post请求参数

A:情况一

此时请求的bodyx-www-form-urlencoded,也即form表单

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("/postparameter")  
public class PostParameter extends HttpServlet {  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 通过发送post请求,获取 body 中的参数  
        // 让Servlet知道如何解析  
        req.setCharacterEncoding("utf-8");  
        String studentId = req.getParameter("studentId");  
        String studentName = req.getParameter("studentName");  
        System.out.println(studentId);  
        System.out.println(studentName);  
  
        // 告诉浏览器类型和编码,让浏览器正常显示  
        resp.setContentType("text/html; charset=utf-8");  
        resp.getWriter().write("studentId: " + studentId + ", " + "studentName: " + studentName);  
    }  
}

此时并不能在浏览器中直接输入参数,因为那是Get请求,构造Post请求可以有以下两种方法

  • 方法一:利用Html通过form表单发送
  • 方法二:使用软件postman

先说方法一:需要注意该Html文件必须位于webapp目录之下。复习一下,在HTML中,form标签用于创建一个表单,其中action属性义了表单提交时要发送数据的目标URL或服务器端脚本,当用户提交表单时,浏览器会将表单中的数据发送到action属性指定的URL。有以下两种常见的写法

  • 相对路径(此时基准目录就是Html文件所在目录,也即/PostParameter:例如postparameter
  • 绝对路径:例如/PostParameter.postparameter

运行PostParameter后,然后在地址栏中输入http://localhost:8080/PostParameter/student.html,即可正确访问到该文件

  • 再次重复:在Java Web应用程序中,通常将静态资源(例如HtmlCSS等)放置在webapp目录下,该目录是Web应用程序的根目录。链接中PostParameter是Servlet类的名称,并不是文件夹或路径

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

接着向表单输入内容,然后提交

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言


再说方法二:postman使用方法非常简单

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

另外,postman十分方便的一点是可以转换为代码

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

B:情况二

这种情况下请求的body是json格式,步骤如下

  • 首先需要读取body中的内容,这里需要借助getInputStream,以此获取到要解析的字符串
  • Servlet并没有内置json解释器,所以需要我们手动实现或者是借助第三方库,这里借助jackson这个库(因为它是SpringBoot御用的)。然后就会得到一组键值对
  • 根据类对象(在Java反射中讲到过)创建一个实例
  • 遍历类对象中的属性的名字,以此作为Key查询对应的Value
  • 返回构造好的对象

进入Java中央仓库,搜索jackson,选择Jackson Databind

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

随便选择一个版本后,拷贝Maven至pom.xml中的<dependencies></dependencies>标签内

<dependencies>  
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->  
    <dependency>  
        <groupId>javax.servlet</groupId>  
        <artifactId>javax.servlet-api</artifactId>  
        <version>3.1.0</version>  
        <scope>provided</scope>  
    </dependency>  
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->  
    <dependency>  
        <groupId>com.fasterxml.jackson.core</groupId>  
        <artifactId>jackson-databind</artifactId>  
        <version>2.13.4.1</version>  
    </dependency>  
  
</dependencies>

jackson会提供一个核心类叫ObjectMapper,其中有两个常用方法:

  • readValue:用于将json数据转换为Java对象
    • 第一个参数:可以是字符串,也可以是输入流
    • 第二个参数:是一个类对象,也就是要解析出来的结果的对象的类
  • writeValueAsString:用于将Java对象转换为json数据

代码如下

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;  
  
/*  
一个Java对象,要想正确解析,必须满足以下条件  
    这个类的属性务必是public或者带有public的getter/setter,否则jackson无法访问到这个对象的属性  
    这个类务必要有无参版本的构造方法(如果不写编译器自动生成无参构造)  
 */class Student {  
    public int studentId;  
    public String studentName;  
}  
  
@WebServlet("/json")  
public class JacksonServlet extends HttpServlet {  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 假设请求的body格式如下  
        // {studentId: 10, studentName: "张三"}  
  
        // 创建Jackson核心类  
        ObjectMapper objectMapper = new ObjectMapper();  
        // 解析json  
        Student s = objectMapper.readValue(req.getInputStream(), Student.class);  
        System.out.println(s.studentId);  
        System.out.println(s.studentName);  
  
        resp.setContentType("text/html; charset=utf-8");  
        resp.getWriter().write("studentId: " + s.studentId + ", " + "studentName: " + s.studentName);  
    }  
}

利用postman发送请求(注意设置正确),可以看到回应

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

当然我们也可以返回json

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;  
  
/*  
一个Java对象,要想正确解析,必须满足以下条件  
    这个类的属性务必是public或者带有public的getter/setter,否则jackson无法访问到这个对象的属性  
    这个类务必要有无参版本的构造方法(如果不写编译器自动生成无参构造)  
 */class Student {  
    public int studentId;  
    public String studentName;  
}  
  
@WebServlet("/json")  
public class JacksonServlet extends HttpServlet {  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 假设请求的body格式如下  
        // {studentId: 10, studentName: "张三"}  
  
        // 创建Jackson核心类  
        ObjectMapper objectMapper = new ObjectMapper();  
        // 解析json  
        Student s = objectMapper.readValue(req.getInputStream(), Student.class);  
        System.out.println(s.studentId);  
        System.out.println(s.studentName);  
  
        // 修改  
        s.studentId=20;  
        s.studentName="李四";  
        // 返回json  
        resp.setContentType("application/json; charset=utf-8");  
        resp.getWriter().write(objectMapper.writeValueAsString(s));  
    }  
}

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

三:HttpServletResponse

(1)介绍

HttpServletResponse:用于处理来自客户端的请求并生成响应,其中的方法可以设置和操作HTTP响应的各种属性,包括响应头、状态码、字符编码等等

其核心方法如下(都是set系列)

方法 描述
void setStatus(int sc) 为该响应设置状态码
void setHeader(String name, String value) 设置一个带有给定的名称和值的header(如果name存在则覆盖)
void addHeader(String name, Strin value) 添加一个带有给定的名称和值的header(如果name存在则并列添加新键值对)
void setContentType(String type) 设置被发送到客户端的响应的内容类型
void setCharacterEncoding(String charset) 设置被发送到客户端的响应的字符编码(MIME字符集),例如utf-8
void sendRedirect(String location) 使用指定的重定向位置URL发送临时重定向响应到客户端
PrintWriter getWriter() 用于向body中写入文本格式数据
OutputStream getOutputStream() 用于向body中写入二进制格式数据

(2)示例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("/status")  
public class StatusServlet extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 利用 queryString 设置状态码  
       String type = req.getParameter("type");  
  
       if (type.equals("1")) {  
           resp.setStatus(200);  
       } else if (type.equals("2")) {  
           resp.setStatus(404);  
       } else {  
           resp.setStatus(504);  
       }  
    }  
}

在浏览器地址里输入http://localhost:8080/StatusServlet/status?type=2

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(3)示例2:自动刷新

在HTTP响应的头部(Header)中,Refresh属性用于在服务器返回的响应中指示浏览器进行自动刷新或重定向操作。语法如下

  • 延迟时间:表示延迟多少秒后进行属性,默认为0s
  • URL=重定向URL:指定要重定向的URL
Refresh: [延迟时间]; URL=重定向URL

当浏览器接收到带有Refresh属性的响应时,它会根据指定的延迟时间进行等待,并在延迟结束后执行刷新或重定向。如果未指定延迟时间,默认为立即刷新

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 AutoRefreshServlet extends HttpServlet {  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 每2s刷新一次  
        resp.setHeader("refresh", "2");  
        // 显示当前时间戳  
        resp.getWriter().write(System.currentTimeMillis() + "");  
    }  
}

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(4)示例3:重定向

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);  
        resp.setHeader("Location", "https://www.baidu.com");  
    }  
}

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

四:综合案例之表白墙

前面介绍的表白墙案例非常简单,它只是一个单纯的HTML页面,如果将浏览器关闭,那么输入的内容将不复存在。所以这里我们可以将其做成服务器版本,这样即使页面关闭,表白墙内容也不会丢失

  • 注意:本案例虽然比较简单,但是会结合到之前很多知识,所以相关内容不再重复,如有需求可以翻看前面的内容

(1)效果展示

当加载页面时可以自动从服务器数据库中获取之前的提交内容

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

点击提交则可以将内容保存到服务器数据库中

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(2)请求和响应报文格式

发送数据给服务器

  • 请求报文
    • POST/message HTTP/1.1
    • Content-Type:application/json; charset=utf-8
    • {"who":"我", "whom":"你", "我啊你"}
  • 响应报文
    • HTTP/1.1 200 OK

从服务器获取数据

  • 请求报文
    • GET/message
  • 响应报文
    • HTTP/1.1 200ok
    • Content-Type:application/json; charset=utf-8

(3)代码梳理

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

(4)完整代码

  • 代码Github:点击跳转

整个项目概览

(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例,Java基础教程和高级教程,java,servlet,开发语言

Mysql相关语句


show databases;  
create database confession_wall;  
use confession_wall;  
create table message (who varchar(50), whom varchar(50), content varchar(1024));  

配置文件

pom.xml

<dependencies>  
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->  
    <dependency>  
        <groupId>javax.servlet</groupId>  
        <artifactId>javax.servlet-api</artifactId>  
        <version>3.1.0</version>  
        <scope>provided</scope>  
    </dependency>  
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->  
    <dependency>  
        <groupId>com.fasterxml.jackson.core</groupId>  
        <artifactId>jackson-databind</artifactId>  
        <version>2.13.4.1</version>  
    </dependency>  
  
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->  
    <dependency>  
        <groupId>mysql</groupId>  
        <artifactId>mysql-connector-java</artifactId>  
        <version>5.1.49</version>  
    </dependency>  
</dependencies>

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>

相关类

Message.java:用于封装消息内容

public class Message {  
    public String who;  
    public String whom;  
    public String content;  
  
  
    public String getWho() {  
        return who;  
    }  
  
    public String getWhom() {  
        return whom;  
    }  
  
    public String getContent() {  
        return content;  
    }  
  
    public void setWho(String who) {  
        this.who = who;  
    }  
  
    public void setWhom(String whom) {  
        this.whom = whom;  
    }  
  
    public void setContent(String content) {  
        this.content = content;  
    }  
}

MessageServlet.java:Servlet服务器

import com.fasterxml.jackson.databind.ObjectMapper;  
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;  
  
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.sql.DataSource;  
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;  
  

@WebServlet("/message")  
public class MessageServlet extends HttpServlet {  
    private ObjectMapper objectMapper = new ObjectMapper();  
    private List<Message> messageList = new ArrayList<>();  
  
    // 让页面获取到数据  
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 声明当前的响应数据格式  
        resp.setContentType("application/json; charset=utf-8");  
        // 读取数据库内容返回给页面  
  
        try {  
            messageList = load();  
        } catch (SQLException e) {  
            throw new RuntimeException(e);  
        }  
        resp.getWriter().write(objectMapper.writeValueAsString(messageList));  
    }  
  
    // 浏览器向服务器提交数据  
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
        // 获取到body中的数据并解析  
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);  
        // 向数据库提交内容  
        try {  
            save(message);  
        } catch (SQLException e) {  
            throw new RuntimeException(e);  
        }  
        resp.setStatus(200);  
        System.out.println("成功提交数据:"  
                + "【" + message.getWho() + "】" + "对【" + message.getWhom() + "】" + "说:" + message.getContent());  
  
    }  
  
    // 从数据库查询数据  
    private List<Message> load() throws SQLException {  
        // 先得有一个数据源  
        DataSource dataSource = DBUtil.getDataSource();  
        // 与服务器建立连接  
        Connection connection = dataSource.getConnection();  
  
  
        // 构造SQL并预处理  
        String sql = "select * from message";  
        PreparedStatement statement = connection.prepareStatement(sql);  
  
  
        // 执行SQL得到结果集合  
        ResultSet resultSet = statement.executeQuery();  
  
        //遍历结果集合  
        // List<Message> messageList = new ArrayList<>();  
        while (resultSet.next()) {  
            Message message = new Message();  
            message.setWho(resultSet.getString("who"));  
            message.setWhom(resultSet.getString("whom"));  
            message.setContent(resultSet.getString("content"));  
            messageList.add(message);  
  
        }  
  
        // 关闭连接释放资源  
        statement.close();  
        connection.close();  
  
        return messageList;  
    }  
  
    // 保存数据到数据库  
    private void save(Message message) throws SQLException {  
        // 先得有一个数据源  
        DataSource dataSource = DBUtil.getDataSource();  
  
        // 与服务器建立连接  
        Connection connection = dataSource.getConnection();  
        System.out.println(connection);  
  
        // 构造SQL并进行预处理  
        String sql = "insert into message values(?, ?, ?)";  
        PreparedStatement statement = connection.prepareStatement(sql);  
        System.out.println(sql);  
        statement.setString(1, message.who);  
        statement.setString(2, message.whom);  
        statement.setString(3, message.content);  
  
        // 执行SQL然后插入  
        try {  
            int res = statement.executeUpdate();  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
  
        // 关闭连接释放资源  
        statement.close();  
        connection.close();  
  
  
    }  
}

DBUtil.java:用于用于封装DataSource的单例

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;   
import javax.sql.DataSource;  
  
// 用于封装DataSource的单例(懒汉模式,注意线程安全)  
public class DBUtil {  
    private static volatile DataSource dataSource = null;  
  
    public static DataSource getDataSource() {  
        if (dataSource == null) {  
            synchronized (DBUtil.class) {  
                if(dataSource == null) {  
                    dataSource = new MysqlDataSource();  
                    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/confession_wall?characterEncoding=utf8&useSSL=false&serverTimezone=UTC");  
                    ((MysqlDataSource)dataSource).setUser("root");  
                    ((MysqlDataSource)dataSource).setPassword("123456");  
                }  
            }  
        }  
  
        return dataSource;  
    }  
  
    // 防止直接new DBUtil  
    private DBUtil() {};  
  
}

webapp

onfessionalWall.html:网页文章来源地址https://www.toymoban.com/news/detail-708849.html

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>ConfessionalWall</title>  
</head>  
<body>  
  
<style>  
  .container {  
    width: 400px;  
    /*水平居中*/  
    margin: 0 auto;  
  }  
  
  h1 {  
    text-align: center;  
  }  
  
  p {  
    text-align: center;  
    color: #808080;  
  }  
  
  .row {  
    height: 40px;  
    display: flex;  
    /*  水平居中*/  
    justify-content: center;  
    /*  垂直居中*/  
    align-items: center;  
  }  
  
  .row span {  
    width: 100px;  
  }  
  
  .row input {  
    width: 200px;  
    height: 25px;  
  }  
  
  .row button {  
    width: 310px;  
    height: 40px;  
    color:white;  
    background-color: orange;  
    border: none;  
  
  }  
    
  .row button:active {  
    background-color: #666;  
  }  
  
  
</style>  
  
  
<div class="container">  
  <h1>表白墙</h1>  
  <p>(输入后点击下方按钮提交)</p>  
  <div class="row">  
    <span>姓名:</span><input type="text">  
  </div>  
  
  <div class="row">  
    <span>对谁:</span><input type="text">  
  </div>  
  
  <div class="row">  
    <span>内容:</span><input type="text">  
  </div>  
  
  <div class="row">  
    <button>提交</button>  
  </div>  
  
  
</div>  
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>  
<script>  
  var container = document.querySelector('.container');  
  var button = document.querySelector('button');  
  button.onclick = function () {  
    // 获取内容  
    var inputs = document.querySelectorAll('input');  
    var who = inputs[0].value;  
    var whom = inputs[1].value;  
    var content = inputs[2].value;  
    console.log(who);  
    console.log(who);  
    console.log(content);  
    if (who === '' || whom === '' || content === '') {  
      alert("有未填写项");  
      return;  
    }  
  
    // 构造出div生成发送内容  
    let newDiv = document.createElement('div');  
    newDiv.className = 'row';  
    newDiv.innerHTML = "【" + who + "】" + "对【" + whom + "】" + "说:" + content;  
    container.appendChild(newDiv);  
  
    // 清空之前输入  
    for (var i = 0; i < inputs.length; i++) {  
      inputs[i].value = '';  
    }  
  
    // 构造对象  
    let data = {  
      who: who,  
      whom, whom,  
      content, content  
    };  
  
    // 利用ajax发送请求  
    $.ajax({  
      type: 'post',  
      url : 'message',  
  
      // 以下是body内容  
      data: JSON.stringify(data),  
      contentType: "application/json; charset=utf-8",  
      success: function(body) {  
        console.log("成功提交数据")  
      }  
    });  
  }  
  
  // 在页面加载时就获取服务器数据  
  function getMessages() {  
    $.ajax({  
      type: 'get',  
      url: 'message',  
      success: function (body) {  
        // body就是响应的body内容,json数组  
        // JQuery可以很智能的我们将json数组解析为js对象数组(但注意设置Content-Type为application/json)  
        let contatiner = document.querySelector('.container')  
        for (let i = 0; i < body.length; i++) {  
          let message = body[i];  
          // 构造元素  
          let newDiv = document.createElement('div');  
          newDiv.className = 'row';  
          newDiv.innerHTML = "【" + message.who + "】" + "对【" + message.whom + "】" + "说:" + message.content;  
          contatiner.appendChild(newDiv);  
        }  
      }  
    })  
  }  
  getMessages();  
  
  
</script>  
  
  
</body>  
</html>

到了这里,关于(Java高级教程)第三章Java网络编程-第七节2:Servlet API和综合案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【计算机网络 - 第三章】运输层

    目录 一、多路复用和多路分解 1、运输层端口号 2、概述 3、原理  1、无连接的多路复用与多路分解 - UDP 2、面向连接的多路复用与多路分解 - TCP 二、无连接运输——UDP用户数据报协议 1、UDP概述 2、UDP的优点 三、可靠数据传输原理 1、概述 2、rdt1.0——可靠信道上的可信数据

    2024年02月11日
    浏览(35)
  • [计算机网络]第三章——传输层

    仅供交流,请勿转载,侵权必删,写作业时请勿直接抄袭 传输层协议为运行在不同主机上的 应用进程之间 提供了 逻辑通信( logic communication) 功能。从应用程序的角度看,通过逻辑通信,运行不同进程的主机好像直接相连一样;实际上,这些主机也许位于地球的两侧,通过很多

    2023年04月08日
    浏览(29)
  • 【RabbitMQ教程】第三章 —— RabbitMQ - 发布确认

                                                                       💧 【 R a b b i t M Q 教程】第三章—— R a b b i t M Q − 发布确认 color{#FF1493}{【RabbitMQ教程】第三章 —— RabbitMQ - 发布确认} 【 R abbi tMQ 教程】第三章 —— R abbi tMQ − 发布确认

    2024年02月08日
    浏览(80)
  • 计算机网络第三章问答题

    答:(1)以太网交换机实质上就是一个 多接口的网桥 。 每个接口都直接与一个单台主机或另一个以太网交换机相连,并且一般都 工作在全双工方式 。 以太网交换机具有 并行性 。 相互通信的主机都是独占传输媒体,无碰撞地传输数据 以太网交换机的 接口有存储器 ,能在

    2024年02月20日
    浏览(44)
  • 第三章 数据链路层【计算机网络】

    2023-7-7 16:29:11 以下内容源自《【计算机网络】》 仅供学习交流使用 第二章 物理层【计算机网络】 计算机网络(第8版) 谢希仁 编著 3.1.1 数据链路和帧 3.1.2 三个基本问题 数据链路层协议有许多种,但有A个基本问题是: 封装成帧、透明传输和差错检测 。下面分别讨论这三个

    2024年02月13日
    浏览(34)
  • 计算机网络第三章——数据链路层(上)

    提示:节物风光不相待。桑田碧海须臾改 这一章主要学习数据链路层的功能和应用, 功能中最主要的也是最重要的就是封装成帧和透明传输 ,封装成帧就是帮我过滤一下物理层,这里就是将物理层的几个bit封装成帧, 帧就是数据链路层的传输单位或者说是传输单元 ,透明

    2024年02月08日
    浏览(37)
  • 计算机网络第三章——数据链路层(下)

    提示:任何命运无论多么复杂,都只是反映在一瞬间 局域网也有无线局域网, 局域网的特性主要由三个要素决定:拓扑结构、传输介质,介质访问控制方式,最重要的是介质访问控制方式,它决定着局域网的技术特性 我们日常生活中局域网主要是使用总线型这种结构,若是中

    2024年02月09日
    浏览(42)
  • 计算机网络第三章——数据链路层(中)

    数声风笛离亭晚,君向潇湘我向秦 主要任务:为使用介质的每个结点隔离来自同一信道上其他结点所传送的信号,以协调活动结点的传输 介质访问控制(Medium Access Control,MAC)子层: 用来决定广播信道中信道分配 总线型和星型都是广播式通信,看一下目的地址是否是本主机,若是

    2024年02月09日
    浏览(42)
  • 计算机网络-笔记-第三章-数据链路层

    一、第一章——计算机网络概述 二、第二章——物理层 三、第三章——数据链路层 四、第四章——网络层 五、第五章——运输层 六、第六章——应用层 目录 三、第三章——数据链路层 1、数据链路层概述(帧) (1)封装成帧、差错检测、可靠传输(简单介绍) (2)CS

    2024年02月10日
    浏览(37)
  • JAVA学习笔记——第三章 变量

    🔥 博客主页 : A_SHOWY 🎥 系列专栏 :力扣刷题总结录 数据结构  云计算  数字图像处理  力扣每日一题_  变量是程序的基本组成单位,是内存中的一个数据存储空间。变量有三个基本要素:类型+名称+值。变量的使用,声明后赋值后即可使用 变量使用注意事项:同c+

    2024年01月18日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包