一. 储备知识

1.1 添加功能的设计思想

创建book_add.jsp页面+修改表单提交的地址为BookManagerServlet,并且数据提交给addBook方法处理表单中的请求参数名必须和Book类的属性名一致

1.2 实现的步骤

  1. 创建book_add.jsp页面+修改表单提交的地址为BookManagerServlet,并且数据提交给addBook方法处理
  2. 修改book_manager.jsp页面中的添加图书超链接,点击跳转到book_add.jsp页面
  3. 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;
	 }
	
	
	
}