Java Web基础入门第九十一讲 在线网上书店(六)——实现图书管理模块

后台添加图书

后台要添加图书的时候,应该说明图书的类型是什么。要想在显示添加图书的页面上知道全部类型的id,就要经过Servlet把类型的集合传送过去。
首先,我们要找到后台左侧导航页面——left.jsp,在添加图书的超链接上绑定处理请求的BookServlet。
在这里插入图片描述
然后,在BookServlet中获取到类型的集合,并带到添加图书的页面上。

package cn.liayun.web.manager;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.liayun.domain.Category;
import cn.liayun.service.BusinessService;
import cn.liayun.service.impl.BusinessServiceImpl;

@WebServlet("/manager/BookServlet")
public class BookServlet extends HttpServlet {
	
	private BusinessService service = new BusinessServiceImpl();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method = request.getParameter("method");
		if ("forAddUI".equals(method)) {
			forAddUI(request, response);
		}
	}

	private void forAddUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Category> categories = service.getAllCategory();
		request.setAttribute("categories", categories);
		request.getRequestDispatcher("/manager/addbook.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

紧接着,在manager目录中创建出添加图书的addbook.jsp页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加图书的页面</title>
</head>
<body>
	<br />
	<br />
	<form
		action="${pageContext.request.contextPath }/manager/BookServlet?method=add"
		method="post" enctype="multipart/form-data">
		<table width="500px">
			<tr>
				<td>书名</td>
				<td><input type="text" name="name" style="width: 200px"></td>
			<tr>
			<tr>
				<td>作者</td>
				<td><input type="text" name="author" style="width: 200px"></td>
			</tr>
			<tr>
				<td>售价</td>
				<td><input type="text" name="price" style="width: 200px"></td>
			</tr>
			<tr>
				<td>图片</td>
				<td><input type="file" name="image" style="width: 200px"></td>
			</tr>
			<tr>
				<td>描述</td>
				<td><textarea rows="4" cols="40" name="description"></textarea></td>
			</tr>
			<tr>
				<td>所属分类</td>
				<td>
					<select name="category_id">
						<c:forEach var="category" items="${categories}">
							<option value="${category.id }">${category.name }</option>
						</c:forEach>
					</select>
				</td>
			</tr>
			<tr>
				<td></td>
				<td><input type="submit" value="添加书籍"></td>
			</tr>
		</table>
	</form>
</body>
</html>

从以上页面中,可以看到我们在添加图书的时候,还得添加图片,所以需要在WebRoot根目录下新建一个images目录,用于保存上传的图书图片。
在这里插入图片描述
管理员填写完图书的基本信息,并为图书选择了一张相关图片后,点击添加书籍按钮,就要将请求交给BookServlet,现在我们来编写该Servlet用来处理添加图书请求的代码。

package cn.liayun.web.manager;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.liayun.domain.Book;
import cn.liayun.domain.Category;
import cn.liayun.service.BusinessService;
import cn.liayun.service.impl.BusinessServiceImpl;
import cn.liayun.utils.WebUtils;

@WebServlet("/manager/BookServlet")
public class BookServlet extends HttpServlet {
	
	private BusinessService service = new BusinessServiceImpl();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method = request.getParameter("method");
		if ("forAddUI".equals(method)) {
			forAddUI(request, response);
		}
		if ("add".equals(method)) {
			add(request, response);
		}
	}

	private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			Book book = WebUtils.upload(request, this.getServletContext().getRealPath("/images"));
			service.addBook(book);
			request.setAttribute("message", "添加成功!!");
		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("message", "添加失败!!");
		}
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	private void forAddUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Category> categories = service.getAllCategory();
		request.setAttribute("categories", categories);
		request.getRequestDispatcher("/manager/addbook.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

接着,我们还要在WebUtils工具类中增加一个upload方法,WebUtils工具类内部会从request里面取出数据,除了把上传的图书图片保存下来,并且还会把上传图书信息封装到一个Book对象里面返回给你。

package cn.liayun.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.liayun.domain.Book;
import cn.liayun.domain.Category;
import cn.liayun.service.BusinessService;
import cn.liayun.service.impl.BusinessServiceImpl;

//主要把请求数据封装到一个JavaBean中
public class WebUtils {
	
	public static <T> T request2Bean(HttpServletRequest request, Class<T> beanClass) {
		try {
			T bean = beanClass.newInstance();
			Map<String, String[]> map = request.getParameterMap();
			BeanUtils.populate(bean, map);
			return bean;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public static Book upload(HttpServletRequest request, String uploadPath) {
		try {
			Book book = new Book();
			
			DiskFileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			upload.setHeaderEncoding(request.getCharacterEncoding());
			
			List<FileItem> list = upload.parseRequest(request);
			for (FileItem item : list) {
				if (item.isFormField()) {
					String inputName = item.getFieldName();
					String value = item.getString("UTF-8");
					if ("category_id".equals(inputName)) {
						BusinessService service = new BusinessServiceImpl();
						Category c = service.findCategory(value);
						book.setCategory(c);
					} else {
						BeanUtils.setProperty(book, inputName, value);
					}
				} else {
					String filename = item.getName();//拿到上传文件的名称
					filename = filename.substring(filename.lastIndexOf("\\") + 1);
					String savepath = uploadPath;
					String saveFilename = UUID.randomUUID().toString() + filename;
					
					InputStream in = item.getInputStream();
					FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFilename);
					int len = 0;
					byte[] buffer = new byte[1024];
					while ((len = in.read(buffer)) > 0) {
						out.write(buffer, 0, len);
					}
					out.close();
					in.close();
					
					item.delete();
					book.setImage(saveFilename);
				}
			}
			book.setId(UUID.randomUUID().toString());
			return book;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
}

最后,我们测试一番。
在这里插入图片描述

后台显示图书

找到后台左侧导航页面——left.jsp,在查看图书的超链接上绑定处理请求的BookServlet。
在这里插入图片描述
紧接着,在BookServlet处理显示图书的请求。

package cn.liayun.web.manager;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.liayun.domain.Book;
import cn.liayun.domain.Category;
import cn.liayun.service.BusinessService;
import cn.liayun.service.impl.BusinessServiceImpl;
import cn.liayun.utils.WebUtils;

@WebServlet("/manager/BookServlet")
public class BookServlet extends HttpServlet {
	
	private BusinessService service = new BusinessServiceImpl();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method = request.getParameter("method");
		if ("forAddUI".equals(method)) {
			forAddUI(request, response);
		}
		if ("add".equals(method)) {
			add(request, response);
		}
		if ("list".equals(method)) {
			list(request, response);
		}
	}

	private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Book> list = service.getAllBook();
		request.setAttribute("list", list);
		request.getRequestDispatcher("/manager/listbook.jsp").forward(request, response);
	}

	private void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			Book book = WebUtils.upload(request, this.getServletContext().getRealPath("/images"));
			service.addBook(book);
			request.setAttribute("message", "添加成功!!");
		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("message", "添加失败!!");
		}
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	private void forAddUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		List<Category> categories = service.getAllCategory();
		request.setAttribute("categories", categories);
		request.getRequestDispatcher("/manager/addbook.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

接着,在manager目录中创建出显示图书的listbook.jsp页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>展示后台书籍列表的页面</title>
</head>
<body style="text-align: center">
	<br />
	<br />
	<table border="1px" cellpadding="0" cellspacing="0" width="90%">
		<caption>
			<h2>图书信息</h2>
		</caption>
		<tr>
			<td>书名</td>
			<td>作者</td>
			<td>描述</td>
			<td>图片</td>
			<td>操作</td>
		</tr>

		<c:forEach var="book" items="${list}">
			<tr>
				<td>${book.name }</td>
				<td>${book.author }</td>
				<td>${book.description }</td>
				<td><a
					href="${pageContext.request.contextPath }/images/${book.image }">查看图片</a></td>
				<td><a href="#">修改</a> <a href="#">删除</a></td>
			</tr>
		</c:forEach>
	</table>
	<br />
	<br />
</body>
</html>

从以上页面中可以看到,我们是根据记载在Book对象的图片名称,弄一个超链接,超链接指向服务端的图片,这样就可以查看图片了!温馨提示:在后台展示书籍列表时,我们并没有进行分页。
最后,测试效果如下:
在这里插入图片描述

前台显示图书

看回我们前台页面的成果图,我们可以把整个body页面分成是三个div。

  • body占整个div;
  • 页头是一个div;
  • 显示图书的地方是一个div。

在这里插入图片描述

设计好大概的布局

下面是前台首页中的3个div。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>前台首页</title>
</head>
<body style="text-align: center;">
	<div id="container">
		<div id="head">
			<!-- 静态引入 -->
			<%@include file="/client/head.jsp" %>
		</div>
		
		<div id="main">
			这是展示书籍的地方(包括书籍分类列表和书籍详细信息)
			<div id="categories">
				书籍分类列表:
				......
			</div>
			
			<div id="books">
				书籍详细信息:
				<div id="book">
					<div id="image">
						图书的图片......
					</div>
					<div id="info">
						图书的详细信息......
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

页面中的CSS代码如下:

body {
	margin: 0px;
	padding: 0px;
	text-align: center;
}

#container {
	width: 100%;
	height: 300px;
	/* border: solid 1px red; */
	text-align: left;
}

#main {
	margin-top: 20px;
}

#head {
	text-align: center;
}

#categories {
	border: solid 1px blue;
	width: 250px;
	height: 400px;
	padding-left: 20px;
	line-height: 40px;
	float: left;
}

#books {
	float: left;
	margin-left: 20px;
}

#image {
	float: left;
}

#info {
	float: left;
}

#book {
	float: left;
	width: 350px;
}

获取首页数据

在显示首页的下部分的时候,应该先去寻找一个Servlet来把数据交给对应的JSP。因为我们的JSP一般都是放在WEB-INF下,是不能直接访问的,还有就是JSP往往是需要我们后台的数据的,因此我们使用Servlet来获取得到数据,再交由JSP来展示就最好不过了。
首先,在WebRoot根目录下新建整个网站首页,即index.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>在线网上书店前台进入页面</title>
</head>
<body>
	<jsp:forward page="/client/IndexServlet"></jsp:forward>
</body>
</html>

然后,在cn.liayun.web.client包中新建一个IndexServlet,用于获取首页数据,并将数据交给前台首页来展示。

package cn.liayun.web.client;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.liayun.domain.Category;
import cn.liayun.domain.PageBean;
import cn.liayun.domain.QueryInfo;
import cn.liayun.service.impl.BusinessServiceImpl;
import cn.liayun.utils.WebUtils;

//获取首页数据
@WebServlet("/client/IndexServlet")
public class IndexServlet extends HttpServlet {
	
	private BusinessServiceImpl service = new BusinessServiceImpl();
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//首先看别人有没有带查询条件过来
		QueryInfo info = WebUtils.request2Bean(request, QueryInfo.class);
		String category_id = request.getParameter("category_id");
		//IndexServlet即处理某个分类下面的分页请求,又处理所有的分页请求,所以要判断客户机有没有带category_id过来
		if (category_id != null && !category_id.trim().equals("")) {
			info.setQueryname("category_id");
			info.setQueryvalue(category_id);
		}
		
		List<Category> categories = service.getAllCategory();
		PageBean pageBean = service.bookPageQuery(info);
		
		request.setAttribute("categories", categories);
		request.setAttribute("pageBean", pageBean);
		
		request.getRequestDispatcher("/client/index.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

IndexServlet既处理某个分类下面的分页请求,又处理所有的分页请求,所以要判断客户机有没有带category_id过来。
接下来,在前台首页(即client/index.jsp)中显示数据,如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>前台首页</title>
<style type="text/css">
	body {
		margin: 0px;
		padding: 0px;
		text-align: center;
	}
	
	#container {
		width: 100%;
		height: 300px;
		/* border: solid 1px red; */
		text-align: left;
	}
	
	#main {
		margin-top: 20px;
	}
	
	#head {
		text-align: center;
	}
	
	#categories {
		border: solid 1px blue;
		width: 250px;
		height: 400px;
		padding-left: 20px;
		line-height: 40px;
		float: left;
	}
	
	#books {
		float: left;
		margin-left: 20px;
	}
	
	#image {
		float: left;
	}
	
	#info {
		float: left;
	}
	
	#book {
		float: left;
		width: 350px;
	}
</style>
</head>
<body style="text-align: center;">
	<div id="container">
		<div id="head">
			<!-- 静态引入 -->
			<%@include file="/client/head.jsp" %>
		</div>
		
		<div id="main">
			<div id="categories">
				书籍分类列表:
				<c:forEach var="c" items="${categories }">
					<li><a href="${pageContext.request.contextPath }/client/IndexServlet?category_id=${c.id }">${c.name }</a></li>
				</c:forEach>
			</div>
			
			<div id="books">
				<c:forEach var="book" items="${pageBean.list }" varStatus="status">
					<div id="book">
						<div id="image">
							<img alt="" src="${pageContext.request.contextPath }/images/${book.image}" />
						</div>
						<div id="info">
							<li>${book.name }</li>
							<li>${book.author }</li>
							<li>${book.price }</li>
							<li>
								<a href="#">购买</a>
							</li>
						</div>
						<div style="clear: both"></div>
					</div>
					<!-- 每一行显示三本书籍 -->
					<c:if test="${status.count % 3 == 0 }">
						<%-- 这里要清除浮动,十分重要! --%>
						<div style="clear: both"></div>
						<br/>
					</c:if>
				</c:forEach>
				
				<%-- 这里要清除浮动,十分重要! --%>
				<div style="clear: both"></div>
				<br/>
				<div id="pagebar"> 
					总共${pageBean.totalpage }页,
					当前第${pageBean.currentpage }页,
					<c:forEach var="pagenum" items="${pageBean.pagebar }">
						<a href="${pageContext.request.contextPath }/client/IndexServlet?currentpage=${pagenum }&category_id=${param.category_id }">${pagenum }</a>
					</c:forEach>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

重要的是:如果div浮动都黏贴在一起了,那么在后边多加个div,用于清除浮动效果。
最后,测试的效果如下:
在这里插入图片描述

版权声明:本文为yerenyuan_pku原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yerenyuan_pku/article/details/91350215