1. 准备工作
创建项目,引入依赖......
将静态页面放到项目中(放在webapp目录下):
当前,这个表白墙页面,已经可以输入内容,点击提交之后也能显示内容,后续后端要做的工作即:
①存档
用户点提交的时候,把刚才输入的内容通过网络传输给服务器,由服务器保存这个数据.
②读档
后续有页面加载的时候,此时就通过网络,从服务器获取到之前保存好的内容.
都需要进行前后端交互接口的约定.
约定好,前端会给后端发起一个什么样的HTTP请求,后端返回什么样的HTTP响应.
html中的每个元素,同时都可以映射到js中的一个对象.(文档-对象模型)
通过对象的属性,就能获取到页面的内容.
修改对象的属性,也就能更新页面的内容.
2. 后端操作
非持久化保存数据:
class Message{public String from;public String to;public String message;@Overridepublic 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<>(); //更科学的方式,应该是保存到数据库中//用来实现存档操作@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取请求的body,转换成Java对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//2.得到message之后,把message保存到服务器中messageList.add(message);System.out.println("服务器收到message: "+ message );//3.返回响应(不太必要,主要是返回一个200 OK就行了,body可以没有)resp.setStatus(200);resp.getWriter().write("ok");}//用来实现读档操作@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//把我们内存中的这些Message,组织成json格式,返回到响应中.String respJson = objectMapper.writeValueAsString(messageList);//告诉浏览器,返回的响应的body是一个json格式.resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}
}
持久化保存数据:
class Message{public String from;public String to;public String message;@Overridepublic 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<>(); //更科学的方式,应该是保存到数据库中//用来实现存档操作@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取请求的body,转换成Java对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//2.得到message之后,把message保存到服务器中//messageList.add(message);try {save(message);} catch (SQLException e) {e.printStackTrace();}System.out.println("服务器收到message: "+ message );//3.返回响应(不太必要,主要是返回一个200 OK就行了,body可以没有)resp.setStatus(200);resp.getWriter().write("ok");}//用来实现读档操作@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//把我们内存中的这些Message,组织成json格式,返回到响应中.List<Message> messageList = null;try {messageList = load();} catch (SQLException e) {e.printStackTrace();}String respJson = objectMapper.writeValueAsString(messageList);//告诉浏览器,返回的响应的body是一个json格式.resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}//通过jdbc,往数据库中存一个数据.private void save(Message message) throws SQLException {//1.创建数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java108?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("808250");//2.建立连接Connection connection = dataSource.getConnection();//3.构造SQLString sql = "insert into message values(?,?,?)";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1,message.from);statement.setString(2,message.to);statement.setString(3,message.message);//4.执行SQLstatement.executeUpdate();//5.释放资源,关闭连接statement.close();connection.close();}private List<Message> load() throws SQLException {//1.创建数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java108?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("808250");//2.建立连接Connection connection = dataSource.getConnection();//3.构造SQLString sql = "select * from message";PreparedStatement statement = connection.prepareStatement(sql);//4.执行SQLResultSet 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.关闭连接,释放资源resultSet.close();;statement.close();connection.close();return messageList;}
}
2.1 存档(非持久化保存数据)
针对存档操作来说,前端发起一个HTTP请求.
此处约定使用json格式,把数据输出到后端.
让服务器返回一个HTTP响应. HTTP/1.1 200OK.
当前这个程序并不能在服务器重启之后保存数据,也就是把数据保存在了内存里,这样的设定并不科学.应该让数据持久化保存.
在刚才的代码基础上,引入数据库,来保存上述数据.
2.2 读档
前端页面加载的时候,需要从服务器拿到之前已经提交的数据.
响应的json应该是数组了,返回的数据会有多条.
2.3 用数据库-持久化保存数据
2.3.1 引入数据库的依赖(驱动包)
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.32</version>
</dependency>
2.3.2 创建数据库,创建数据表
2.3.3 编写代码
JDBC操作数据库,完成这里的数据存和取.
3. 前端操作
3.1 "存档"请求
先让js代码发起"存档"请求.
需要前端和后端通过HTTP交互,使用ajax.
这个相对路径的基准路径,就是当前HTML所在的路径.
写了相对路径message,就相当于在message基础上,加上一层/messageWall
一般会优先写作相对路径的方式.
后续如果要修改context path就比较方便,对于代码影响比较小了.
用户点击提交按钮,触发js提交数据的代码.
1.ajax方法会根据输入的参数,构造出HTTP请求,发给服务器.
2.服务器就会执行到对应的doPost方法.
3.响应回来之后,执行刚才设置好的success回调函数.
回调函数,其实是有三个参数的.
success(result,status,xhr)
对于JS的函数来说,参数如果不用,可以不写.
这里的body是形参,名字无所谓,一个参数的时候,就表示响应的body.
这个操作是把收到的数据显示到浏览器的控制台上,而不是页面上.
3.2 "读档"请求
此时也需要把这个json字符串,反向转换回js对象数组.
但是,实际上,jquery自动帮我们做好了这里的解析操作.
此时,形参body,已经是js的对象数组了,不需要使用JSON.parse进行解析.
4. 修改代码后,重启服务器没反应
4.1 先抓包
通过抓包,就能先把问题确定出,是前端还是后端的问题.
如果抓包发现,ajax的HTTP请求就没发出来,大概率是前端的问题.
如果发出来了,并且内容符合要求,大概率是后端的问题.
4.2 关注前端代码(HTTP请求没发出来)
此时更需要关注的是,浏览器里的情况.(js代码都是被下载到浏览器中,并执行的)