表白墙服务器版【交互接口、服务器端代码、前端代码、数据存入文件/数据库】

文章目录

  • 一、准备工作
  • 二、约定前后端交互接口
  • 三、实现服务器端代码
  • 四、调整前端页面代码
  • 五、数据存入文件
  • 六、数据存入数据库

  • 一、准备工作

    1) 创建 maven 项目   2) 创建必要的目录 webapp, WEB-INF, web.xml;web.xml如下:
      Archetype Created Web Application

    3) 引入依赖(Servlet、Jackson)

    4) 把表白墙前端页面代码拷贝到 webapp 目录中

     

    二、约定前后端交互接口

    所谓 "前后端交互接口" 是进行 Web 开发中的关键环节。

    为了完成前后端交互,要约定两个交互接口:

    1.从服务器上获取到所有消息:

    请求: GET/message

    响应: JSON 格式

    {

           {from:"xxx" ,to:"xxx", message:"xxxxxx"}

            ..............

            .............

    }

    2.往服务器上提交数据

    请求: body 也为 JSON 格式    

    POST/message

     {from:"xxx" ,to:"xxx", message:"xxxxxx"}

    响应: JSON 格式

    {ok:1}

    三、实现服务器端代码

    //这个类表示一条消息的数据格式
    class Message{
            public String from;
            public String to;
            public String message;
    }
    @WebServlet("/message")
    public class MessageServlet extends HttpServlet {
        // 用于转换 JSON 字符串
        private ObjectMapper objectMapper = new ObjectMapper();
        // 用于保存所有的留言
        private List messageList = new ArrayList<>();
        //doGet方法用来从服务器上获取消息
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("application/json;charset=utf-8");
            //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
            objectMapper.writeValue(resp.getWriter(),messageList);
        }
        //doPost方法用来把客户端的数据提交到服务器
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
            //返回值放到Message对象中
            //通过这个代码就完成了读取body,并且解析成json的过程
            Message message = objectMapper.readValue(req.getInputStream(),Message.class);
            messageList.add(message);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":1}");
        }
    }

    四、调整前端页面代码

      
    此时在浏览器通过 URL http://127.0.0.1:8080/messageWall924/表白墙.html访问服务器, 即可看 到 。

     数据此时是存储在服务器的内存中 ( private List messages = new ArrayList(); ), 一旦服务器重启, 数据仍然会丢失。

    五、数据存入文件

    在上面的代码中,我们是把数据保存在messageList这个变量里面的,如果我们要把数据放在文件中,进行持久化存储,就不需要这变量了。

    FileWriter fileWriter = new FileWriter(filePath,true)

    java打开文件主要由三种方式:

    1.读方式打开(使用输入流对象的时候)

    2.写方式打开(使用输出流对象的时候)这种方式会清空原有内容

    3.追加写方式打开(使用输出流对象的时候) ,这种方式不会清空原有内容,而是直接在文件内容后面拼接。后面加上true就是追加写状态。

    数据存入文件完整代码如下:

    class Message{
            public String from;
            public String to;
            public String message;
    }
    @WebServlet("/message")
    public class MessageServlet extends HttpServlet {
        // 用于转换 JSON 字符串
        private ObjectMapper objectMapper = new ObjectMapper();
        // 用于保存所有的留言
    //    private List messageList = new ArrayList<>();
        //保存文件的路径
        private String filePath = "d:code/java/messageWall924/messages924.txt";
        //doGet方法用来从服务器上获取消息
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("application/json;charset=utf-8");
            //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
            List messageList = load();
            objectMapper.writeValue(resp.getWriter(),messageList);
        }
        private List load(){
            //把读到的数据放到List中
            List messageList = new ArrayList<>();
            System.out.println("开始从文件加载数据!");
            //此处需要按行读取,FileReader不支持,需要套上一层BufferedReader
            try(BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath))){
                while (true){
                    String line = bufferedReader.readLine();
                    if (line == null){
                        break;
                    }
                    //读取到的内容,就解析成Message对象
                    String[] tokens = line.split("\t");
                    Message message = new Message();
                    message.from = tokens[0];
                    message.to = tokens[1];
                    message.message = tokens[2];
                    messageList.add(message);
                }
            }catch (IOException e){
                e.printStackTrace();
            }
            return messageList;
        }
        //doPost方法用来把客户端的数据提交到服务器
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
            //返回值放到Message对象中
            //通过这个代码就完成了读取body,并且解析成json的过程
            Message message = objectMapper.readValue(req.getInputStream(),Message.class);
            //这里进行一个写文件操作
            save(message);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":1}");
        }
        private void save(Message message){
            System.out.println("数据开始写入文件");
            try(FileWriter fileWriter = new FileWriter(filePath,true)){
                fileWriter.write(message.from + '\t' + message.to +
                        '\t' + message.message + '\n');
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
    

    六、数据存入数据库

    1) 在 pom.xml 中引入 mysql 的依赖
      mysql mysql-connector-java 5.1.47 
    2) 创建数据库, 创建 messages 表

     

     3) 创建 DBUtil 类

    DBUtil 类主要实现以下功能: 创建 MysqlDataSource 实例, 设置 URL, username, password 等属性。 提供 getConnection 方法, 和 MySQL 服务器建立连接。 提供 close 方法, 用来释放必要的资源。
    public class DBUtil {
        private static final String URL = "jdbc:mysql://127.0.0.1:3306/messageWall924?characterEncoding=utf8&useSSL=false";
        private static final String USERNAME = "root";
        private static final String PASSWORD = "1234";
        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(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();
                }
            }
        }
    }
    4) 修改 load 和 save 方法, 改成操作数据库
     @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //readValue第一个参数可以支持一个字符串,也可以放inputStream对象;第二个参数是用来接收读取到的结果
            //返回值放到Message对象中
            //通过这个代码就完成了读取body,并且解析成json的过程
            Message message = objectMapper.readValue(req.getInputStream(),Message.class);
            //这里进行一个写数据操作
            save(message);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":1}");
        }
        private void save(Message message){
            System.out.println("向数据库写入数据!");
            //1.先和数据库建立连接
            Connection connection = null;
            PreparedStatement statement = null;
            try {
                //1.先和数据库建立连接
                connection = DBUtil.getConnection();
                //2.拼装sql
                String sql = "insert into message values(?,?,?)";
                statement = connection.prepareStatement(sql);
                statement.setString(1,message.from);
                statement.setString(2,message.to);
                statement.setString(3,message.message);
                //执行sql
                int ret = statement.executeUpdate();
                if (ret == 1){
                    System.out.println("插入数据库成功");
                }else {
                    System.out.println("插入数据库失败");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                DBUtil.close(connection,statement,null);
            }
        }
     //doGet方法用来从服务器上获取消息
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("application/json;charset=utf-8");
            //writeValue就是把messageList对象转换成json格式的字符串,并通过写入响应(resp.getWriter())返回
            List messageList = load();
            objectMapper.writeValue(resp.getWriter(),messageList);
        }
        private List load(){
            //把读到的数据放到List中
            List messageList = new ArrayList<>();
            System.out.println("从数据库开始读取数据!");
            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");
                    messageList.add(message);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                DBUtil.close(connection,statement,resultSet);
            }
            return messageList;
        }