java实训小组合作小项目 爱购网 之 用户地址管理模块实现
要求:
使用maven进行一个项目的管理
通过mybatis连接数据库
使用servlet实现前后端数据的交互
实现用户地址的展示、插入、删除、修改操作
每个用户只能存有五个地址
支持用户将地址设为默认地址(且每个用户只有一个默认地址)
结果图:
1.项目业务逻辑分析:
理清所负责模块需要实现的功能和细节
2.按照小组基本规则实现项目
进行小组项目 注意 提前按小组建好规范 方便小组项目日后的整合。
基本的maven+web项目的建立参照之前所写的 宠物商店博客 下面展示本次 项目地 址管理模块 一些主要难点实现细节。
(1)单选框值的读取方式
<input type="checkbox" value="uncheck" onclick="this.value=(this.value=='uncheck')?'checked':'uncheck'" name="isDefault"/>
直接给单选框的选中 给予一个初值 checked 意味选中其 name为 isDefalut的控件对应值为 checked ,后端对控件 checkBox的值进行读取
String isDefault = req.getParameter("isDefault");
// 判断默认地址CheckBox是否选中 选中参数设为1 否则为-1
if ("checked".equals(isDefault)){
receivingDefault = 1;
// 设置其他地址为非默认 测试代码 用户未传入
AddressUtil.setAllAddressIsUnDefault();
}
(3)对数据库的内容进行循环读取,展示到前端
前端部分:
<c:forEach var = "address" items="${addresss}">
<tr>
<td>${address.getReceivingPerson()}</td>
<td>${address.getReceivingAddress()}</td>
<td>${address.getmobilePhone()}</td>
<td><a href="/getUpdateId.do?id=${address.id}">修改</a>|<a href="/delAddress.do?id=${address.id}">删除</a></td>
<%-- 判断 是否为默认地址 选择不同的标签--%>
<c:choose>
<c:when test="${address.isDefault == 1}"><td class="default-on">默认地址</td></c:when>
<c:otherwise> <td><a href="/setDefault.do?id=${address.id}">设为默认</a></td></c:otherwise>
</c:choose>
</tr>
</c:forEach>
后端对应servlet部分:
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 列表的刷新
// 将查询的集合保存到request中
List<Address> addresss = AddressUtil.showAllAddress();
req.setAttribute("addresss",addresss);
req.getRequestDispatcher("deliverAddress.jsp").forward(req,resp);
问题解决:前后端交互时,所传的信息 出现的字符为乱码
前端添加代码:
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
rsp.setContentType("text/html;charset=utf-8");
后端添加代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
(4)删除、修改功能通过超链接实现同一列操作的绑定
效果图
同行实现对指定行的删除、修改等操作时,需要传入一定的参数给后端,实现后端对前端的操作精确地定位。
<td><a href="/getUpdateId.do?id=${address.id}">修改</a>|<a href="/delAddress.do?id=${address.id}">删除</a></td>
前端点击删除 修改连接的同时 可以向绑定的前端 delAddress.do 的servlet类 传值 id 后端读取到 id 后可以对指定行进行操作。
@WebServlet("/delAddress.do")
public class DelAddressServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 读取对应商品的id
String id = req.getParameter("id");
// 调用mapper 实现数据库内容删除
AddressUtil.deleteAddressById(id);
// 请求跳转到 原界面 实现刷新
req.getRequestDispatcher("deliverAddress.do").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
(5)地址管理中的下拉框的赋值 与 修改的回显问题
赋值:结合前端知识,使用 js 枚举的方式实现下拉框的选项填充
对应HTML块
<div class="add-area">
<label>地址信息:</label>
<div id="area"></div> // 此处对应地址的下拉框,事项通过id 绑定js
</div>
js文件:
var city = [
{
"name": "北京", "city": [
{ "name": "北京市", "area": ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区", "密云区", "延庆区", "其他区"] }
]
}];
var sheng = document.createElement("select");
var shi = document.createElement("select");
var qu = document.createElement("select");
var area = document.getElementById("area");
area.appendChild(sheng);
area.appendChild(shi);
area.appendChild(qu);
// 前端读取就是此处的 name 对应的值
sheng.name = "sheng";
shi.name = "shi";
qu.name = "qu";
sheng.options[0] = new Option("请输入省");
shi.options[0] = new Option("请输入市");
qu.options[0] = new Option("请输入区");
sheng.options[0].value = "-1";
shi.options[0].value = "-1";
qu.options[0].value = "-1";
// 循环第一步,把省循环进select
for (var i = 0; i < city.length; i++) {
sheng.options[sheng.length] = new Option(city[i].name);
sheng.options[i+1].value = city[i].name;
// 循环第二步,把所有的市都循环进select
sheng.onchange = function(){
shi.options.length = 0;
shi.options[shi.length] = new Option("请输入市");
shi.options[0].value = "-1";
for (var j = 0; j < city[sheng.selectedIndex-1].city.length; j++) {
shi.options[shi.length] = new Option(city[sheng.selectedIndex-1].city[j].name);
shi.options[j+1].value = city[sheng.selectedIndex-1].city[j].name;
}
}
shi.onchange = function(){
qu.options.length = 0;
qu.options[qu.length] = new Option("请输入区");
qu.options[0].value = "-1";
for (var k = 0; k < city[sheng.selectedIndex-1].city[shi.selectedIndex-1].area.length; k++) {
qu.options[qu.length] = new Option(city[sheng.selectedIndex-1].city[shi.selectedIndex-1].area[k]);
qu.options[k+1].value = city[sheng.selectedIndex-1].city[shi.selectedIndex-1].area[k];
};
}
};
问题出现
后端servlet 读取前端已经起名好的sheng shi qu 时读不进值 清楚浏览器记录再试即可。
回显下拉框内容:
重新建一个 update.js实现下拉框的同时,对其初值进行一个设置
下拉框的实现见上,初值的回显设置如下:
设置 id 对其值通过 id 获取
sheng.id = "sheng";
shi.id = "shi";
qu.id = "qu";
var oldsheng = document.getElementById("sheng").value;
var oldshi = document.getElementById("shi").value;
var oldqu = document.getElementById("qu").value;
sheng.options[0] = new Option(oldsheng);
shi.options[0] = new Option(oldshi);
qu.options[0] = new Option(oldqu);
sheng.options[0].value = oldsheng;
shi.options[0].value = oldshi;
qu.options[0].value = oldqu;
在对应的前端 jsp中隐藏好对应id的变量 即在update.jsp 修改页面
<input type="hidden" id="sheng" value="${sheng}">
<input type="hidden" id="shi" value="${shi}">
<input type="hidden" id="qu" value="${qu}">
在后端将上一个页面的对应值 回显到 更新页面
获取上一页面值 GetUpdateServlet
// 回显数据
req.setAttribute("sheng",sheng);
req.setAttribute("shi",shi);
req.setAttribute("qu",qu);
req.setAttribute("detailAddress",detailAddress);
// 请求跳转 带回显信息的更新信息页面
req.getRequestDispatcher("/update.jsp").forward(req,resp);
实现地址的修改操作 UpdateServlet类 , 即获取表单的内容实现地址的修改
(6)其他知识
要在前端用到 taglib标签时 需要提前在jsp页面 声明如下
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
用到的taglib 标签
<c:forEach var = "address" items="${addresss}">
<tr>
<td>${address.getReceivingPerson()}</td>
<td>${address.getReceivingAddress()}</td>
<td>${address.getmobilePhone()}</td>
<td><a href="/getUpdateId.do?id=${address.id}">修改</a>|<a href="/delAddress.do?id=${address.id}">删除</a></td>
<%-- 判断 是否为默认地址 选择不同的标签--%>
<c:choose>
<c:when test="${address.isDefault == 1}"><td class="default-on">默认地址</td></c:when>
<c:otherwise> <td><a href="/setDefault.do?id=${address.id}">设为默认</a></td></c:otherwise>
</c:choose>
</tr>
</c:forEach>
第一次小组完成项目心得:
按小组规范进行编程,对后期的项目整合极有好处。