学习了AJAX之后,为了练练手,用AJAX和JSON实现了简易的点赞功能:数据库中的数据表存储着每篇微博的点赞数,用户点赞1次,对应点赞数就会+1,取消点赞,对应点赞数就会-1,用户不能重复点赞。
现在来总结一下,需要关注的有2个方面:1.AJAX怎么实现的前后端数据传递?2. JSON与Java对象之间的转换
仍采用MVC设计模式,关于MVC,可参考之前写的博客: MVC设计模式+Servlet+Filter【练习】搭建 MVC 架构,实现数据的增删改查
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); } })需要使用到第三方Jar包,第三方Jar包不同,语法就不同。 有如下第三方包可供选择:
阿里Jar包:FastJson谷歌Jar包:Gsonjson-lib (本例子所选用的方式)JacksonFastJson和Gson的使用方法,可见之前写的文章: Java【教程】数据格式:XML与JSON
也可参考这篇文章,介绍了4种包: 四种JSON解析工具–(json-lib&Jackson&Gson&FastJson)
为了能够正常使用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类
注意:jQuery的JS文件不是Jar包,不放在lib文件夹里,单独放在js文件夹里。
引入的Jar包较多,下图标注了各Jar包的作用:
接口和实现类
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; } }接口和实现类
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); } }