
提交信息后,就得到了下面的一行话

但是存在一些问题
在一个网站中,服务器起到的最主要的效果,就是 “存储数据”
因此服务器这边往往也就需要能够提供两种风格的接口。存数据 、取数据

二、实现前后端交互
1)先规定此处请求和响应的细节
2)先编写提交信息~
1.先写前端代码,发送请求
2.再写后端代码,解析请求,构造响应
3.再写前端代码,解析响应。
先写前端代码,发送请求

前端发起一个 ajax 请求
这个代码在点击按钮的回调函数中,在点击之后被调用到


3)服务器读取上述请求,并计算出响应
创建MessageServlet类,重写doPost方法
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;
    @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.读取前端发来的数据,把这个数据保存到服务器这边
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        System.out.println("请求中收到的message:" + message);
        //2.存储数据:最简单的办法,直接在内存中保存,可以使用一个集合类,把所有收到的message 都存到内存中
        //并非很合理的办法,因为一旦重启服务器,数据就丢失了
        //相比之下,把数据持久化存储到数据库中,更科学
        messageList.add(message);
        //3。返回一个响应
        resp.setStatus(200);
        resp.getWriter().write("ok");
    }
}

4)回到前端代码,处理服务器返回的响应
这里后端返回的ok 就会到 前端这里的回调函数 中responseBody这里



重启smart tomcat ,打开浏览器 ,查看效果


用fiddler抓包看看



5)客户端收到响应,就需要针对响应数据进行解析处理
把响应中的信息,构造成页面元素,并显示出来(需要拼接出html片段)

现在刷新浏览器,原有的数据还能保存,不会消失了
新开浏览器之后,之前的数据也还是在的
 6)整个逻辑梳理
6)整个逻辑梳理
 


三、存储到数据库中
由于刚才的后端代码实现是存储到浏览器内存中,当重新启动smart servlet后,原来的数据又会消失不见
 1)把数据库引入到代码中(引入依赖)
1)把数据库引入到代码中(引入依赖)
 
选择版本5.1.47

2)建库建表
在main目录里创建一个sql文件(文件名可以随便起,db.sql)

将这段代码复制到mysql里,创建好库和表
并插入两条数据

3)编写数据库代码
JDBC
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;
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<>();
    //创建数据库的 数据源
    private DataSource dataSource = new MysqlDataSource();
    @Override
    public void init() throws ServletException {
        //1.初始化数据源
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");//设置数据库的用户
        ((MysqlDataSource)dataSource).setPassword("123456");//设置数据库用户密码
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.读取前端发来的数据,把这个数据保存到服务器这边
        Message message = objectMapper.readValue(req.getInputStream(),Message.class);
        System.out.println("请求中收到的message:" + message);
        //2.存储数据:最简单的办法,
        //方法1:直接在内存中保存,可以使用一个集合类,把所有收到的message 都存到内存中
        //并非很合理的办法,因为一旦重启服务器,数据就丢失了
        //相比之下,把数据持久化存储到数据库中,更科学
        //messageList.add(message);//引入数据库后,这个内存临时保存的数据也可以不要了
        // TODO 插入数据库
        //方法2:引入数据库(最可靠)
        try {
            save(message);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        //3.返回一个响应
        resp.setStatus(200);
        resp.getWriter().write("ok");//对应前端的 回调函数 中的 responseBody
//        resp.setContentType("application/json; charset=utf8");//对应前端的 json格式
//        resp.getWriter().write("{ok:true}");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //通过这个方法来处理当前获取消息的列表的get请求,不需要解析参数,直接返回
        resp.setStatus(200);
        resp.setContentType("application/json; charset=utf8");
        //TODO 从数据库查询
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        String respJson = objectMapper.writeValueAsString(messageList);//将message这个存储的表的内容,转换成json字符串
        resp.getWriter().write(respJson);//返回响应
    }
    private void save(Message message) throws SQLException {
        //通过这个方法 把message 插入到数据库中
//        //1.创建数据源
//        DataSource dataSource = new MysqlDataSource();
//        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");
//        ((MysqlDataSource)dataSource).setUser("root");//设置数据库的用户
//        ((MysqlDataSource)dataSource).setPassword("123456");//设置数据库用户密码
        //2.建立连接(connection是java.sql里的对象)
        Connection connection = dataSource.getConnection();//需要抛出异常
        //3.构造sql
        String sql = "insert into message values(?,?,?)";//?是占位符
        PreparedStatement statement = connection.prepareStatement(sql);//构造sql语句对象
        statement.setString(1, message.from);//第一个占位符?替换成from
        statement.setString(2, message.to);//第二个占位符?替换成to
        statement.setString(3, message.message);//第三个占位符?替换成message
        //4,执行sql
        statement.executeUpdate();
        //5.回收资源
        statement.close();
        connection.close();
    }
    private List<Message> load() throws SQLException {
        //通过这个方法从数据库读取到message
        //1.创建数据源(init方法里写了)
        //2.建立连接
        Connection connection = dataSource.getConnection();
        //3.构造sql
        String sql = "select * from message";//查询这个表的sql语句
        PreparedStatement statement = connection.prepareStatement(sql);//将这个sql语句构造成一个sql语句对象
        //4.执行sql语句,放入到result集合里
        ResultSet resultSet = statement.executeQuery();
        //5.遍历结果集合
        List<Message> messageList = new ArrayList<>();
        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);
        }
        //6.回收资源
        connection.close();
        statement.close();
        resultSet.close();
        //7.返回messageList
        return messageList;
    }
}
重启smart tomcat 看到之前在数据库插入的信息还保存着在,并且显示到浏览器上了

输入了一个新的数据

在数据库中 也能查到
 
 










