MVC设计模式案例(下)
标签(空格分隔): JavaWeb
Servlet之删除操作
在查询到的表格中进行删除,涉及到删除指定id的数据。如何使servlet获取到jsp中的id?使用Parameter参数进行交互。
我们通过获取Parameter参数(也就是路径问号后面的参数)来获取要删除的id,通过<%=%>
的方式获取id
超链接:
<a href="delete.do?id=<%=customer.getId()%>">DELETE</a>
Servlet的delete方法:
1. 获取id
2. 调用DAO执行删除
3. 重定向到query.do(若目标页面不需要读取当前请求的request属性,就可以重定向), 将显式删除后的Customer对象
private void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("delete");
//获取jsp传递的参数(字符串类型)
String idStr = request.getParameter("id");
int id = 0;
//trycatch的作用是为了防止idStr不能被转为Integer
//若不能转则id=0,无法进行任何删除操作
try {
id = Integer.parseInt(idStr);
customerDAO.delete(id);
} catch (Exception e) {}
response.sendRedirect("query.do");
}
Servlet之添加
该操作为在index.jsp页面中的点击,跳转到添加页面,并填写信息向数据表中添加一条数据。若name已经被占用则显示提示信息,之前填写的信息回显。若可以添加,则添加成功后返回一个成功页面。
步骤
- 给index.jsp中的超链接添加一个地址:add.jsp
- 创建add.jsp页面,输入参数,提交按钮,表单的action转为add.do
- 在CustomerServlet中写add方法,作为add.do的响应
- 获取表单参数
- 判断name是否已经被占用
- 若验证不通过,则返回add.jsp页面,提示信息,回显参数
- 若验证通过,则把表单参数封装为一个Customer对象customer
- 调用customerDAO的save(customer)执行保存操作
- 重定向到addSuccess.jsp页面
- addSuccess.jsp页面提示信息,并提供返回
add.jsp
对于写add.jsp除了写一个显式的表单外,有两点需要注意:
一是如果name被占用,返回到该界面的时候会显示一个提示信息。我们将该提示信息,通过属性以setAttribute()的方式,封装成一个字符串。然后我们在jsp中写java代码进行判断:如果我们获取到的对象不是null,则显式这个字符串。
二是如果name被占用,那么需要回显之前写的内容。也就是在value属性上,我们要获取之前表单提交的Parameter参数,如果我们仅这么写,那么在还没填写的时候,显示null而不是空白,因此我们要进行一个判断。
要注意的一点是:包裹java代码的<%=%>
写在value=""
分号中。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object msg = request.getAttribute("message");
if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<%
}
%>
<form action="add.do" method="post">
<table>
<tr>
<td>CustomerName:</td>
<td><input type="text" name="name"
value="<%= request.getParameter("name") == null ? "" : request.getParameter("name")%>"
/></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="address"
value="<%= request.getParameter("address")==null ? "" : request.getParameter("address") %>"/></td>
</tr>
<tr>
<td>Phone:</td>
<td><input type="text" name="phone"
value="<%= request.getParameter("phone")==null ? "" : request.getParameter("phone") %>"/></td>
</tr>
<tr>
<td><input type="submit" value="Add"/></td>
</tr>
</table>
</form>
</body>
</html>
add方法
检查用户名是否被占用,是一个与之前操作不同的地方。
- 通过调用CustomerDAO的getCountWithName(String name)获取该name在数据库中存在的个数
- 如果返回值大于0,说明name不存在,则响应add.jsp页面
- 要求在add.jsp显示一个错误信息,在这种情况下我们应该使用Attribute属性(因此我们要设立,而Parameter没有set方法)即在request上放一个属性message来显示(在jsp中通过get方法进行获取)。
- 要求add.jsp的表单值可以回显(这一步是在jsp上进行操作)。
- 通过转发的方式响应add.jsp,因为我们还需要使用request,因此使用转发,保证这是一次请求。
- return结束该方法(不进行下面的操作)。
- 若验证通过把表单参数封装为一个Customer对象customer
- 调用customerDAO的save(customer)执行保存操作
- 重定向到addSuccess.jsp页面:使用重定向可以避免表单重复提交的问题(如果是转发,在添加成功之后再点刷新,表单会重复提交)
private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取表单参数:name,address,phone
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone");
//2. 检验name是否已经被占用
//2.1 调用CustomerDAO的getCountWithName(String name)获取该name在数据库中存在的个数
long count = customerDAO.getCountWithName(name);
//2.2 如果返回值大于0,则说明该name不存在,响应add.jsp页面
if (count > 0) {
//2.2.1 要求在add.jsp显示一个错误信息,即在request上放一个属性message来显式
request.setAttribute("message","用户" + name + "已存在!");
//2.2.2 add.jsp的表单值可以回显(在jsp上进行操作)
//通过 value="<%= request.getParameter("name") == null ? "" : request.getParameter("name") %>"进行回显
//2.2.3 通过转发的方式响应add.jsp,然后结束该方法
request.getRequestDispatcher("/add.jsp").forward(request,response);
return;
}
// 若验证通过把表单参数封装为一个Customer对象customer
Customer customer = new Customer(name,address,phone);
//调用customerDAO的save(customer)执行保存操作
customerDAO.save(customer);
//重定向到addSuccess.jsp页面:使用重定向可以避免表单重复提交的问题
response.sendRedirect("addSuccess.jsp");
}
有一点需要注意:
当我们封装一个对象的时候,是通过构造函数拉起传递获取的参数的,因此在Customer类中应该创建一个带参数的构造函数。然后!记得再创建一个无参的构造函数,否则会出现错误。
Servlet之修改
修改一条数据对象,一共分为两步骤:
1. 点击要修改条目的修改按钮,通过edit方法将该对象的信息显示到update.jsp上
2. 在update上写好信息之后点击更改按钮,用过update方法进行更改
edit方法
UPDATE的超链接(需要获取id,通过id来确定修改哪个),跳转到servlet页面,执行edit方法
<a href="edit.do?id=<%=customer.getId()%>">UPDATE</a>
edit方法:
获取id,调用CustomerDAO的方法获取id对应的Customer对象,将Customer对象放入request中,然后响应updateCustomer.jsp页面(转发)
步骤如下:
1. 获取当前对象的id
2. 通过customerDAO的get(id)方法获取该id对应的Customer对象
3. 如果Customer对象不为null,说明传入的id是正确的
4. 将customer对象作为属性,传递给update.jsp
5. 请求转发到update.jsp
private void edit(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
String forwardPath = "/error.jsp";
//获取当前对象的id
String idStr = request.getParameter("id");
try {
//通过customerDAO的get(id)方法获取该id对应的Customer对象
Customer customer = customerDAO.get(Integer.parseInt(idStr));
//如果customer对象不为null,说明id传入是正确的
if (customer != null) {
//将路径更改为要传递的路径
forwardPath = "/update.jsp";
//将customer对象作为属性,要传递给update.jsp页面
request.setAttribute("customer",customer);
}
} catch (NumberFormatException e) {
}
//请求转方法到update.jps页面
request.getRequestDispatcher(forwardPath).forward(request,response);
}
update.jsp
JSP页面:
获取请求域中Customer对象,调用对应的字段中的get()方法来显示值。
wo我们修改Customer对象,需要在数据库中找到这条数据,需要使用id。但是我们在界面上是不显示id的,这里我们就需要使用隐藏域来获取Customet对象的id。
关于隐藏域,与其他表单域一样可以被提交到服务器,但是在页面上不显示。
同样的,在回显的时候,我们需要知道原name不能丢失,因此我们也需要使用隐藏域来保存oldName。提交到update.do
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object msg = request.getAttribute("msg");
if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<% } %>
<%
Customer customer = (Customer) request.getAttribute("customer");
%>
<form action="update.do" method="post">
<input type="hidden" name="id" value="<%=customer.getId()%>"/>
<input type="hidden" name="oldName" value="<%=customer.getName()%>"/>
<table>
<tr>
<td>CustomerName:</td>
<td><input type="text" name="name"
value="<%=customer.getName()%>"
/></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="address"
value="<%=customer.getAddress()%>"
/></td>
</tr>
<tr>
<td>Phone:</td>
<td><input type="text" name="phone"
value="<%=customer.getPhone()%>"
/></td>
</tr>
<tr>
<td><input type="submit" value="Update"/></td>
</tr>
</table>
</form>
</body>
</html>
update方法
update方法是修改操作。在update.jsp页面上填完信息后提交表单,在servlet中,通过update方法对封装好的对象进行修改。
在update方法中,需要对name进行验证。与添加操作的验证不同的是:
此时有可能修改name,也有可能没修改name,如果没有修改,在数据库中有该name,不算重复。
因此需要进行一个判断:
获取隐藏域中的oldName作为待比较的对象,如果修改了name,则在数据库中进行比对;如果没修改name,则不用进行比对。
在回显的时候,address,phone显示表单提交的新值,name回显oldName
如果通过验证,则封装对象,执行update操作,返回重定向到query.do
其步骤如下:
- 获取表单参数
- 对name进行检验,是否被占用
2.1 比较name和oldName是否相同,如果相同,则当前name可用
2.2 如果不同则要在数据空中查找该name是否被占用
2.3 如果name被占用,则说明封装提示纤细,然后请求转发到jsp页面,并结束方法 - 如果检验通过,则封装参数为customer对象
- 调用CustomerDAO的update方法
- 请求重定向
private void update(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//1. 获取表单参数
String oldName = request.getParameter("oldName");
String id = request.getParameter("id");
String name = request.getParameter("name");
String address = request.getParameter("address");
String phone = request.getParameter("phone");
//2. 对name进行检验,是否被占用
//2.1 比较name和oldName是否相同,如果相同,则当前name可用
//2.2 如果不同,则要在数据库中查找该name是否被占用
if (!name.equalsIgnoreCase(oldName)) {
//2.3 如果name被占用,则将进行一系列操作并最终转到update.jsp
long count = customerDAO.getCountWithName(name);
if (count > 0) {
//2.3.1 封装一个用于提示的信息msg
String msg = "用户名" + name + "被占用!";
request.setAttribute("msg",msg);
//2.3.2 表单值进行回显,name使用oldName(否则会丢失),address,phone写新的
//这步在jsp中进行操作
//2.3.3 通过请求转发的方式到update.jsp
request.getRequestDispatcher("/update.jsp").forward(request,response);
//2.3.4 return结束方法
return;
}
}
//3. 如果name通过验证,将获取到的表单参数封装成Customer对象
Customer customer = new Customer(id,name,address,phone);
//4. 调用CustomerDAO的update方法
customerDAO.update(customer);
//5.请求重定向,避免表单重复提交
response.sendRedirect("query.do");
}
问题
这是我们发现,我们在修改操作的时候,当我们修改name的时候,发现在name被占用的时候会出现异常。
这个异常出现在哪?通过调试。在name被占用的时候,请求转发有问题,更具体的说是此时update.jsp页面有问题。
为什么出现异常?
因为,当用户名被占用时,从表单获取到的参数对应的对象在数据库中是不存在的,因此在请求转发到update.jsp中,对于input中的value="<%=customer.getId()%>"
实际上是获取不到的,因此我们要在update.jsp中进行一个判断:
当customer不为null时,获取该对象的customer;当customer为null时,获取之前表单提交的Parameter参数
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object msg = request.getAttribute("msg");
if(msg != null){
%>
<br>
<font color="red"><%= msg %></font>
<br><br>
<%
}
%>
<%
String id = null;
String name = null;
String oldName = null;
String address = null;
String phone = null;
Customer customer = (Customer) request.getAttribute("customer");
if (customer != null) {
id = String.valueOf(customer.getId());
name = customer.getName();
oldName = customer.getName();
address = customer.getAddress();
phone = customer.getPhone();
} else {
id = request.getParameter("id");
oldName = request.getParameter("oldName");
name = request.getParameter("name");
address = request.getParameter("address");
phone = request.getParameter("phone");
}
%>
<form action="update.do" method="post">
<input type="hidden" name="id" value="<%=id%>"/>
<input type="hidden" name="oldName" value="<%=oldName%>"/>
<table>
<tr>
<td>CustomerName:</td>
<td><input type="text" name="name"
value="<%=name%>"
/></td>
</tr>
<tr>
<td>Address:</td>
<td><input type="text" name="address"
value="<%=address%>"
/></td>
</tr>
<tr>
<td>Phone:</td>
<td><input type="text" name="phone"
value="<%=phone%>"
/></td>
</tr>
<tr>
<td><input type="submit" value="Update"/></td>
</tr>
</table>
</form>
</body>
</html>