作者:~小明学编程
文章专栏:JavaEE
格言:热爱编程的,终将被编程所厚爱。
目录
服务器版本的表白墙
创建项目
约定前后端交互接口
获取全部留言
发表新的留言
服务端代码
创建Message类
创建DBUtil类
创建MessageServlet类
前端代码
效果演示
服务器版本的表白墙
在我们了解了Servlet API的使用之后下面我们就可以来修改前面的表白墙代码了,让其加上一些后端代码实现前后端的交互。
创建项目
首先我们要给表白墙的的代码专门创建一个项目来,创建的过程可以参考上一篇文章,这里我们要说一下就是我们的依赖,因为我们想要把后面表白墙的信息都给存入数据库中所以我们要引入mysql的依赖包,然后我们的传输格式想要采用JSON的格式所以还要引入jackson的依赖具体代码见下面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>test_1_10_love_wall</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<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.12.6.1</version>
</dependency>
<!-- 引入mysql驱动包-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>
约定前后端交互接口
约定前后端的交互接口是非常的关键的,我们在开发的过程中通常是前端负责前端,后端负责后端,最后前后端代码合在一起,所以二者要约定好前端发送什么样的请求我们后端处理请求然后再将处理好的请求给发送回去,最后前端再解析后端返回的数据。
获取全部留言
这里我们采用get的请求方式来获取全部的留言,然后约定我们的数据格式。
请求:
GET /message
响应:Json格式
{
{
from: "黑猫",
to: "白猫",
message: "喵"
},
{
from: "黑狗",
to: "白狗",
message: "汪"
},
......
}
我们期望浏览器给服务器发送一个 GET /message 这样的请求, 就能返回当前一共有哪些留言记
录. 结果以 json 的格式返回过来。
发表新的留言
请求:body为json格式
POST /message
{
from: "黑猫",
to: "白猫",
message: "喵"
}
响应:json格式
{
ok: true
}
服务端代码
创建Message类
class Message{
public String from;
public String to;
public String message;
}
创建DBUtil类
public class DBUtil {
private static final String URL = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false";
private static final String USERNAME = "root";
private static final String PASSWORD = "0217";
private volatile static DataSource dataSource = null;//创建数据库源
private static DataSource getDataSource() {
//保证我们的线程安全
if (dataSource==null) {
synchronized (DBUtil.class) {
if (dataSource == null) {
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl(URL);
((MysqlDataSource)dataSource).setUser(USERNAME);
((MysqlDataSource)dataSource).setPassword(PASSWORD);
}
}
}
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) {
e.printStackTrace();
}
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
这里我们要连接数据库,我们采用JDBC的方式与数据库建立连接。
创建MessageServlet类
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
// private List<Message> messages = new ArrayList<>();
//改成数据库版本
//发表新留言
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
//获取全部留言
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
private void save(Message message) {
//存入数据
}
private List<Message> load() {
//获取数据
}
}
doPost()
//发表新留言
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理提交信息
Message message = objectMapper.readValue(req.getInputStream(),Message.class);
//将处理提交信息存在我们的内存中去
// messages.add(message);
//告诉页面返回的数据是 json 格式
save(message);
resp.setContentType("application/json; charset=utf8");
resp.getWriter().write("{\"ok\":true}");
}
doPost()方法主要是处理我们新发表的留言,当我们的前端代码发来post请求之后我们会从请求中读取其body中的数据然后将其放在我们的Message类中,接着将数据写入数据库中,然后设置我们的返回的数据格式将其设置为json格式,最后返回响应ok:true。
doGet()
//获取全部留言
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//把Java对象转换成JSON格式的字符串
resp.setContentType("application/json; charset=utf8");
List<Message> messages = load();
String jsonString = objectMapper.writeValueAsString(messages);
System.out.println("jsonString"+jsonString);
resp.getWriter().write(jsonString);
}
doGet()样式的请求是获取我们当前全部留言,首先设置我们返回的数据格式,然后用一个List集合类来获取我们数据库中的相关数据,然后通过writeValueAsString的方法将一个一个的对象转换成json格式的字符串,最后返回我们所有的数据。
这里我在做项目的时候遇到了一个问题,就是少写了setContentType然后前端将其解析成字符串了,导致前后端处理数据的格式不一样。
最后出现这种情况,解析的都是空的。
全部代码:
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;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 86184
* Date: 2023-01-10
* Time: 15:21
*/
class Message{
public String from;
public String to;
public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
// private List<Message> messages = new ArrayList<>();
//改成数据库版本
//发表新留言
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理提交信息
Message message = objectMapper.readValue(req.getInputStream(),Message.class);
//将处理提交信息存在我们的内存中去
// messages.add(message);
//告诉页面返回的数据是 json 格式
save(message);
resp.setContentType("application/json; charset=utf8");
resp.getWriter().write("{\"ok\":true}");
}
//获取全部留言
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//把Java对象转换成JSON格式的字符串
resp.setContentType("application/json; charset=utf8");
List<Message> messages = load();
String jsonString = objectMapper.writeValueAsString(messages);
System.out.println("jsonString"+jsonString);
resp.getWriter().write(jsonString);
}
private void save(Message message) {
//存入数据
Connection connection = null;
PreparedStatement statement = null;
//获得数据库连接
try {
connection = DBUtil.getConnection();
//构造SQL
String sql = "insert into message value(?,?,?)";
statement = connection.prepareStatement(sql);
statement.setString(1,message.from);
statement.setString(2,message.to);
statement.setString(3,message.message);
//执行sql
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection,statement,null);
}
}
private List<Message> load() {
//获取数据
List<Message> messages = new ArrayList<>();
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from message";
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while(resultSet.next()) {
Message message = new Message();//创建对象将查询到的数据写入其中
message.from = resultSet.getString("from");
message.to = resultSet.getString("to");
message.message = resultSet.getString("message");
messages.add(message);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection,statement,resultSet);
}
return messages;
}
}
前端代码
关于前端代码这里就不详细介绍了主要就是通过ajax发送请求,然后通过解析数据将其加载到页面上。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表白墙</title>
</head>
<body>
<div class="container">
<h1>表白墙</h1>
<p>输入后点击提交,会将信息显示在表格中</p>
<div class="row">
<span>谁:</span>
<input type="text" class="edit">
</div>
<div class="row" >
<span>对谁:</span>
<input type="text" class="edit">
</div>
<div class="row">
<span>说什么:</span>
<input type="text" class="edit">
</div>
<div class="row">
<input type="button" value="提 交" id="submit">
</div>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
//点击按钮提交的时候,ajax要构造数据发送给服务器
//页面加载的时候,从服务器获取消息列表,并且在页面上直接显示。
function getMessages() {
$.ajax({
type: 'get',
url:'message',
contentType: 'json',
success: function(body) {
let container=document.querySelector('.container');
console.log(body);
for(let message of body) {
let row=document.createElement('div');
row.innerHTML=message.from+'对'+message.to+'说:'+message.message;
row.className='row';
//3.把这个新的元素添加到DOM树上
container.appendChild(row);
}
}
});
}
getMessages();
let submitButton=document.querySelector('#submit');
submitButton.onclick=function(){
//1.先获取到编辑框的内容
let edits=document.querySelectorAll('.edit');
//依靠.value来获得其输入框的值
let from=edits[0].value;
let to=edits[1].value;
let message=edits[2].value;
// console.log(from,to,message);
//这里是对用户输入进行合法的校验,看用户输入是否合法
if(from==''||to==' '||message==''){
return;
}
//2.根据内容,构造HTML元素(.row里面包含用户输入的话)
//createElement:创建一个元素
let row=document.createElement('div');
row.className='row';
row.innerHTML=from+'对'+to+'说:'+message;
//3.把这个新的元素添加到DOM树上
let container=document.querySelector('.container');
container.appendChild(row);
//4.清空原来的输入框
for(let i=0;i<edits.length;i++){
edits[i].value='';
}
5.//把当前获取到的输入框的内容,构造成一个HTTP POST请求,然后通过ajax发给服务器
let body = {
"from": from,
"to": to,
"message": message
};
$.ajax({
type: "post",
url: "message",
contentType: "application/json;charset=utf8",
data: JSON.stringify(body),
success: function(body) {
alert("消息提交成功!");
},
error: function() {
alert("消息提交失败!");
}
});
}
</script>
<style>
/*去除浏览器默认样式:内边距,外边距,内边框和外边框不会撑大盒子*/
*{
margin:0;
padding: 0;
box-sizing: border-box;
}
/*margin:0 auto :意思是 中央居中*/
.container{
width: 400px;
margin:0 auto;
}
/*padding:20px auto :h1标签:上下间距20*/
h1{
text-align:center;
padding:20px auto;
}
p{
text-align:center;
color:#666;
padding: 10px 0;
font-size:14px;
}
/*display:flex:基于弹性布局
justify-content:center:水平居中
align-items:center:垂直居中
*/
.row{
height:50px ;
display: flex;
justify-content: center;
align-items:center;
}
/*现在对于span和input的长度进行调整*/
span{
width:90px;
font-size: 20px;
}
input{
width:310px;
height: 40px;
font-size: 18px;
}
/*现在处理一下 提交 按钮
首先,提交按钮宽度和父元素一样宽
其次,设置字体颜色和背景颜色
然后,border:none:作用:为了去除黑边框
border-radius:设置四个角角为圆矩形
font-size:设置 提交 字体的大小
*/
#submit{
width: 400px;
color: white;
background-color:orange;
border:none;
border-radius:5px;
font-size: 18px;
}
/*点击 提交 按钮 就会改变其背景颜色*/
#submit:active{
background-color: black;
}
</style>
</div>
</body>
</html>
效果演示