一. 储备知识
1.1 添加功能的设计思想
创建book_add.jsp页面+修改表单提交的地址为BookManagerServlet,并且数据提交给addBook方法处理表单中的请求参数名必须和Book类的属性名一致
1.2 实现的步骤
- 创建book_add.jsp页面+修改表单提交的地址为BookManagerServlet,并且数据提交给addBook方法处理
- 修改book_manager.jsp页面中的添加图书超链接,点击跳转到book_add.jsp页面
- BookManagerServlet中创建addBook方法处理添加图书的请求
addBook中获取图书的参数太多,可以使用第三方工具BeanUtils解决
(1)BeanUtils可以将map中的键值对的值设置给一个JavaBean(map中item的键必须和JavaBean的属性名一致)注意:用第三方工具BeanUtils要导入一个logging依赖包
(2)post请求乱码需要解决:在BaseServlet中的doGet方法中第一行设置
request.setCharacterEncoding("UTF-8");
(3)将BeanUtils给对象设置属性值的代码提取到工具方法中(优化代码)
4. 处理完成后重定向到BookManagerServlet的getAllBooks方法再转发到图书显示页面
二. 源码例子
BookManager.java
package com.atguigu.bookstore.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
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.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.service.BookService;
import com.atguigu.bookstore.service.impl.BookServiceImpl;
import com.atguigu.bookstore.utils.WebUtils;
/**
* Servlet implementation class BookManagerServlet
*/
public class BookManagerServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
private BookService service = new BookServiceImpl();
/**
* 处理添加图书的请求
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void addBook(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
//1.获取请求参数
//参数1:要设置属性的对象 参数2:数据源map[map中的key和对象的属性名必须对应]
Book book = WebUtils.params2Bean(new Book(), request);
System.out.println(book);
//2.调用service处理业务
boolean b = service.addBook(book);
//3.根据处理结果给用户响应
//重定向到BookManagerServlet.getAllBooks
response.sendRedirect(request.getContextPath() + "/BookManagerServlet?type=getAllBooks");
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void getAllBooks(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.获取请求参数
//2.调用其他类处理业务
List<Book> list = service.getAllBooks();
//将数据存到域中共享
request.setAttribute("list", list);
//3.给用户响应[转发(使用request域进行转发)、重定向、response对象向响应体写入内容]
//将集合数据交给book_manager.jsp页面显示
//转发到book_manager.jsp
request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request, response);
}
}
book_add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>添加图书</title>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/baozhatanglogo.jpg" >
<span class="wel_word">添加图书</span>
<%@ include file="/WEB-INF/include/manager_header.jsp" %>
</div>
<div id="main">
<form action="BookManagerServlet" method="post">
<!-- 隐藏域携带type参数 -->
<input type="hidden" name="type" value="addBook">
<!-- 通过隐藏域给图书携带一个默认的封面地址 -->
<input type="hidden" name="imgPath" value="/static/img/default.jpg">
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
<td><input name="title" type="text" value="${requestScope.book.title }"></td>
<td><input name="price" type="text" value="${requestScope.book.price }"></td>
<td><input name="author" type="text" value="${requestScope.book.author }"></td>
<td><input name="sales" type="text" value="${requestScope.book.sales }"></td>
<td><input name="stock" type="text" value="${requestScope.book.stock }"></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
</div>
<div id="bottom">
<span>
一流爆炸糖书城.Copyright ©2019
</span>
</div>
</body>
</html>
book_manager.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<%@ include file="/WEB-INF/include/base.jsp" %>
<script type="text/javascript">
/*给删除超链接绑定删除事件*/
$(function(){
$(".delA").click(function(){
//由于a标签遍历显示图书时会产生多个,所以不能使用id属性
//获取被点击的a标签所在行的第一个单元格的文本内容,即a标签的爹(td标签)的爹(tr标签)的第一个儿子(即tr中的第一个td标签)
//this为a标签的dom对象,$(this)为将dom对象转换为jquery对象
var title = $(this).parents("tr").children("td:eq(0)").text();
if(! confirm("你真的要删除《" + title + "》吗?")){
//取消删除,阻止a标签的默认行为
return false;
}
});
});
</script>
</head>
<body>
<div id="header">
<div class="logo_content">
<div class="logo_img">
<img src="static/img/baozhatanglogo.jpg" alt="" width="30px">
</div>
<span>欢迎来到一流爆炸糖书城</span>
</div>
<div class="header_content">
<a href="">设置</a> |
<a href="">退出</a>
</div>
</div>
<div id="main">
<c:choose>
<c:when test="${empty requestScope.list }">
<%-- ${empty requestScope.list } 判断查询所有的图书集合 --%>
<h3 style="color:red; text-align:center; margin-top: 150px;">没有图书数据!赶紧去添加吧!<a href="pages/manager/book_add.jsp">添加图书</a></h3>
</c:when>
<c:otherwise>
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<!-- 遍历图书集合,每本图书数据对应一行显示 -->
<c:forEach items="${list }" var="book">
<td>${book.title }</td>
<td>${book.price }</td>
<td>${book.author }</td>
<td>${book.sales }</td>
<td>${book.stock }</td>
<td><a href="pages/manager/book_edit.jsp">修改</a></td>
<td><a class="delA" href="BookManagerServlet?type=deleteBook&bookId=${book.id }">删除</a></td>
</c:forEach>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a href="pages/manager/book_add.jsp">添加图书</a></td>
</tr>
</table>
</c:otherwise>
</c:choose>
</div>
<div id="bottom">
<span>
一流爆炸糖书城.Copyright ©2019
</span>
</div>
</body>
</html>
BaseServlet.java
package com.atguigu.bookstore.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class BaseServlet
*/
public class BaseServlet extends HttpServlet {
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//解决post请求乱码
request.setCharacterEncoding("UTF-8");
//获取type参数:对应方法名
String type = request.getParameter("type");
//获取子类的类型:this:BaseServlet不会创建对象,this代表子类的Servlet的对象
Class<? extends BaseServlet> cla = this.getClass();
//获取类模板中的type方法
try {
Method method = cla.getDeclaredMethod(type, HttpServletRequest.class, HttpServletResponse.class);
//调用方法
method.invoke(this, request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
WebUtils.java
package com.atguigu.bookstore.utils;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.BeanUtils;
import com.atguigu.bookstore.bean.Book;
public class WebUtils {
/**
* BeanUtils根据请求参数的key自动将值设置给对象的工具方法
* 1.请求参数的key必须和对象的属性名一致
* 2.一个初始化过的对象
* 3.数据源[map]
*/
public static <T>T params2Bean(T t, HttpServletRequest request) {
//1.获取数据源
Map<String, String[]> map = request.getParameterMap();
//2.使用BeanUtils将map中的值设置给book对象
try {
BeanUtils.populate(t, map);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return t;
}
}