jsp-servlet(2)响应HTML文档-书籍管理系统

时间:2021-06-06 13:47:16

基础知识预备:

 目标:

构建一个书籍管理系统,实现以下功能。

功能:

1 图书信息查询,(查)

2 书籍管理:添加书籍

3 书籍管理:修改书籍信息

4 书籍管理:删除书籍

一、预备工作

Book{
Id,
Name,
Price,
Author,
Pubdate,
}

建表:

CREATE TABLE `book`  (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`price` double NULL DEFAULT NULL,
`author` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`pubDate` date NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;

二、书籍查询功能

在java项目中新建实体类(Book类):放于cn.piggy.entity中

package cn.piggy.entity;

import java.util.Date;

public class Book {
private int id;
private String name;
private double price;
private String author;
private Date pubDate; //需要三种构造方法:1无参的;2不带id的,用于添加书籍时;3 带有id的,用于查询时
//1无参构造方法
public Book(){ }
//2 不带id
public Book(String name, double price, String author, Date pubDate) {
super();
this.name = name;
this.price = price;
this.author = author;
this.pubDate = pubDate;
}
//3 带有id
public Book(int id, String name, double price, String author, Date pubDate) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
this.pubDate = pubDate;
} public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getPubDate() {
return pubDate;
}
public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + ", price=" + price + ", author=" + author + ", pubDate=" + pubDate
+ "]";
} }

分析功能:先做显示所有书籍的功能。

先做书籍查询功能----

由于对于书籍的操作有很多:如查询,修改,增加等与数据库交互的操作。将它们放于一个类中,放于BookDao中。

建一个Dao包,该包下放所有与数据库相关的操作。

由于需要与数据库进行连接、返回结果等操作,所以写了一个util的工具包,放于cn.piggy.util包中,其中有一个类叫做BaseDao.

BaseDao:加载jdbc驱动;实现数据库连接和关闭连接;查询,增删改SQL语句的实现。

package cn.piggy.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class BaseDao {
private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
//获得连接
private void getConnection(){
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载MySQL的驱动,jar包放于webroot的lib目录下
System.out.println("数据库加载成功!"); String url="jdbc:mysql://localhost:3306/booksys?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";//booksys数据库的地址,本地,3306端口
conn = DriverManager.getConnection(url,"root","******");
System.out.println("连接成功,获取连接对象: " + conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
} //关闭连接
public void close(){
if(rs!=null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(ps!=null)
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(conn!=null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} //更新--修改,增加,删除
//sql=insert into book(name,price,author,pubDate) values(?,?,?,?),更新时只需要传入这条sql语句即可
public int executeUpdate(String sql,Object...objects){//这里objects是不定参数,需要查资料看一下是什么
try {
this.getConnection();
ps = conn.prepareStatement(sql);
if(objects!=null)//设置四个参数
for(int i=0;i<objects.length;i++){
ps.setObject(i+1, objects[i]);//从1开始
}
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
this.close();
}
return -1;
} //查询(查询与前面三者不同)
public ResultSet executeQuery(String sql,Object...objects){
try {
this.getConnection();
ps = conn.prepareStatement(sql);
if((ps!=null)&(objects!=null))//设置四个参数
for(int i=0;i<objects.length;i++){
ps.setObject(i+1, objects[i]);//从1开始
}
return rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
} }

BookDao:继承自BaseDao,当具体的实体类(Book)需要与数据库进行交互的时候,在BookDao中实现相应的查询,增加,修改,删除功能。

编写ListServlet类

部署Servlet

、500错误
显示语句中BaseDao的第71行if(objects!=null)有NullException的错误。一开始以为是没有判断空指针。后来分析,出现空指针的原因是
mysql没有连接上
数据库是空的 一开始以为是加载jdbc驱动失败的问题,
旧版本的驱动加载是这样写的:
com.mysql.jdbc.Driver 新版本是这样的:
com.mysql.cj.jdbc.Driver 修改完以后,添加一条打印语句:
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("数据库加载成功!");
发现打印了该语句,说明并不是加载驱动失败的问题。 然后检查发现是URL写错了,booksys写成了sysbook。 The server time zone value '???ú±ê×??±??' is unrecognized or represents more than one time zone.
出现这个的原因是因为 mysql返回的时间总是有问题,比实际时间要早8小时。 在jdbc连接的url后面加上serverTimezone=GMT即可解决问题,如果需要使用gmt+8时区,需要写成GMT%2B8
public static final String URL="jdbc:mysql://localhost:3306/jdbc01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";//链接的mysql

部署的时候出现的几个问题

三、书籍添加功能

思路:新建add.html,完成图书添加的操作(客户端请求,表单以post方式提交);编写AddServlet类,处理表单提交的数据,对get和post两种提交方式,有对应的doGet和doPost两种处理方式;获得表单数据以后,编写BookDao,将数据存到数据库中。

新建add.html,完成图书添加的操作。

jsp-servlet(2)响应HTML文档-书籍管理系统

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>add.html</title> <meta name="keywords" content="keyword1,keyword2,keyword3">
<meta name="description" content="this is my page">
<meta name="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body>
<form action="add" method="post">
<table width="80%" align="center">
<tr>
<td colspan="2"><h3>添加书籍</h3>></td>
</tr>
<tr>
<td>书名</td>
<td><input type="text" name="name"/></td>
</tr>
<tr>
<td>价格</td>
<td><input type="text" name="price"/></td>
</tr>
<tr>
<td>作者</td>
<td><input type="text" name="author"/></td>
</tr>
<tr>
<td>出版日期</td>
<td><input type="text" name="pubDate"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" name="提交"/></td>
</tr>
</table>
</form>
</body>
</html>

这里存在一个乱码的问题待解决(已解决:Chrome没有utf-8,插件也不太方便安装,转用360浏览器后,编码选择utf-8就可以正常显示了;更新:在add.html的head后增加

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>add.html</title>

即可解决问题)。 

下面编写AddServlet类,处理add.html提交的数据:HttpServletRequest有一个方法getParameter("fieldName"),可以获取表单提交的数据(fieldName是表单的项)。

package cn.piggy.servlet;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.piggy.dao.BookDao;
import cn.piggy.entity.Book; public class AddServlet extends HttpServlet{
private BookDao bookDao = new BookDao();//BookDao.java是一个类,需要new一个对象进行保存
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8"); //对乱码进行处理
resp.setCharacterEncoding("utf-8");
String bookName = req.getParameter("name"); //HttpServletRequest获取表单中fieldName的方法
//System.out.println("书名:"+bookName);
double price = Double.parseDouble(req.getParameter("price"));//getParameter返回的是String类型,需要转换一下
String author = req.getParameter("author");
Date pubDate = null;
try {
pubDate = new SimpleDateFormat("yyyy-MM-dd").parse(req.getParameter("pubDate")); //日期的格式转换
} catch (ParseException e) {
e.printStackTrace();
}
Book book = new Book(bookName, price, author, pubDate);
if(bookDao.add(book)>0){
// resp.setContentType("text/html;charset=utf-8");
// resp.getWriter().print("添加成功!! <a href='list'>查询列表</>");//出现查询列表按钮,点击可以跳转到“list”;还可以使用重定向方法
//重定向
resp.sendRedirect("list");//response对象的该函数可以重新定向到添加书籍后的状态
}else{
resp.getWriter().print("添加失败");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp); //当以post提交时,也采用get提交,以简化操作
}
}

在web.xml中增加代码,对AddServlet进行部署。

  <servlet>
<servlet-name>addServlet</servlet-name>
<servlet-class>cn.piggy.servlet.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>addServlet</servlet-name>
<url-pattern>/add</url-pattern>
</servlet-mapping>

在BookDao.java中添加一个查询书籍的函数,通过添加SQL语句进行添加。

package cn.piggy.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List; import cn.piggy.entity.Book;
import cn.piggy.util.BaseDao; public class BookDao extends BaseDao{
//查询出所有书籍,放到一个List中
public List<Book> getAll(){
List<Book> list = new ArrayList<Book>();
String sql="select * from book";
//查询的操作
try {
ResultSet rs=this.executeQuery(sql);
while(rs.next()){
list.add(new Book(rs.getInt(1),rs.getString(2),rs.getDouble(3),
rs.getString(4),rs.getDate(5)));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.close();
}
return list;
} public Book getById(int id){
String sql="select * from book where id=?";
//查询的操作
try {
ResultSet rs=this.executeQuery(sql,id);
if(rs.next()){
return new Book(rs.getInt(1),rs.getString(2),rs.getDouble(3),
rs.getString(4),rs.getDate(5));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.close();
}
return null;
} //添加书籍
public int add(Book b){
String sql = "insert into book(name,price,author,pubDate) values(?,?,?,?)";
return this.executeUpdate(sql, b.getName(),b.getPrice(),b.getAuthor(),
new SimpleDateFormat("yyyy-MM-dd").format(b.getPubDate()));//b.getPubDate()直接传入不行
} //修改书籍
public int update(Book b){
String sql="update book set name=?,price=?,author=?,pubDate=? where id=?";
return this.executeUpdate(sql,b.getName(),b.getPrice(),b.getAuthor(),
new SimpleDateFormat("yyyy-MM-dd").format(b.getPubDate()),b.getId());
} //删除书籍
public int delete(int id){
String sql = "delete from book where id=?";
return this.executeUpdate(sql, id);
} }

四、书籍修改功能

package cn.piggy.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.piggy.dao.BookDao;
import cn.piggy.entity.Book; public class SelectByIdServlet extends HttpServlet {
private BookDao bookDao = new BookDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 获取id
int id = 0;
if(req.getParameter("id")!=null)
id = Integer.parseInt(req.getParameter("id"));
//根据id查询对应记录
Book book = bookDao.getById(id);
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("<html>");
out.print("<head>");
out.print("<title>书籍列表</title>");
out.print("</head>");
out.print("<body>");
out.print("<form action='update' method='post'>");
out.print("<table width='80%' align='center'>");
out.print("<tr><td colspan='2' align='center'>修改书籍</td></tr>");
out.print("<tr>");
out.print("<td>");
out.print("书名:<input type='hidden' name='id' value='"+book.getId()+"'/>");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='name' value='"+book.getName()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("价格");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='price' value='"+book.getPrice()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("作者");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='author' value='"+book.getAuthor()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("出版日期");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='pubDate' value='"+book.getPubDate().toLocaleString()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td colspan='2' align='center'>");
out.print("<input type='submit' value='修改'/>");
out.print("</td>");
out.print("</tr>");
out.print("</table>");
out.print("</form>");
out.print("</body>");
out.print("</html>");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
} }
package cn.piggy.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.piggy.dao.BookDao;
import cn.piggy.entity.Book; public class UpdateServlet extends HttpServlet {
private BookDao bookDao = new BookDao();//BookDao.java是一个类,需要new一个对象进行保存
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8"); //对乱码进行处理
resp.setCharacterEncoding("utf-8");
int id = 0;
if(req.getParameter("id")!=null)
id = Integer.parseInt(req.getParameter("id"));
String bookName = req.getParameter("name"); //HttpServletRequest获取表单中fieldName的方法
//System.out.println("书名:"+bookName);
double price = Double.parseDouble(req.getParameter("price"));//getParameter返回的是String类型,需要转换一下
String author = req.getParameter("author");
Date pubDate = null;
try {
pubDate = new SimpleDateFormat("yyyy-MM-dd").parse(req.getParameter("pubDate")); //日期的格式转换
} catch (ParseException e) {
e.printStackTrace();
}
Book book = new Book(id,bookName,price,author,pubDate);
System.out.println(book);
if(bookDao.update(book)>0){
// resp.setContentType("text/html;charset=utf-8");
// resp.getWriter().print("添加成功!! <a href='list'>查询列表</>");//出现查询列表按钮,点击可以跳转到“list”;还可以使用重定向方法
//重定向
resp.sendRedirect("list");//response对象的该函数可以重新定向到添加书籍后的状态
}else{
resp.getWriter().print("修改失败");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp); //当以post提交时,也采用get提交,以简化操作
}
}
package cn.piggy.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.piggy.dao.BookDao;
import cn.piggy.entity.Book; public class SelectByIdServlet extends HttpServlet {
private BookDao bookDao = new BookDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 获取id
int id = 0;
if(req.getParameter("id")!=null)
id = Integer.parseInt(req.getParameter("id"));
//根据id查询对应记录
Book book = bookDao.getById(id);
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("<html>");
out.print("<head>");
out.print("<title>书籍列表</title>");
out.print("</head>");
out.print("<body>");
out.print("<form action='update' method='post'>");
out.print("<table width='80%' align='center'>");
out.print("<tr><td colspan='2' align='center'>修改书籍</td></tr>");
out.print("<tr>");
out.print("<td>");
out.print("书名:<input type='hidden' name='id' value='"+book.getId()+"'/>");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='name' value='"+book.getName()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("价格");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='price' value='"+book.getPrice()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("作者");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='author' value='"+book.getAuthor()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td>");
out.print("出版日期");
out.print("</td>");
out.print("<td>");
out.print("<input type='text' name='pubDate' value='"+book.getPubDate().toLocaleString()+"'/>");
out.print("</td>");
out.print("</tr>");
out.print("<tr>");
out.print("<td colspan='2' align='center'>");
out.print("<input type='submit' value='修改'/>");
out.print("</td>");
out.print("</tr>");
out.print("</table>");
out.print("</form>");
out.print("</body>");
out.print("</html>");
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
} }

难点:

out.print("<td>");
out.print("书名:<input type='hidden' name='id' value='"+book.getId()+"'/>");
out.print("</td>");

在SelectByIdServlet中,建立了一个表单,其中不需要显示Id。该表单向服务器提交请求。

服务器收到请求以后,在UpdateServlet中响应。UpdateServlet需要获取Id的值,所以有了上述代码。‘hidden’参数:请求中既提交了id的信息,又不会在表单中显示id。

五、最终效果:

jsp-servlet(2)响应HTML文档-书籍管理系统

jsp-servlet(2)响应HTML文档-书籍管理系统

jsp-servlet(2)响应HTML文档-书籍管理系统

六、附录:

知识点(包括笔记):

1 DAO:data access object数据访问对象

HttpServletResponse对象

3 HttpServletRequest对象

jsp-servlet(2)响应HTML文档-书籍管理系统

注:http协议的小知识:

客户端:浏览器;服务端:Tomcat服务器

如果表单是get提交,所提交的参数是跟在URL后的,以?name=value&price=23这样的方式追加在URL后。特点:长度有限;不安全;效率相对较高。

如果表单是post提交,那么数据将被封装在formdata里面。特点:长度没有限制;安全性高;效率相对低。

HttpServletRequest有一个方法getParameter("fieldName"),可以获取表单提交的数据(fieldName是表单的项)。

4 重定向与转发

由response.sendRedirect("list") 实现,当使用重定向时,服务器会将重新定向的地址(“list”)交给浏览器,浏览器会根据新的URL,重新发起请求。

jsp-servlet(2)响应HTML文档-书籍管理系统

5 JDBC 

Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

简单地说,就是用于执行SQL语句的一类Java API

Base.Dao中:

public ResultSet executeQuery(String sql,Object...objects){
} //在java中实现query(查询)SQL语句 java.sql.ResultSet类型包含从数据库中查询的结果集
public int executeUpdate(String sql,Object...objects){
} //在java中实现Update(增删改)SQL语句

6 书籍管理系统中的难点分析

jsp-servlet(2)响应HTML文档-书籍管理系统

jsp-servlet(2)响应HTML文档-书籍管理系统