Servlet小小项目练习:表白墙页面的实现
下面我们将通过这个实例,去感受前后端交接的处理流程
首先我们先来看一个这样的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>
<!-- 通过内部样式style标签,引入CSS样式 -->
<style>
*{
/* 首先先去除浏览器样式 */
/* 将 内外边距设置为0,设置盒子模型为向内挤压 */
margin: 0;
padding: 0;
box-sizing: border-box;
}
.containner{
width: 100%;
}
h3{
/* 文本居中 */
text-align: center;
/* 上下边距为 20px,左右边距为0 */
padding: 20px 0;
font-size: 24px;
}
p{
text-align: center;
color: #666;
padding: 10px 0;
}
.row{
width: 400px;
height: 50px;
/* 上下外边距为零,左右外边距自适应 */
/* 就是元素水平居中操作 */
margin: 0 auto;
/* 弹性布局 */
display: flex;
/* 水平居中 */
justify-content: center;
/* 垂直居中 */
align-items: center;
}
.row span{
width: 60px;
font-size: 17px;
}
.row input{
width: 300px;
height: 40px;
line-height: 40px;
font-size: 20px;
text-indent: 0.5em;
outline: none;
}
.row #submit{
width: 360px;
height: 40px;
font-size: 20px;
line-height: 40px;
margin: 0 auto;
color: white;
background-color: orange;
border: none;
border-radius: 15px;
outline: none;
}
/* 当鼠标点击按钮的时候,会改变按钮颜色 */
.row #submit:active{
background-color: grey;
}
</style>
<div class="container">
<h3>表白墙</h3>
<p>输入后点击提交,会将信息显示在表格中</p>
<br>
<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 id="submit">提交</button>
</div>
</div>
<script>
let submitBtn = document.querySelector('#submit');
submitBtn.onclick = function(){
// 1、获取 3个input 文本框中的数据
let inputs = document.querySelectorAll('input');
let from = inputs[0].value;
let to = inputs[1].value;
let say = inputs[2].value;
if(from == ''|| to == '' || say == ''){
// 用户填写的数据,并不完整。所以不提交。
return;
}
// 2、生成一个新的 div,内容就是 三个 input 文本框的内容拼接
// 再把这个 元素,挂在DOM树上。
let newDiv = document.createElement('div');
newDiv.innerHTML = from + "对" + to +"说:" + say;
newDiv.className = 'row';
// 将新建节点,挂在 container 这个节点下面
let container = document.querySelector('.container');
container.appendChild(newDiv);
}
</script>
</body>
</html>
效果图
既然是前后端的交互我们就首先要搞清楚具体的流程
下面是我们的要达到的效果
接下来让我们看看具体的代码怎么写
完整的servlet代码
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;
// 我们后端用这个类来接收前端提交的数据
class Message {
public String from;
public String to;
public String message;
}
// 这里只是把我们的数据存到了我们的内存中,服务器一重启,数据就没了
@WebServlet("/message")
public class MessageWallServlet extends HttpServlet{
// 因为前后端提交数据的格式是json,我们用jackson这个第三方库来接收处理前端传来的json类型的数据
private ObjectMapper objectMapper = new ObjectMapper(); // 又因为我们两个方法都有用到这个objectMapper这个类,我们把他放到
List<Message> messages = new ArrayList<>();
@Override // 这个接口用来前端从后端获取数据,并显示在页面上
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
resp.setContentType("application/json; charset=utf-8"); // 设置返回的数据类型
// 把么message对象转成json格式的字符串
String body = objectMapper.writeValueAsString(messages);
resp.getWriter().write(body); // 把json格式的数据写入返回响应的body当中
}
@Override // 这个接口用来后端接收从前端获取到的表单数据并储存起来
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
Message message = objectMapper.readValue(req.getInputStream(), Message.class); // 读取数据到message对象当中
messages.add(message); // 最直接的办法就是把这个直接存到内存里
resp.setContentType("application/json; charset=utf-8"); // 设置返回的编码格式
// 因为前端给我的数据格式是json类型的,所以我们后端返回给前端的数据也是json类型的(为了统一格式)
resp.setStatus(200);
resp.getWriter().write("{\"ok\":1}");
}
}
前端代码:
<!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: 10px 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: 50px;
}
.row button {
width: 400px;
height: 50px;
color: white;
background-color: orange;
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>
</div>
<!-- 引入ajax相关的内容,我们可以通过ajax构造get请求和post请求 -->
<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 请求, 交给后端服务器!
// 这里创建出了js一个对象,js对象中的每个方法和属性都是通过键值对这样的形式来表达的,键值对之间采用逗号进行分割,键和值之间用冒号来分割
// json中的键要求是字符串的形式
let messageJson = {
"from": from,
"to": to,
"message": message
};
// 客户端也就是我们通过ajax发起的请求,这个请求通过网络发给我们的tomcat服务器,进而就会调用我们也就是后端的doxxx方法
// 之后也就是我们后端通过resp.getWriter.writer构造出http响应,通过我们的tomcat服务器传给我们的客户端,客户端这里收到数据就会触发客户端的代码(ajax的回调success函数)
$.ajax({
type: 'post',
// 相对路径的写法
url: 'message',
contentType: 'application/json;charset=utf8',
// 绝对路径的写法
// 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 对象的数组了.
// ajax 自动帮我们进行类型转换了.
// 本来服务器返回的是 JSON 格式的字符串, ajax 会自动的根据 Content-Type 为 application/json
// 对响应的 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();
// 整个前后端交互的流程,大致是我们打开这个html页面或者说刷新页面,就会调用我们的load函数,
//load函数中的ajax构造了一个get请求,发送给tomcat服务器,进而调用我们后端servlet代码中的doGet方法
// 我们通过doGet方法返回一个http响应,并通过tomcat服务器把响应传给客户端,
// 客户端接收到数据后就会调用ajax的回调函数succes函数,把数据显示在页面上
</script>
</body>
</html>
还没有评论,来说两句吧...