继续来做Javaweb的案例练习,本篇学习如何修改一本书的信息。在图书列表页,表格中点击某一本书的编辑链接,然后用户就可以修改图书信息,就是这么一个场景。
1.修改思路分析
首先,来看看修改图书的思路分析,要如何跳转,用几个servlet,都在下图
看这张图左边部分,首先用户在list.jsp中点击修改菜单,这个时候需要把图书的id传给findBookByIdServlet,然后根据id去查询数据库,拿到这本书的全部信息,然后相关字段回显到edit.jsp,用户可以随便改里面数据,点击保存,就跳转到updateBookServlet,然后调用Dao层的update相关方法去更新数据表信息,完成这个过程。
2.什么是回显?
在list.jsp点击编辑,我们看到是一个和新增图书差不多的页面,唯一区别就是标题显示这个是修改页面,这种就是表单数据没有回显给用户,用户进来什么信息都看不到,不好做信息修改操作,很差的体验,所以我们需要回显数据。
上面如果不是编辑商品几个字,用户还以为是新增图书的页面呢?
3.完成数据回显
3.1 修改list.jsp中修改链接跳转到findBookByIdServlet, 在list.jsp中大概在133-135行,修改下edit的跳转链接。
<a href="${pageContext.request.contextPath}/findBookByIdServlet?id=${b.id}">
3.2 新建一个findBookByIdServlet的servlet
在com.anthony.web.servlet包下新建这个servlet类,Eclipse新建servlet会自动配置web.xml,这个前提是创建java web动态项目,选择j2ee 2.5版本。这个代码,我们暂时不写,我们先需要完成Dao层,然后Service层,然后再回来写servlet代码。
3.3 Dao接口和具体实现类添加根据id查找图书方法
package com.anthony.dao;
import java.sql.SQLException;
import java.util.List;
import com.anthony.domain.Book;
public interface BookDao {
/**
* 查询所有书
* @return
* @throws SQLException
*/
public List<Book> findAllBooks() throws SQLException;
/**
* 添加图书
* @throws SQLException
*/
public void addBook(Book book) throws SQLException;
/**
* 根据id查询图书
* @param id
* @return
* @throws SQLException
*/
public Book findBookById(String id) throws SQLException;
}
具体实现类方法
package com.anthony.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.anthony.datasource.C3P0Utils;
import com.anthony.domain.Book;
public class BookDaoImpl implements BookDao {
public List<Book> findAllBooks() throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
List<Book> query = qr.query("select * from book", new BeanListHandler<Book>(Book.class));
return query;
}
public void addBook(Book book) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
qr.update("INSERT INTO book VALUES(?,?,?,?,?,?)", book.getId(),book.getName(),book.getPrice(),book.getPnum(),book.getCategory(),book.getDescription());
}
public Book findBookById(String id) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
Book book = qr.query("select * from book where id=?", new BeanHandler<Book>(Book.class),id);
return book;
}
}
3.4 service层添加相关方法
package com.anthony.service;
import java.util.List;
import com.anthony.domain.Book;
public interface BookService {
public List<Book> findAllBooks();
public void addBook(Book book);
public Book findBookById(String id);
}
package com.anthony.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.anthony.datasource.C3P0Utils;
import com.anthony.domain.Book;
public class BookDaoImpl implements BookDao {
public List<Book> findAllBooks() throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
List<Book> query = qr.query("select * from book", new BeanListHandler<Book>(Book.class));
return query;
}
public void addBook(Book book) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
qr.update("INSERT INTO book VALUES(?,?,?,?,?,?)", book.getId(),book.getName(),book.getPrice(),book.getPnum(),book.getCategory(),book.getDescription());
}
public Book findBookById(String id) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
Book book = qr.query("select * from book where id=?", new BeanHandler<Book>(Book.class),id);
return book;
}
}
3.5 findBookByIdServlet代码如下
package com.anthony.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.anthony.domain.Book;
import com.anthony.service.BookService;
import com.anthony.service.BookServiceImpl;
public class FindBookByIdServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
BookService bs = new BookServiceImpl();
Book book = bs.findBookById(id);
//转发,book放入request域中
request.setAttribute("book", book);
request.getRequestDispatcher("/admin/products/edit.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
3.6 修改edit.jsp
在edit.jsp,用${book.id}来替换原来name值,全部替换需要修改的地方的字段值,这样达到字段回显效果。这里能直接用book这个变量,是因为我们在上面servlet中添加到了request域对象中,然后转发过来,所以edit.jsp能直接使用book。
44-46行找到商品名称代码,修改如下
<td align="center" bgColor="#f5fafe" class="ta_01">商品名称:</td>
<td class="ta_01" bgColor="#ffffff"><input type="text"
name="name" class="bg" value="${book.name}" /></td>
然后商品价格
<td align="center" bgColor="#f5fafe" class="ta_01">商品价格:</td>
<td class="ta_01" bgColor="#ffffff"><input type="text"
name="price" class="bg" value="${book.price}" /></td>
商品数量
<td align="center" bgColor="#f5fafe" class="ta_01">商品数量:</td>
<td class="ta_01" bgColor="#ffffff"><input type="text"
name="pnum" class="bg" value="${book.pnum}" /></td>
商品描述
<TD class="ta_01" align="center" bgColor="#f5fafe">商品描述:</TD>
<TD class="ta_01" bgColor="#ffffff" colSpan="3"><textarea
name="description" cols="30" rows="3" style="WIDTH: 96%">${book.description}</textarea>
</TD>
商品类别有点复杂,先不改动,重启tomcat服务器,然后看看点击编辑进来页面的回显效果。
接下来看看商品类别
这个需要js代码来支持,在这个案例素材中,已经写好了这个js代码,我们只需要调用下就可以。edit.jsp中16-31行代码
//设置类别的默认值
function setProductCategory(t) {
var category = document.getElementById("category");
var ops = category.options;
for ( var i = 0; i < ops.length; i++) {
if (ops[i].value == t) {
ops[i].selected = true;
return;
}
}
};
</script>
<body onload="setProductCategory('${book.category}')">
<form id="userAction_save_do" name="Form1"
再来看看图书类别这个点击编辑,会不会自动显示之前设置的类别
我之前代码中写的是编程语言这么一个类别,这个和edit.jsp中类别不一致,所以需要到数据库表改成计算机。
点击上面编辑菜单
这个类别 计算机是自动出来,不是人工点出啦,说明字段回显做完了。
4.完成UpdateBookServlet功能
在edit.jsp中提交跳转我们需要修改,跳转到/updateBookServlet,这个servlet类我们还没有创建,但是我们先来看一个问题,那就是如果把id传给/updateBookServlet, 因为在执行SQL的update语句where条件是book的id,所以我们需要在edit.jsp页面就想办法把id传递给/updateBookServlet,下面创建一个隐藏的id控件来接受id的value. 31-34行代码
<body onload="setProductCategory('${book.category}')">
<form id="userAction_save_do" name="Form1"
action="${pageContext.request.contextPath}/updateBookServlet" method="post">
<input type="hidden" name="id" value="${book.id}"/>
4.1 创建一个空的UpdateBookServlet.java
在com.anthony.web.servile新建一个UpdateBookServlet.java,url映射是updateBookServlet
4.2 写Dao层代码
在这个接口中添加这个方法
public void updateBook(Book book) throws SQLException;
具体实现类新增以下方法
public void updateBook(Book book) throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
qr.update("update book set name=?, price=?, pnum=?, category=?, description=? where id=?",
book.getName(),book.getPrice(),book.getPnum(),book.getCategory(),book.getDescription(),book.getId());
}
4.3 写service层代码
BookService接口中新加这个方法
public void updateBook(Book book);
具体实现类新加这个方法
public void updateBook(Book book) {
try {
bd.updateBook(book);
} catch (SQLException e) {
e.printStackTrace();
}
}
4.4 写web层中servlet代码
package com.anthony.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import com.anthony.domain.Book;
import com.anthony.service.BookService;
import com.anthony.service.BookServiceImpl;
public class UpdateBookServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
Book book = new Book();
try {
BeanUtils.populate(book, request.getParameterMap());
} catch (Exception e) {
e.printStackTrace();
}
BookService bs = new BookServiceImpl();
bs.updateBook(book);
//跳转
request.getRequestDispatcher("/bookListServlet").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
重启tomcat服务器之后,可以进行测试了。