Servlet的实战用法(表白墙前后端)

文章介绍了如何使用JavaEE创建一个服务器版本的表白墙应用,涉及到前后端交互接口的约定,如GET请求获取全部留言和POST请求发表新留言。后端使用ServletAPI、MySQL数据库存储及Jackson库处理JSON数据。在实现过程中,详细讲解了数据库连接、数据存取以及前后端数据交换的细节。
摘要由CSDN通过智能技术生成

作者:~小明学编程 

文章专栏: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>

效果演示

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值