AJAX+JSON【练习】实现简易的点赞功能

it2024-11-22  41

AJAX+JSON【练习】实现简易的点赞功能

1.前言2.AJAX实现前后端数据传递3.JSON与Java对象之间的转换4.数据库相关配置5.jQuery的JS文件,lib中的Jar包6.代码project目录beandaoservicewebClickThumbsupServletSelectServlet JSP 7.测试

1.前言

学习了AJAX之后,为了练练手,用AJAX和JSON实现了简易的点赞功能:数据库中的数据表存储着每篇微博的点赞数,用户点赞1次,对应点赞数就会+1,取消点赞,对应点赞数就会-1,用户不能重复点赞。

现在来总结一下,需要关注的有2个方面:1.AJAX怎么实现的前后端数据传递?2. JSON与Java对象之间的转换

仍采用MVC设计模式,关于MVC,可参考之前写的博客: MVC设计模式+Servlet+Filter【练习】搭建 MVC 架构,实现数据的增删改查

2.AJAX实现前后端数据传递

AJAX有2种实现方式: 1.用JavaScript实现 2.用jQuery实现 后者比前者简洁方便多了!

jQuery实现AJAX有3种方法: 1.ajax()方法 2.get()方法 3.post()方法 我们选用3种方法之一就可以了。

注意: ajax()方法是 jQuery 底层 AJAX 实现,更加灵活,有很多可选参数(以键值对的形式)。我们使用get()方法、post()方法时,jQuery会调用底层的ajax()方法。

在这个例子中,使用的是ajax()方法,现针对该例子,讲解前后端如何实现数据传递:

ajax()方法的参数data,前端往后端传数据: 参数data,就是前端往后端传的数据。

可以传入3种类型的数据:

文本:“uname=alice&mobileIpt=110&birthday=1983-05-12”json对象:{uanme:‘vic’,mobileIpt:‘110’,birthday:‘2013-11-11’}json数组: [ {“name”:“uname”,“value”:“alice”}, {“name”:“mobileIpt”,“value”:“110”}, {“name”:“birthday”,“value”:“2012-11-11”} ]

详见这篇文章:JQuery.Ajax()的data参数类型

ajax()方法的参数success,后端往前端传数据: 后端:从数据库中查询得到的数据,封装在实体类(bean)的对象中,从dao传到service再传到sevlet,在servlet中,将对象转换为JSON格式,通过PrintWriter将JSON发给前端。

//3.将对象返回给客户端,需要转换成json格式 JSONObject jo = JSONObject.fromObject(ar); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.print(jo);

前端:ajax()方法的参数success是一个回调函数,在回调函数的参数接收JSON数据。 所谓回调函数:就是请求在后台处理完,再返回到前台后,才调用的函数。

$.ajax({ url:"/toClickThumbsup", data:{"ifCancelThumbsup":ifCancelThumbsup,"articleID":articleID.toString()},//存入request域,servlet通过req.getParameter获取 type:"post", dataType:"JSON", success:function (result) { //服务器传来的result是JSON数据,该数据由Article对象转换而来 $(".thumbsupNum").text(result.thumbsupNum); } })

3.JSON与Java对象之间的转换

需要使用到第三方Jar包,第三方Jar包不同,语法就不同。 有如下第三方包可供选择:

阿里Jar包:FastJson谷歌Jar包:Gsonjson-lib (本例子所选用的方式)Jackson

FastJson和Gson的使用方法,可见之前写的文章: Java【教程】数据格式:XML与JSON

也可参考这篇文章,介绍了4种包: 四种JSON解析工具–(json-lib&Jackson&Gson&FastJson)

4.数据库相关配置

为了能够正常使用JDBC操作数据,以及使用Druid连接池,需要做以下工作: 1.创建lib文件夹,在idea里配置其为project library(过程略) 2.在lib里放有关数据库的jar包(Druid的jar包,JDBC的jar包) 3. src文件夹里放druid.properties文件,别放错地方了,里边的配置要改一下(数据库的名字) 4. 创建util包,util里放DruidUtil.java文件,这是一个工具类,方便使用连接池 5. dao的impl实现类要继承DruidUtil类

5.jQuery的JS文件,lib中的Jar包

注意:jQuery的JS文件不是Jar包,不放在lib文件夹里,单独放在js文件夹里。

引入的Jar包较多,下图标注了各Jar包的作用:

6.代码

project目录

bean

package com.czn.bean; public class Article { private int articleID; private int thumbsupNum = 0; public Article() { } public Article(int articleID, int thumbsupNum) { this.articleID = articleID; this.thumbsupNum = thumbsupNum; } public int getArticleID() { return articleID; } public void setArticleID(int articleID) { this.articleID = articleID; } public int getThumbsupNum() { return thumbsupNum; } public void setThumbsupNum(int thumbsupNum) { this.thumbsupNum = thumbsupNum; } }

dao

接口和实现类

package com.czn.dao; import com.czn.bean.Article; import java.util.List; public interface ArticleDao { //查 public Article selectOne(Article ar); //改 public Article updateThumbsup(Article ar,String ifCancelThumbsup); } package com.czn.dao.impl; import com.czn.bean.Article; import com.czn.dao.ArticleDao; import com.czn.util.DruidUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class ArticleDaoImpl implements ArticleDao { @Override public Article selectOne(Article ar) { int articleID = ar.getArticleID(); Connection conn = null; PreparedStatement state = null; ResultSet rs = null; try{ conn = DruidUtil.getConnection();//DruidUtil里的方法 String sql = "select * from article where articleID = ?"; state = conn.prepareStatement(sql); state.setInt(1,articleID); rs = state.executeQuery(); while(rs.next()){ //在数据库中获取该文章的点赞数,并修改文章对象的点赞数属性 ar.setThumbsupNum(rs.getInt("thumbsupNum")); } }catch (SQLException e){ System.out.println("从数据库中取数据时出错。"); e.printStackTrace(); }finally { //关闭资源 DruidUtil.close(conn,state,rs);//DruidUtil里的方法 } return ar; } @Override public Article updateThumbsup(Article ar,String ifCancelThumbsup) { Connection conn = null; PreparedStatement state = null; int rowNumAffected = 0; //先查找该文章,获取其原来的点赞数 Article oldAr = selectOne(ar); int previousNum = oldAr.getThumbsupNum(); try{ conn = DruidUtil.getConnection();//DruidUtil里的方法 String sql = "update article set thumbsupNum=? where articleID = ?"; state = conn.prepareStatement(sql); if(ifCancelThumbsup.equals("false")){ state.setInt(1,previousNum+1); }else if(ifCancelThumbsup.equals("true")){ state.setInt(1,previousNum-1); } state.setInt(2,oldAr.getArticleID()); rowNumAffected = state.executeUpdate(); System.out.println("更新数据库的数据时,影响表的行数:"+rowNumAffected); if(rowNumAffected <= 0){ throw new SQLException(); } }catch (SQLException e){ System.out.println("在数据库中更新数据时出错。"); e.printStackTrace(); }finally { //关闭资源 DruidUtil.close(conn,state,null); } //再次查找该文章,点赞数已经改变了 Article newAr = selectOne(ar); return newAr; } }

service

接口和实现类

package com.czn.service; import com.czn.bean.Article; public interface ArticleService { //查 public Article selectOne(Article ar); //改 public Article updateThumbsup(Article ar,String ifCancelThumbsup); } package com.czn.service.impl; import com.czn.bean.Article; import com.czn.dao.ArticleDao; import com.czn.dao.impl.ArticleDaoImpl; import com.czn.service.ArticleService; public class ArticleServiceImpl implements ArticleService { private ArticleDao dao = new ArticleDaoImpl(); @Override public Article selectOne(Article ar) { return dao.selectOne(ar); } @Override public Article updateThumbsup(Article ar,String ifCancelThumbsup) { return dao.updateThumbsup(ar,ifCancelThumbsup); } }

web

ClickThumbsupServlet

package com.czn.web; import com.czn.bean.Article; import com.czn.service.ArticleService; import com.czn.service.impl.ArticleServiceImpl; import net.sf.json.JSONObject; 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.io.PrintWriter; @WebServlet(value = "/toClickThumbsup") public class ClickThumbsupServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接受参数(是点赞,还是取消点赞) String ifCancelThumbsup = req.getParameter("ifCancelThumbsup"); String str = req.getParameter("articleID"); int articleID = Integer.parseInt(str); Article initAr = new Article(); initAr.setArticleID(articleID); //2.调取service方法 ArticleService service = new ArticleServiceImpl(); Article ar = service.updateThumbsup(initAr,ifCancelThumbsup); //3.将对象返回给客户端,需要转换成json格式 JSONObject jo = JSONObject.fromObject(ar); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.print(jo); } }

SelectServlet

package com.czn.web; import com.czn.bean.Article; import com.czn.service.ArticleService; import com.czn.service.impl.ArticleServiceImpl; import net.sf.json.JSONObject; 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.io.PrintWriter; @WebServlet(value = "/toSelect") public class SelectServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.接受参数 String str = req.getParameter("articleID"); int articleID = Integer.parseInt(str); //initAr的点赞数初始化为0 Article initAr = new Article(); initAr.setArticleID(articleID); //2.调取service方法 ArticleService service = new ArticleServiceImpl(); Article ar = service.selectOne(initAr); //3.将对象返回给客户端,需要转换成json格式 JSONObject jo = JSONObject.fromObject(ar); resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.print(jo); } }

JSP

<%@ page import="com.czn.bean.Article" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Microblog</title> <style> .article{ border: 1px solid coral; height: 250px; width: 500px; } .thumbsup{ color: darkgray; cursor: pointer; } .thumbsupNum{ color:lightsalmon; } </style> </head> <body> <div class="article" id="1"> <h5>summernight98</h5> <p>候馆梅残,溪桥柳细。草薰风暖摇征辔。离愁渐远渐无穷,迢迢不断如春水。 寸寸柔肠,盈盈粉泪。楼高莫近危阑倚。平芜尽处是春山,行人更在春山外。</p> <h6>2020.10.16</h6> <span class="thumbsup" active="false"></span><!--active是自定义属性--> <span class="thumbsupNum"></span> </div> </body> <script type="text/javascript" src="js/jquery-1.8.0.min.js"></script> <script type="text/javascript"> //从数据库获取该条微博的点赞数,显示出来 var articleID = $(".article").attr("id"); console.log("id:",articleID); //注意:接收JSON数据,必须用ajax方法,不能用get/post(默认接收文本数据) $.ajax({ url:"/toSelect", data:{"articleID":articleID.toString()},//存入request域,servlet通过req.getParameter获取 type:"post", dataType:"JSON", success:function (result) { //服务器传来的result是JSON数据,该数据由Article对象转换而来 $(".thumbsupNum").text(result.thumbsupNum); } }) //如果用户点击”赞“ var ifCancelThumbsup; $(".thumbsup").click(function () { if($(".thumbsup").attr("active")=="false"){ //改颜色 $(".thumbsup").css("color","coral"); //点赞次数+1 //var num = $(".thumbsupNum").text(); //$(".thumbsupNum").text(Number(num)+1); //改变active属性的值 $(".thumbsup").attr("active","true") ifCancelThumbsup = "false"; }else if($(".thumbsup").attr("active")=="true"){ //改颜色 $(".thumbsup").css("color","darkgray"); //点赞次数+1 //var num = $(".thumbsupNum").text(); //$(".thumbsupNum").text(Number(num)-1); //改变active属性的值 $(".thumbsup").attr("active","false") ifCancelThumbsup = "true"; } //改变数据库中的数据 $.ajax({ url:"/toClickThumbsup", data:{"ifCancelThumbsup":ifCancelThumbsup,"articleID":articleID.toString()},//存入request域,servlet通过req.getParameter获取 type:"post", dataType:"JSON", success:function (result) { //服务器传来的result是JSON数据,该数据由Article对象转换而来 $(".thumbsupNum").text(result.thumbsupNum); } }) }) </script> </html>

7.测试

最新回复(0)