关于ajax方法向服务器发送json数据并返回显示数据到页面的问题可结合我另一篇博文观看:https://blog.csdn.net/VEclipses/article/details/104883278Maven项目学习笔记(七)SSM项目使用JQuery结合PageHelper对数据进行分页(实战)。
这几天自己一直在琢磨着如何利用JQuery的ajax方法向服务器发送json数据,服务器接收到数据后进行数据库查询操作返回数据到ajax的success方法内。在自己研究下后成功实现了。在这个过程中,自己不仅学习了相关SSM知识,还学习了JQuery的知识,技术进步了一点点,还是有点满意的。之前我的项目的前端和后端交互都交给了Spring,没有利用到JQuery,这样感觉很不好。再者前端利用Spring封装数据点击提交,必选输入框的内容为空都直接发送请求到服务器,再让服务器做验证工作显然是不合理,一是给服务器造成多余的负担,二是增加了服务器控制器的代码。
(重点在步骤3和4)
1.准备数据库层
准备数据库实体类:
package com.myhomes.entity;
import org.springframework.format.annotation.DateTimeFormat;
import java.sql.Date;
public class MonthCost {
private String HouseId;
private Integer BookerId;
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date yearsMonth;
private Integer rent;
private double waterMeter;
private double powerMeter;
private Integer network;
private Integer clean;
private double sum;
private User users;
public Date getYearsMonth() {
return yearsMonth;
}
public void setYearsMonth(Date yearsMonth) {
this.yearsMonth = yearsMonth;
}
public String getHouseId() {
return HouseId;
}
public void setHouseId(String houseId) {
HouseId = houseId;
}
public Integer getBookerId() {
return BookerId;
}
public void setBookerId(Integer bookerId) {
BookerId = bookerId;
}
public Integer getRent() {
return rent;
}
public void setRent(Integer rent) {
this.rent = rent;
}
public double getWaterMeter() {
return waterMeter;
}
public void setWaterMeter(double waterMeter) {
this.waterMeter = waterMeter;
}
public double getPowerMeter() {
return powerMeter;
}
public void setPowerMeter(double powerMeter) {
this.powerMeter = powerMeter;
}
public Integer getNetwork() {
return network;
}
public void setNetwork(Integer network) {
this.network = network;
}
public Integer getClean() {
return clean;
}
public void setClean(Integer clean) {
this.clean = clean;
}
public double getSum() {
return sum;
}
public void setSum(double sum) {
this.sum = sum;
}
public User getUsers() {
return users;
}
public void setUsers(User users) {
this.users = users;
}
}
准备数据库操作类接口方法:
package com.myhomes.dao;
import com.myhomes.entity.MonthCost;
import org.springframework.stereotype.Repository;
@Repository("monthCostDao")
public interface MonthCostDao {
MonthCost selectLastMonthMeterByHouseId(String houseId);
}
准备对应的映射xml文件:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.myhomes.dao.MonthCostDao">
<resultMap id="monthCost" type="MonthCost">
<id property="id" column="id" javaType="Integer"></id>
<result property="HouseId" column="house_id" javaType="String"></result>
<result property="BookerId" column="booker_id" javaType="Integer"></result>
<result property="yearsMonth" column="years_month" javaType="java.sql.Date"></result>
<result property="rent" column="rent" javaType="Integer"></result>
<result property="waterMeter" column="water_meter" javaType="Double"></result>
<result property="powerMeter" column="power_meter" javaType="Double"></result>
<result property="network" column="network" javaType="Integer"></result>
<result property="clean" column="clean" javaType="Integer"></result>
<result property="sum" column="sum" javaType="Double"></result>
<association property="users" column="booker_id" javaType="User" select="com.myhomes.dao.UserDao.selectById">
</association>
</resultMap>
<select id="selectLastMonthMeterByHouseId" parameterType="String" resultMap="monthCost">
select house_id,years_month,rent,water_meter,power_meter from month_cost where house_id = #{houseId} order by years_month desc LIMIT 0,1
</select>
</mapper>
准备数据库对应的表:
另一张表:
这个表的booker_id字段为外键,对应users表的id。我这个表目前是一张空表。
2.服务层
新建服务层接口方法:
package com.myhomes.biz;
import com.myhomes.entity.MonthCost;
public interface MonthCostBiz {
MonthCost searchLastMonthMeterByHouseId(String houseId);
}
添加实现类:
package com.myhomes.biz.impl;
import com.myhomes.biz.MonthCostBiz;
import com.myhomes.dao.MonthCostDao;
import com.myhomes.entity.MonthCost;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service("monthCostBiz")
public class MonthCostBizImpl implements MonthCostBiz {
@Autowired
@Qualifier(value = "monthCostDao")
private MonthCostDao monthCostDao;
public MonthCost searchLastMonthMeterByHouseId(String houseId) {
return monthCostDao.selectLastMonthMeterByHouseId(houseId);
}
}
3.控制器层
在添加控制器层文件之前,我们可以先在pom中添加json的相关依赖文件:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
添加控制器类:
package com.myhomes.controller;
import com.myhomes.biz.HouseBiz;
import com.myhomes.biz.MonthCostBiz;
import com.myhomes.entity.House;
import com.myhomes.entity.MonthCost;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("monthCostController")
@RequestMapping(value = "/count")
public class MonthCostController {
@Autowired
private HouseBiz houseBiz;
@Autowired
private MonthCostBiz monthCostBiz;
@RequestMapping(value = "/view")
public String click(Model model){
model.addAttribute("houseList",houseBiz.searchAllHouseId());
return "count_house";
}
@RequestMapping(value = "/lastMonthMeter")
@ResponseBody
public Map<String,Object> lastMonthMeter(String houseId){
Map<String,Object> map = new HashMap<>();
MonthCost monthCost = monthCostBiz.searchLastMonthMeterByHouseId(houseId);
if (monthCost!=null){
map.put("monthCost",monthCost);
return map;
}else{
map.put("monthCost",null);
return map;
}
}
}
利用json的方法是:lastMonthMeter()。
1.这个方法从前端ajax接收用户选择的houseId后,进行数据库的查找,查找其上次添加的记录,不管是否有查找到数据都返回map。
2.SSM项目需要返回json数据需要在方法前添加@ResponseBody注解。
4.前端
页面准备:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<jsp:include page="top.jsp"></jsp:include>
<section id="right">
<a id="user_local">
业务管理 -> (每月/退房)计算房租
</a>
<div id="count_house_div">
<form id="count_house_form" name="count_house_form">
<label>房间号 </label>
<select name="HouseId" id="count_house_HouseId">*
<option selected disabled style="display:none" value="">选择房号</option>
<c:forEach items="${houseList}" var="hlist">
<option value="${hlist.houseId}"> ${hlist.houseId}</option>
</c:forEach>
</select>
<label>年月日 </label>
<%--<div class="layui-input-inline">--%>
<input type="text" class="layui-input" id="counthouse1" placeholder="yyyy-MM-dd" name="yearMonth" style="width: 80px;">*
<%--</div>--%>
<label>月租金 </label>
<input type="text" placeholder="只能输入整数..." maxlength="4" name="rent" id="rent" style="width: 100px;">*
<label>今月水表数 </label>
<input type="text" placeholder="目前水表数..." maxlength="10" name="waterMeter" id="waterMeter" style="width: 85px;">*
<label>今月电表数 </label>
<input type="text" placeholder="目前电表数..." maxlength="10" name="powerMeter" id="powerMeter" style="width: 85px;">*
<label>网费 </label>
<input type="text" placeholder="只能输入整数..." maxlength="10" name="network" id="network" style="width: 100px;">
<label>清洁费 </label>
<input type="text" name="clean" id="clean" readonly value="10" style="width: 40px;background-color: #93D1FF">
<div id="lastMonth" style="top: 20px;"></div>
<label id="sum_label">总计 </label>
<input id="sum_input" type="text" readonly name="sum" style="width: 70px;background-color: #93D1FF">
<input id="count_house_btn" type="button" onclick="" value="添加">
</form>
</div>
<script src="/js/monthCount.js"></script>
</section>
<jsp:include page="buttom.jsp"></jsp:include>
注意看代码的倒数第三行引入js的代码,我是在这里引入的,这样保证用户使用这块html页面的时候才使用这里需要的js代码。
(暂时没有用到前端页面框架)
注意,我这里的下拉列表的数据是从数据库查找的,其用<c:foreach>标签循环显示的。详细可以查看控制器的第一个方法。
JQuery部分:
$(document).ready(function(){
var yearMonth = $("#counthouse1").val();
var rent = $("#rent").val();
var waterMeter = $("#waterMeter").val();
var powerMeter = $("#powerMeter").val();
var network = $("#network").val();
var clean = $("#clean").val();
$("#count_house_HouseId").change(function () {
var HouseId = $("#count_house_HouseId").val();
$.ajax({
dataType:"json",
type:"get",
url:"/count/lastMonthMeter",
data:{houseId:HouseId},
success:function (data) {
var last = data.monthCost;
if (data.monthCost == null){
var htmls = "<label>上次对:"+HouseId+" 计算房租时间:空 </label>"+"<label>上月本金:无 </label>"+
"<label>上月水表度数:0 </label>"+"<label>上月电表度数:0</label>";
if ($("#lastMonth").find("*").length > 0){
$("#lastMonth").html(htmls);
}else{
$("#lastMonth").append(htmls);
}
}else{
var htmls = "<label>上次对:"+HouseId+" 计算房租时间:"+last.yearsMonth+"</label>"+"<label>上月本金:"+last.rent+"</label>"+
"<label>上月水表度数:"+last.waterMeter+"</label>"+"<label>上月电表度数:"+last.powerMeter+"</label>";
$("#rent").val(last.rent);
if ($("#lastMonth").find("*").length > 0){
$("#lastMonth").html(htmls);
}else{
$("#lastMonth").append(htmls);
}
}
}
});
});
//count sum
$("#sum_input").val(rent + network + clean);
});
我js代码用到了JQuery的change方法,该方法的作用是用户在前端修改了下拉框的选项时,查询对应的数据库表,成功后显示该房间的相关信息。
5.演示
准备的工作都完备了,接下来进行展示:
选择A202房间
显示(横线是我截图时加的):
再次修改所选,这次选B101:
显示:
旧的A202得红色的提示信息修改成B101的提示信息。
6.后言
这个功能还没有做完,填完数据后是要进行添加操作的,不出意外的话就会继续更新。
7.补
今天晚上终于搞好从前端获取json发送到后台并进行添加操作并返回添加的信息了,赶紧来更新这里——2020-3-8 23:09。
我做的功能是(每月/退房)计算房租的功能 :
⒈用户来到“计算房间”页面后,系统接收请求,并且查找已入住的房间号数据列表(model封装它)返回到前端,使用<c:forEach>标签显示数据。
已入住的房间。
这里牵涉的表有3张:
users表:
现任租客的user_class为3。
2.houses表:
booker_id是外键,对应着users表的id键。
month_cost表:
booker_id是外键,对应着users表的id键。
2.选择A101号房间后,向服务器发送{houseId:"A101"}这json数据。服务器接收收进行查找操作,查询此房间上次计算房租的时间等等数据,并返回到前端。
月租金输入框直接显示月租金数额,因为租金一般是不变的,而且直接显示月租金也对用户友好一点。
3.前端输入好各项数据后进行总金额计算
总计输入框和清洁费输入框都是“只读”的,每次修改水表电表网费月租金中的某个输入框数值,总计输入框动态计算总金额。
4.点击添加按钮进行添加操作
必选的输入框不为空才能点击此按钮。
5.如果提交的月份与上次计算房租的月份相同,则进行退房操作,需要修改前面所述的3张表。
我这里有多个严重的逻辑bug,今月水/电表数都可以比其上月的小而且网费可以为负数,总计金额也有问题,而且年月日时间可以比上次的时间早。明天再改改吧,不过不影响文章的主旨。
点击添加后:
三个数据表:
houses表的入住ID为空。
用户类型为4,而且搬出时间已经设置为当前了。
主要部分:
JQuery:
$(document).ready(function(){
clean = $("#clean").val();
lastMonth ;
$("#count_house_HouseId").change(function () {
var HouseId = $("#count_house_HouseId").val();
$.ajax({
dataType:"json",
type:"get",
url:"/count/lastMonthMeter",
data:{houseId:HouseId},
success:function (data) {
var last = data.monthCost;
if (data.monthCost == null){
lastMonth = null;
var htmls = "<label>上次对:"+HouseId+" 计算房租时间:空 </label>"+"<label>上月本金:无 </label>"+
"<label>上月水表度数:0 </label>"+"<label>上月电表度数:0</label>";
if ($("#lastMonth").find("*").length > 0){
$("#lastMonth").html(htmls);
}else{
$("#lastMonth").append(htmls);
}
$("#counthouse1").val(null);
$("#rent").val(null);
$("#waterMeter").val(null);
$("#powerMeter").val(null);
$("#network").val(null);
}else{
lastMonth = last.yearsMonth;
//alert("lastMonth:"+lastMonth);
var htmls = "<label>上次对:"+HouseId+" 计算房租时间:"+last.yearsMonth+",</label>"+"<label>上月本金:"+last.rent+",</label>"+
"<label>上月水表度数:"+last.waterMeter+", </label>"+"<label>上月电表度数:"+last.powerMeter+"</label>";
$("#rent").val(last.rent);
if ($("#lastMonth").find("*").length > 0){
$("#lastMonth").html(htmls);
}else{
$("#lastMonth").append(htmls);
}
}
}
});
});
//count sum
//$("#sum_input").val(rent + network + clean);
// //年月日输入框值变化后执行
// $("#counthouse1").change(function () {
// alert("counthouse1");
// if (lastMonth == null){
// alert("lastMonth == null");
// }else{
// alert("lastMonth != null");
// var thisMonth = lastMonth.substr(0,7);
// alert("thisMonth:"+thisMonth);
// var userInputMonth = $("#counthouse1").val().substr(0,7);
// alert("userInputMonth:"+userInputMonth);
// if (thisMonth === userInputMonth){
// alert("年月份相同,系统会进行退房处理!请注意");
// }
// }
// });
//月租金输入框值变化后执行
$("#rent").change(function () {
var rent1 = $("#rent").val()*1;
var waterMeter = $("#waterMeter").val()*2.5;
var powerMeter = $("#powerMeter").val()*1.5;
var network = $("#network").val()*1;
var clean = $("#clean").val()*1;
//计算
var i = rent1 + waterMeter + powerMeter + network + clean;
$("#sum_input").val(i);
});
//今月水表数输入框值变化后执行
$("#waterMeter").change(function () {
var rent1 = $("#rent").val()*1;
var waterMeter = $("#waterMeter").val()*2.5;
var powerMeter = $("#powerMeter").val()*1.5;
var network = $("#network").val()*1;
var clean = $("#clean").val()*1;
//计算
var i = rent1 + waterMeter + powerMeter + network + clean;
$("#sum_input").val(i);
});
//今月电表数输入框值变化后执行
$("#powerMeter").change(function () {
var rent1 = $("#rent").val()*1;
var waterMeter = $("#waterMeter").val()*2.5;
var powerMeter = $("#powerMeter").val()*1.5;
var network = $("#network").val()*1;
var clean = $("#clean").val()*1;
//计算
var i = rent1 + waterMeter + powerMeter + network + clean;
$("#sum_input").val(i);
});
//网费输入框值变化后执行
$("#network").change(function () {
var rent1 = $("#rent").val()*1;
var waterMeter = $("#waterMeter").val()*2.5;
var powerMeter = $("#powerMeter").val()*1.5;
var network = $("#network").val()*1;
var clean = $("#clean").val()*1;
//计算
var i = rent1 + waterMeter + powerMeter + network + clean;
$("#sum_input").val(i);
});
//添加数据提交
$("#count_house_btn").click(function () {
//判断必填选项是否为空
if (!$("#count_house_HouseId").val()||!$("#counthouse1").val()||!$("#rent").val()||!$("#waterMeter").val()||!$("#powerMeter").val()){
alert("必选内容不能为空!");
return false;
}
var houseId = $("#count_house_HouseId").val();
var yearsMonth = $("#counthouse1").val();
var rent = $("#rent").val()*1;
var waterMeter = $("#waterMeter").val()*2.5;
var powerMeter = $("#powerMeter").val()*1.5;
var network = $("#network").val()*1;
var clean = $("#clean").val()*1;
var sums = $("#sum_input").val()*1;
$.ajax({
type:"post",
url:"/count/add",
dataType : "json",
contentType : "application/json;charset=UTF-8",
data:JSON.stringify({
id:null,
houseId:houseId,
bookerId:null,
yearsMonth:yearsMonth,
rent:rent,
waterMeter:waterMeter,
powerMeter:powerMeter,
network:network,
clean:clean,
sum:sums,
lastMonth:lastMonth
}),
success:function (data) {
if (data.msg === "add") {
$("#counthouse1").val("");
$("#rent").val("");
$("#waterMeter").val("");
$("#powerMeter").val("");
$("#network").val("");
alert("添加成功!");
window.location.href='/count/view';
}else if (data.msg === "out") {
$("#counthouse1").val("");
$("#rent").val("");
$("#waterMeter").val("");
$("#powerMeter").val("");
$("#network").val("");
alert("退房成功!");
window.location.href='/count/view';
// if(data.de1){
// alert("需要向住户返还押金!"+de1+"元!");
// }else if(data.de2){
// alert("押金不够抵押本月房租,需要向住户拿!"+de2+"元!");
// }
}else{
alert("系统出错!");
}
}
});
});
});
控制器:
package com.myhomes.controller;
import com.myhomes.biz.HouseBiz;
import com.myhomes.biz.MonthCostBiz;
import com.myhomes.biz.UserService;
import com.myhomes.entity.House;
import com.myhomes.entity.MonthCost;
import com.myhomes.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("monthCostController")
@RequestMapping(value = "/count")
public class MonthCostController {
@Autowired
private HouseBiz houseBiz;
@Autowired
private UserService userService;
@Autowired
private MonthCostBiz monthCostBiz;
@RequestMapping(value = "/view")
public String click(Model model){
model.addAttribute("houseList",houseBiz.searchAllNotEmptyHouse());
return "count_house";
}
@RequestMapping(value = "/lastMonthMeter")
@ResponseBody
public Map<String,Object> lastMonthMeter(String houseId){
Map<String,Object> map = new HashMap<>();
MonthCost monthCost = monthCostBiz.searchLastMonthMeterByHouseId(houseId);
if (monthCost!=null){
map.put("monthCost",monthCost);
return map;
}else{
map.put("monthCost",null);
return map;
}
}
@RequestMapping(value = "/add")
@ResponseBody
@Transactional
public Map<String,Object> add(@RequestBody Map<String,String> map) throws ParseException {
MonthCost monthCost = new MonthCost();
Map<String,Object> map2 = new HashMap<>();
//先判断提交的月份与上次提交的月份是否一致,如果一致则计算房租并进行退房操作,否则进行计算本月房租操作
//用户提交过来的时间并截取
String userInputMonths = map.get("yearsMonth").substring(0,7);
//进行计算本月房租操作
monthCost.setHouseId(map.get("houseId"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = simpleDateFormat.parse(map.get("yearsMonth"));
monthCost.setYearsMonth(date);
monthCost.setRent(Integer.parseInt(map.get("rent")));
monthCost.setWaterMeter(Double.parseDouble(map.get("waterMeter")));
monthCost.setPowerMeter(Double.parseDouble(map.get("powerMeter")));
monthCost.setNetwork(Integer.parseInt(map.get("network")));
monthCost.setClean(Integer.parseInt(map.get("clean")));
monthCost.setSum(Double.parseDouble(map.get("sum")));
//monthCost.setDeposit(150);
House house = houseBiz.searchByHouseIdName(monthCost.getHouseId());
monthCost.setBookerId(house.getBookerId());
monthCostBiz.addMonthCost(monthCost);
//上月提交时间并截取
String lastMonths = map.get("lastMonth");
//要判断房间上次计算房租是否为空
//进行年月判断
if (lastMonths.substring(0,7).equals(map.get("yearsMonth").substring(0,7))){
//计算房租并进行退房操作,需要改用户表的用户类型为前任租客,添加修改退房时间和房间表入住状态为空
house.setBookerId(null);
houseBiz.editTheBookerId(house);
//修改users表
User user = userService.searchByUserClassHouseId(3,map.get("houseId"));
user.setUserClass(4);
user.setOutTime(date);
userService.editUser(user);
map2.put("msg","out");
return map2;
}
map2.put("msg","add");
return map2;
}
}