学习Java已经有了几个月了,终于做到了一个完整的项目。在做项目的过程中,运用到之前学习到的很多知识点,对于知识点的梳理以及应用都有了进一步的认知。下面先简单介绍下这个项目。前提说明:这个项目分为WEB端和微信公众号端,由于篇幅关系,本篇只记录了WEB端的一些要点。
WEB项目想要达到的效果
首先,先简单的介绍下WEB项目达到的效果,以下是效果图。
系统总共分为4个模块,分别是控制台,快递员,用户,快递模块。控制台可以显示用户,快递员和快递的总数及日增量。还可以显示待取件快递的数量及日增量。之后的快递员,用户,快递模块可以实现各自的增删改查功能。
项目的整体架构
项目整体采用的是mvc架构,MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。简单的来说,视图层就是前端页面,即用户看到的视图效果。模型层负责数据操作和信息存储。控制层实现前后端的交互,即获取页面点击或者输入的数据,再对数据进行相应的操作,将结果返回给页面。可以理解为实现前后端数据交互的一个功能。
本次编写的项目主要有一下几个包,bean,dao,service,controller。bean所做的事情是私有化对象属性,对外开放get和set方法。这也是一种叫做开闭原则的设计模式,不允许随意更改对象的属性,整个项目都会贯穿这个原则。dao的主要就是实现各个操作的细节,比如数据的增删改查都写在这个包中。dao包中会有一个接口,以及接口所对应的实现类。那么,问题来了。为什么要有接口呢,直接写个类里面存放各种操作的实现方法,需要使用的时候直接调用,不好吗?其实接口的主要作用就是降低耦合度,屏蔽具体的底层实现。如果dao不用接口去实现的话,会导致调用dao(实现类)service部分的代码也要相应的做改变。有了接口,service就可以直接去调用dao接口所定义的方。不会出现牵一发而动全身的尴尬局面。还有一个好处就是在编写代码的时候,dao接口不需要具体的业务细节,比较容易的整理思路。同样service也可以实现降低耦合度,可以让前端页面不依赖业务层的具体实现。
前后端交互
在做第一个项目的时候,我个人在编写代码最容易出错的地方就是在前后端交互部分。先上代码,看下前后端是怎么交互的。第一个先演示一个不需要进行传参的前后端交互。想要达到的效果如下图所示,点击左侧用户列表的时候,在右侧出现用户数据。
前端的部分代码如下
<body><table id="user_list"></table><script>$(function(){$("#user_list").bootstrapTable({url:"/user/list.do",//数据地址striped:true,//是否显示行的间隔pageNumber:1,//初始化加载第几页pagination:true,//是否分页sidePagination:'server',pageSize:5,pageList:[5,10,20],showRefresh:true,queryParams:function(params){var temp = {offset:params.offset,pageNumber:params.limit};return temp;},columns:[{title:"编号",field:"id",sortable:false},{title:"昵称",field:"userName",sortable:false},{title:"手机号码",field:"userPhone",sortable:false},{title:"密码",field:"userPassword",sortable:false},{title:"注册时间",field:"registerTime",sortable:false},{title:"上次登录时间",field:"lastLoginTime",sortable:false},]});});</script></body>
当用户点击“用户列表”的时候,会触发一个页面的跳转(在这里没有展示代码)。跳转到的页面就是一个表格。这里用到了一个js组件,bootstrapTable,在columns里面填充数据就可以直接获得一张表格了。前后端交互主要靠的是这行代码:url:"/user/list.do"。可以直接到对应controller类中去找与这个url地址相对应的ResponseBody。
@ResponseBody("/user/list.do")public String list(HttpServletRequest request, HttpServletResponse response) {//1. 获取查询数据的起始索引值int offset = Integer.parseInt(request.getParameter("offset"));//2. 获取当前页要查询的数据量int pageNumber = Integer.parseInt(request.getParameter("pageNumber"));//3. 进行查询List<User> list = UserService.findAll(true, offset, pageNumber);List<BootStrapTableUser> list2 = new ArrayList<>();for(User u:list){String registerTime = DateFormatUtil.format(u.getRegisterTime());String lastLoginTime = DateFormatUtil.format(u.getLastLoginTime());BootStrapTableUser u2 = new BootStrapTableUser(u.getId(),u.getUserName(),u.getUserPhone(),u.getUserPassword(),registerTime,lastLoginTime);list2.add(u2);}Map<String, Integer> console = UserService.console();Integer total = console.get("data1_size");//4. 将集合封装为 bootstrap-table识别的格式ResultData<BootStrapTableUser> data = new ResultData<>();data.setRows(list2);data.setTotal(total);String json = JSONUtil.toJSON(data);return json;}
controller类的这个list方法只要将用户集合返回给前端就可以了。
接下来讲一下需要传参的情况。用修改用户信息这个例子来说明吧。首先来看下效果图
点击“立即查找”按钮之后,要在下面输出相关的用户信息。要完成这个步骤,就需要将用户输入的手机号码给接收到,再到数据库里面进行查询。最后将查询到的结果返回给前端。
$(function(){$("#find").click(function(){var windowId = layer.load();var number = $("#number").val();$.getJSON("/user/find.do",{number:number},function(data){layer.close(windowId);layer.msg(data.result);if(data.status == 0){$(".header:eq(1),.content:eq(1)").fadeIn(1000);userId = data.data.id;g_userPhone = data.data.userPhone;$("input:eq(1)").val(data.data.userName);$("input:eq(2)").val(data.data.userPhone);$("input:eq(3)").val(data.data.userPassword);if(data.data.status == 0){//未签收$("#status").html("未签收");}else{//已签收$("#status").html("已签收");}}})});
这是前端ajax部分的代码,跟上面一样,需要一个地址给到controller类,查询的地址就是“/user/find.do”。不同的是,这次传递的时候需要一个参数,也就是代码中的number。之后要注意的是,controller接收的时候一定是要与之对应,即request.getParameter()方法中填的参数也要是number。
@ResponseBody("/user/find.do")public String find(HttpServletRequest request,HttpServletResponse response){String userPhone = request.getParameter("number");User u = UserService.findByUserPhone(userPhone);Message msg = new Message();if(u == null){msg.setStatus(-1);msg.setResult("手机号不存在");}else{msg.setStatus(0);msg.setResult("查询成功");msg.setData(u);}String json = JSONUtil.toJSON(msg);return json;}
心得体会
做的第一个项目,磕磕撞撞遇到了很多坑。比如遇到空指针问题,传参问题等。做完这个项目之后感觉收获还挺多的,对于MVC框架的整体的应用能力加强了。另外在分析和查找代码问题方面比之前有了明显的进步。