目录

我有话说:

1 项目简介

2 项目展示

2.1 首先创建数据库和表信息

2.2 预先准备操作

2.3 开始配置项目

2.4 开始web层

3 图片展示

4 附上源码文件(百度网盘):


我有话说:

  • 首先 内容比较多,篇幅比较长,有需要的可以耐心看完.
  • 这个项目最开始是跟着狂神写下来的,附上狂神的详细视频链接及详细笔记:

17、ssm整合:Mybatis层_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1aE41167Tu?p=17&vd_source=b1036c3d2e010aa91f6ccb4fed6293ec狂神SSM教程- 专栏 -KuangStudyhttps://www.kuangstudy.com/zl/ssm#1377532368339955713

"如果没有SSM框架的基础,建议先学完SSM的基础知识,这样听起来会容易很多".

  • 跟着狂神写项目的期间没有遇到报错,但是写完之后觉得如果只是这样我并不满足,所以把我会的内容基本上都在这个项目中写出来了,我认为这是我的一种进步.
  • 正常来说一个项目从开始到结束应该是一步一步来的,这里因为时间问题,无法一步一步展示.
  • 虽然内容是整个项目的,但是建议还是再纯手打一遍,因为复制粘贴总会有些不必要的问题,哪怕正确的代码,复制粘贴可能还是有问题.
  • 项目中的jsp页面可以先用vscode写一遍然后复制到jsp页面即可.
  • 所谓框架,就是搭好一个架子,然后所有的操作都在框架的内部进行,不需要对框架进行其他的修改,而且一些操作交给Spring框架就可以帮你完成.
  • 在写这个项目中遇到的一些问题:前段信息乱码,分页查询,大部分的js操作,有的时候可能并不是代码的问题...等等,但是好在坚持下来并逐一解决,这个项目在一些方面还是可以改进,比如多表查询,页面跳转动画,分页的信息,一些好看的css样式等.
  • 知识没有白学的,学无止境.

1 项目简介

1.开发环境:

  • JDK1.8; mysql8.0.31; mybatis3.5.2; mybatis-spring2.0.2; spring-webmvc及springjdbc都是5.1.9.RELEASE(个人认为目前是用的最舒服的一版)

2.开发软件:

  • 可视化前段:VSCode; 数据库:navicat; 后端: IDEA2021.3.3; 服务器: Tomcat

3.其他类插件:lombok PageHelper fileupload

4.该项目通过SSM框架实现,功能包括"基本的CRUD; 用户的登录注册注销; 拦截器; 分页; 文件上传及文件下载,及一些前段操作等"

2 项目展示

2.1 首先创建数据库和表信息

1. book表

CREATE DATABASE javawork;
USE javawork;
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book`  (`bookid` int(0) NOT NULL AUTO_INCREMENT COMMENT 'uuid',`bookname` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '图书名称',`author` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '作者',`publish` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '出版社',`introduction` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '简介',`price` double NOT NULL COMMENT '价格',`booktype` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '书籍类型',PRIMARY KEY (`bookid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '图书信息' ROW_FORMAT = Dynamic;INSERT INTO `book` VALUES (1, '西游记', '吴承恩', '人民文学出版社', '师徒四人去西天取真经', 42, '奇幻类');
INSERT INTO `book` VALUES (2, '三国演义', '罗贯中', '清华大学出版社', '东汉末年分三国。。。', 48, '历史类');
INSERT INTO `book` VALUES (3, '红楼梦', '曹雪芹', '机械工业出版社', '宝玉与众多男女之间故事', 39, '历史类');
INSERT INTO `book` VALUES (4, '资本论', '马克思', '原子能出版社', '马克思的剩余价值理论', 42, '经济类');
INSERT INTO `book` VALUES (5, '经济学原理', '马歇尔', '机械工业出版社', '西方经济学界公认为划时代的著作', 66, '经济类');
INSERT INTO `book` VALUES (6, '大变局下的中国法治', '李卫东', '北京大学出版社', '十大经典法学著作', 42, '政治类');
INSERT INTO `book` VALUES (7, '从你的全世界路过', '张嘉佳', '湖南文艺出版社', '38个爱情故事的小说集', 36, '爱情类');
INSERT INTO `book` VALUES (8, '天才在左,疯子在右', '高铭', '武汉大学出版社', '国内第一本精神病人访谈手记', 30, '教育类');
INSERT INTO `book` VALUES (9, '追风筝的人', '卡勒德·胡赛尼', '上海人民出版社', '人性的背叛与救赎', 36, '情感类');
INSERT INTO `book` VALUES (10, '水浒传', '施耐庵', '人民文学出版社', '108位梁山好汉', 52, '武侠类');
INSERT INTO `book` VALUES (11, '羊脂球', '莫泊桑', '北京联合出版公司', '法国社会各阶层的丑恶嘴脸', 41, '社会类');
INSERT INTO `book` VALUES (12, '百年孤独', '加西亚·马尔克斯', '上海译文出版社', '布恩迪亚家族七代人的百年兴衰', 55, '文学类');
INSERT INTO `book` VALUES (13, '平凡的世界', '路遥', '北京十月文艺出版社', '中国西北农村的历史变革', 58, '文学类');
INSERT INTO `book` VALUES (14, '三体', '刘慈欣', '科幻世界出版社', '征服世界的中国科幻神作', 62, '科幻类');
INSERT INTO `book` VALUES (15, '解忧杂货店', '东野圭谷', '南海出版公司', '收集烦恼和困扰的杂货店', 54, '文学类');
INSERT INTO `book` VALUES (16, '白鹿原', '陈忠实', '人民文学出版社', '中国农村的50年变革', 40, '文学类');
INSERT INTO `book` VALUES (17, '茶馆', '舒庆春(老舍)', '社会科学文献出版社', '一个茶馆的近50年经历', 35, '文学类');
INSERT INTO `book` VALUES (18, '围城', '钱锺书', '上海晨光出版社', '外边的人想进去,里面的人想出来', 30, '文学类');
INSERT INTO `book` VALUES (19, '海边的卡夫卡', '村上春树', '上海译文出版社', '田村卡夫卡的精神救赎', 40, '文学类');
INSERT INTO `book` VALUES (20, '我这一辈子', '舒庆春(老舍)', '中国华侨出版社', '舒庆春的一生', 36, '其他类');
INSERT INTO `book` VALUES (21, '世上另一个我', '萨拉·帕坎南', '湖南文艺出版社', '我在别人设定的角色里拼命挣扎,以为那是我想要的人生', 28, '亲情类');
INSERT INTO `book` VALUES (22, '看见', '柴静', '广西师范大学出版社', '中国社会十年变迁的备忘录', 40, '社会文学类');

2. user表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int(0) NOT NULL AUTO_INCREMENT COMMENT '用户id',`username` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户名',`password` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户密码\r\n',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;INSERT INTO `user` VALUES (1, 'admin', '123456');

2.2 预先准备操作

新建Maven项目"Book"

1. 右键单击Book模块,选择框架支持,选择web应用程序(4.0版本);也可以在选择Maven项目是使用web-app模板,但是不推荐.

然后在项目中会多出来一个web的文件夹,注意:文件夹图标的小圆点一定要是亮着的,否则去Facet中调整选择到当前的项目.

2. 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.gcx</groupId><artifactId>Book</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><!--    导入依赖--><dependencies><!--Junit单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!--数据库驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><!-- 数据库连接池 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency><!--Servlet - JSP --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!--Mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.2</version></dependency><!--Spring/SpringMVC--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.9.RELEASE</version></dependency>
<!--        实体类插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency>
<!--        文件上传--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency>
<!--        myBatis分页插件--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.2</version></dependency></dependencies><!--    静态资源导出--><build><resources><resource><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources></build></project>

3.为了避免出现404,创建lib文件(必须确保所有依赖已加入到maven中)

单击加号后选择库文件,全选,添加,应用即可

4. 配置Tomcat服务器

然后应用,确认即可

5. 测试Tomcat服务器能否正常运行

启动Tomcat后浏览器进入名为$Title$的index.jsp页面,并显示$END信息,表示Tomcat配置没问题

2.3  开始配置项目

1. 创建项目结构

java文件夹下属于源码文件,resources文件夹下属于资源文件,web下是前端的一些配置文件及页面.

2. 开始编写实体类

实体类名需要与数据库表名一致

Book

package com.gcx.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
@SuppressWarnings("all")
public class Book {private int bookid;private String bookname;private String author;private String publish;private String introduction;private Double price;private String booktype;
}

User

package com.gcx.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String username;private String password;
}

3. 编写持久层(dao层)

BookMapper接口

package com.gcx.dao;import com.gcx.pojo.Book;
import com.gcx.pojo.User;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface BookMapper {//    增加一本书int addBook(Book book);//    删除一本书int deleteBookById(@Param("bookid") int id);//    更新一本书int updateBook(Book book);//    查询一本书Book queryBookById(@Param("bookid") int id);//    通过书名查询书籍,因为可能是一个集合,所以用ListList<Book> queryBookByName(@Param("bookname") String bookname);//    获取登录信息User findUserByNameAndPassword(User user);//    分页List<Book> findList();//    注册int adduser(User user);}

因为要通过mybatis链接数据库,所以要配置它的核心配置文件: mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><typeAliases><package name="com.gcx.pojo"/></typeAliases><mappers><mapper class="com.gcx.dao.BookMapper"/></mappers>
</configuration>

database.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javawork?useSSL=true&useUnicode=true&characterEncoding=utf8&ServerTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456

spring-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:Context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><Context:property-placeholder location="classpath:database.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="password" value="${jdbc.password}"/><property name="user" value="${jdbc.username}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="driverClass" value="${jdbc.driver}"/><!--    配置数据库连接池属性--><property name="maxPoolSize" value="30"/><property name="minPoolSize" value="10"/><!-- 关闭连接后不自动commit --><property name="autoCommitOnClose" value="false"/><!-- 获取连接超时时间 --><property name="checkoutTimeout" value="10000"/><!-- 当获取连接失败重试次数 --><property name="acquireRetryAttempts" value="2"/></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatis-config.xml"/><!--        配置分页插件--><property name="plugins"><array><bean class="com.github.pagehelper.PageInterceptor"><property name="properties"><value>helperDialect = mysqlreasonable = true</value></property></bean></array></property></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/><property name="basePackage" value="com.gcx.dao"/></bean></beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><import resource="classpath:spring-service.xml"/><import resource="classpath:spring-dao.xml"/><import resource="classpath:spring-mvc.xml"/>
</beans>

有报错先不用管,是因为还没有配置对应的XML文件.

注意,这里上边会提示要配置应用程序的上下文

点击配置应用程序上下文,创建新的程序上下文

点击确定就可以了,进入项目设置,点击模块,查看是否配置成功

到此数据库链接完成,配置BookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gcx.dao.BookMapper"><insert id="addBook" parameterType="book">insert into book(bookname,author,publish,introduction,price,booktype)values(#{bookname},#{author},#{publish},#{introduction},#{price},#{booktype});</insert><delete id="deleteBookById" parameterType="int">delete from book where bookid =#{bookid};</delete><update id="updateBook" parameterType="book">update book set bookname=#{bookname},author=#{author},publish=#{publish},introduction=#{introduction},price=#{price},booktype=#{booktype}where bookid=#{bookid};</update><select id="queryBookById" resultType="book">select *from book where bookid = #{bookid};</select><select id="queryBookByName" resultType="book">select *from book where bookname = #{bookname};</select><select id="findUserByNameAndPassword" resultType="User">select *from userwhere username = #{username} and password = #{password};</select><select id="findList" resultMap="booksresultmap">select *from book</select><resultMap id="booksresultmap" type="com.gcx.pojo.Book"><id property="bookid" column="bookid" jdbcType="INTEGER"/><result property="bookname" column="bookname" jdbcType="VARCHAR"/><result property="author" column="author" jdbcType="VARCHAR"/><result property="publish" column="publish" jdbcType="VARCHAR"/><result property="introduction" column="introduction" jdbcType="VARCHAR"/><result property="price" column="price" jdbcType="DOUBLE"/><result property="booktype" column="booktype" jdbcType="INTEGER"/></resultMap><insert id="adduser" parameterType="user">insert into user(username,password)values (#{username},#{password});</insert>
</mapper>

4. 编写业务层代码(service接口及实现类)

BookService

package com.gcx.service;import com.gcx.pojo.Book;
import com.gcx.pojo.User;
import com.github.pagehelper.PageInfo;public interface BookService {//    增加一本书int addBook(Book book);//    删除一本书int deleteBookById(int id);//    更新一本书int updateBook(Book book);//    查询一本书Book queryBookById(int id);//    通过书名查询书籍PageInfo<Book> queryBookByName(String bookname);//    获取登录信息User findUserByNameAndPassword(User user);//    分页查询PageInfo<Book> findList(Integer pageNum, Integer pageSize);//    注册int adduser(User user);
}

BookServiceImpl

package com.gcx.service;import com.gcx.dao.BookMapper;
import com.gcx.pojo.Book;
import com.gcx.pojo.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.RequestParam;import java.util.List;public class BookServiceImpl implements BookService {private BookMapper bookMapper;public void setBookMapper(BookMapper bookMapper) {this.bookMapper = bookMapper;}@Overridepublic int addBook(Book book) {return bookMapper.addBook(book);}@Overridepublic int deleteBookById(int id) {return bookMapper.deleteBookById(id);}@Overridepublic int updateBook(Book book) {return bookMapper.updateBook(book);}@Overridepublic Book queryBookById(int id) {return bookMapper.queryBookById(id);}@Overridepublic PageInfo<Book> queryBookByName(String bookname) {List<Book> list = bookMapper.queryBookByName(bookname);return new PageInfo<>(list);}@Overridepublic User findUserByNameAndPassword(User user) {return bookMapper.findUserByNameAndPassword(user);}@Overridepublic PageInfo<Book> findList(@RequestParam Integer pageNum,@RequestParam Integer pageSize) {//        每页显示多少数据if (pageSize== null){pageSize=5;}PageHelper.startPage(pageNum,pageSize);List<Book> list = bookMapper.findList();
//        for (Books books : list) {
//            System.out.println("书籍信息:"+books);
//        }PageInfo PageInfo = new PageInfo(list);System.out.println("总页数:"+PageInfo.getPages());System.out.println("总记录数:"+PageInfo.getTotal());System.out.println("当前页数:"+PageInfo.getPageNum());System.out.println("当前页面记录数:"+PageInfo.getPageSize());return new PageInfo<>(list);}@Overridepublic int adduser(User user) {return bookMapper.adduser(user);}
}

配置spring-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:Context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"><Context:component-scan base-package="com.gcx.service"/><bean id="BookServiceImpl" class="com.gcx.service.BookServiceImpl"><property name="bookMapper" ref="bookMapper"/></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean></beans>

配置上下文为applicationContext.xml.

5. 配置spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:Context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--    开启注解--><mvc:annotation-driven/>
<!--    过滤静态资源--><mvc:default-servlet-handler/>
<!--    扫描包下注解--><Context:component-scan base-package="com.gcx.controller"/>
<!--    视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/jsp/"/><property name="suffix" value=".jsp"/></bean>
<!--    配置拦截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/book/**"/><bean class="com.gcx.interceptor.LoginInterceptor"/></mvc:interceptor></mvc:interceptors><!--文件上传配置--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --><property name="defaultEncoding" value="utf-8"/><!-- 上传文件大小上限,单位为字节(10485760=10M) --><property name="maxUploadSize" value="10485760"/><property name="maxInMemorySize" value="40960"/></bean>
</beans>

如果在配置拦截器的地方报错,是因为还没有些拦截器的类,可以先创建一个不写内容.

配置上下文为applicationContext.xml

此时在Spring的模块中显示如下:

到这里,底层代码基本完成了.然后就是前后端的链接:

在mvc中是通过Servlet层的HttpServlet来实现的,在SpringMVC中,则是通过Controller层的添加注解或继承Controller接口来实现的.

6. BookController

package com.gcx.controller;import com.gcx.pojo.Book;
import com.gcx.pojo.User;
import com.gcx.service.BookService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
/*** author: labixiaoxin@* advice: Controller层可以写的更分工明确;* 新建LoginController来写登录.注册.注销的实现;* 新建PageController用来写分页的实现;* ...其他类似*/@Controller
@RequestMapping("/book")
@SuppressWarnings("all")
public class BookController {@Autowired@Qualifier("BookServiceImpl")private BookService bookService;//    跳转到登录页@RequestMapping("toLogin")public String Login() {return "Login";}//    进入登录页/**** @param session 将数据保存在session中* @param user    数据库内的用户登录信息* @param model   将数据通过el表达式显示在页面* @return 跳转页面*/@RequestMapping("Login")public String Login(HttpSession session, User user, Model model) {
//        用来获取user内的信息User userByNP = bookService.findUserByNameAndPassword(user);/**** 调用业务层接口内方法* 判断用户信息是否正确,且用户信息不为空.* 将user信息保存在session中,并进入首页* 否则返回error1信息*/if (userByNP != null) {session.setAttribute("userLoginInfo", user);System.out.println(user);return "redirect:/book/allbook/1";} else {model.addAttribute("error1", "账号或密码错误,请重新输入");return "Login";}}//   跳转注册@RequestMapping("toregisterPage")public String toregisterPage() {return "register";}//    注册sql/**** @param username* @param password 用@RequestParam获取前段传递的信息获取用户名和密码* @param session* @return*/@GetMapping("register")public String register(@RequestParam("username") String username,@RequestParam("password") String password, HttpSession session) {User user = new User();user.setUsername(username);user.setPassword(password);bookService.adduser(user);session.setAttribute("userLoginInfo", user);System.out.println(user);return "Login";}/**** 两种方法:*      1.removeAttribute 移除指定的信息*      2.invalidate 移除session中所有信息* @param* @return*/@RequestMapping("destory")public String destory(HttpSession session) {session.removeAttribute("userLoginInfo");
//        session.invalidate();
//        User user = new User();
//         验证是否注销成功
//        System.out.println(user.toString());return "Login";}//    登录页面进入首页@RequestMapping("toallbook")public String toallbook() {return "allbook";}//    查询全部书籍(首页)/****对展示页面进行分页* @param pageIndex 当前页码* @param model     给前端传信息*                  if:如果当前页码<=1,则设置为第一页*                  pageSize=null=5* 在Service接口中返回PageInfo类型,保存到"PageInfo"中,方便前段调用PageInfo属性* @return*/@GetMapping("allbook/{num}")public String list(@PathVariable("num") Integer pageIndex, Model model) {if (pageIndex <= 1) {pageIndex = 1;}PageInfo<Book> list = bookService.findList(pageIndex, null);model.addAttribute("PageInfo", list);return "allbook";}//跳转到新增书籍页面@RequestMapping("toAddBook")public String toAddPaper() {return "addBook";}//执行sql新增书籍@RequestMapping("addBook")public String addBook(Book book) {bookService.addBook(book);return "redirect:/book/allbook/1";}//    跳转到更改书籍页面@RequestMapping("toupdateBook")public String toupdatePaper(int id, Model model) {Book book = bookService.queryBookById(id);model.addAttribute("Book", book);return "updatebook";}//    执行sql更改书籍@RequestMapping("updateBook")public String updateBook(Book book) {bookService.updateBook(book);return "redirect:/book/allbook/1";}//    执行sql删除书籍/**** @param id restful风格* @return*/@RequestMapping("deletebook/{bookid}")public String deleteBook(@PathVariable("bookid") int id) {bookService.deleteBookById(id);return "redirect:/book/allbook/1";}//    执行SQL(根据书籍名称)查询书籍/**** @param queryBookname 查询书籍的名字* @param model* @return*/@GetMapping("querybook")public String queryBook(@RequestParam("queryBookname") String queryBookname,Model model) {PageInfo<Book> list = bookService.queryBookByName(queryBookname);
//        如果输入为空或输入的信息不存在,返回error信息
//        if (queryBookname == null) {
//            list = bookService.queryAllBook();
//            model.addAttribute("error1", "没有该书籍,请重新查询");
//        }System.out.println(list);model.addAttribute("PageInfo", list);return "allbook";}/*** 文件上传* @param file* @param request* @return* @throws IOException** @RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象* 批量上传CommonsMultipartFile则为数组即可*/@RequestMapping("/upload")public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//      file.getOriginalFilename() :获取文件名;String uploadFileName = file.getOriginalFilename();
//      如果文件名为空,直接回到首页!if ("".equals(uploadFileName)){return "redirect:/book/allbook/1";}System.out.println("上传文件名 : "+uploadFileName);
//      上传路径保存设置(绝对路径)String path = "C:\\Users\\Gu_cx\\Desktop\\Book\\web\\upload";
//      如果路径不存在,创建一个File realPath = new File(path);if (!realPath.exists()){realPath.mkdir();}System.out.println("上传文件保存地址:"+realPath);InputStream is = file.getInputStream(); //文件输入流OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//      读取写出int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return "redirect:/book/allbook/1";}//    下载图片@RequestMapping(value="/download")public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
//      要下载的图片地址(绝对路径)String path = "C:\\Users\\Gu_cx\\Desktop\\Book\\web\\img\\idea.png";String fileName = path.substring(path.lastIndexOf("\\")+1);
//      1、设置response 响应头response.reset(); //设置页面不缓存,清空bufferresponse.setCharacterEncoding("UTF-8"); //字符编码response.setContentType("multipart/form-data"); //二进制传输数据
//      设置响应头(百度web下载文件的头信息)response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
//      2、 读取文件--输入流InputStream input=new FileInputStream(path);
//      3、 写出文件--输出流OutputStream out = response.getOutputStream();byte[] buff =new byte[1024];int index=0;
//      4、执行 写出操作while((index= input.read(buff))!= -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;}
}

7. LoginInterceptor拦截器

package com.gcx.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
*
*因为是boolean 的返回类型,true代表可以通过拦截器,false代表被拦截器拦截,不能够通过
*/
//      设置编码格式request.setCharacterEncoding("UTF-8");HttpSession session = request.getSession();
//     通过Controller中的setAttribute保存的信息,在这里通过get获取到,如果userLoginInfo内不为空时可以通过if ( session.getAttribute("userLoginInfo")!=null){System.out.println("执行了登录拦截器=>111");return true;}
//     getRequestURI().contains属于获取URL的地址,让URL进入到toLogin;Login;toregisterPage;register时可以通过if (request.getRequestURI().contains("toLogin")){System.out.println("执行了登录拦截器=>222");return true;}if (request.getRequestURI().contains("Login")){System.out.println("执行了登录拦截器=>333");return true;}if (request.getRequestURI().contains("toregisterPage")){System.out.println("执行了登录拦截器=>444");return true;}if (request.getRequestURI().contains("register")){System.out.println("执行了登录拦截器=>555");return true;}
//        判断当不满足以上条件使,都要被拦截器拦截,不能通过并重定向到Login.jsp页面request.getRequestDispatcher("/WEB-INF/jsp/Login.jsp").forward(request,response);return false;}
}

到这里,源码及配置文件层都已经完成

2.4 开始web层

首先,因为视图解析器中的前缀是WEB-INF下的jsp文件夹,所以在WEB-INF下新建jsp文件

1. 首先index.jsp(跳转进入页)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/29Time: 15:11To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><meta charset="utf-8"><title>首页</title>
<%--    使用纯jquery实现轮播图;
优点:适合新手;
缺点:浪费资源,每次加载页面都要更新请求,占用内存和网络--%><script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><link rel="stylesheet" href="${pageContext.request.contextPath}/css/index.css"><script src="js/index.js"></script>
</head>
<body>
<table><tr><td><header><div class="bigBox" id="oImg"><!-- 轮流播放图片 --><img id="insert" src="indexImg/1.jpg"/></div><p class="left" onclick="goBack()"></p><p class="right" onclick="goForward()"></p><ul id="nav"><!-- 指定某张图片 --><li id="1" onclick="move(this)">1</li><li id="2" onclick="move(this)">2</li><li id="3" onclick="move(this)">3</li><li id="4" onclick="move(this)">4</li><li id="5" onclick="move(this)">5</li><li id="6" onclick="move(this)">6</li></ul></header></td><td><h1 class="threesolid">欢迎进入书籍管理系统</h1><div class="texts"><!-- 所有的转发地址都要养成写${pageContext.request.contextPath}的习惯 --><a class="btn btn--stripe" href="${pageContext.request.contextPath}/book/toLogin">登录</a><br><a class="btn btn--stripe" href="${pageContext.request.contextPath}/book/allbook">进入书籍页面</a></div></td></tr></table>
</body>
</html>

2. 首页 allbook

<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/25Time: 14:38To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>书籍展示</title><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><style>.title{font-family:"华文彩云";/*设置字体*/font-size:64px; /*设置字体大小*/font-weight:normal; /*设置字体粗细*/-webkit-text-stroke:1px #0000FF;        /*文字描边*/-webkit-text-fill-color:transparent;    /*设置文字的填充颜色*/}</style><script>/*页面弹窗*/function ok(){alert("删除成功");}</script>
</head>
<body>
<div class="title">书籍展示</div>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>书籍列表----显示所有书籍</small></h1><div style="text-align: right"><a href="${pageContext.request.contextPath}/book/allbook/1" title="返回显示全部书籍">首页</a><a href="${pageContext.request.contextPath}/book/toLogin" title="返回登录页面">登录</a><a href="${pageContext.request.contextPath}/book/destory" title="注销当前用户信息">注销</a></div></div></div><div class="row"><div class="col-md-4 column"><a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a></div><div class="col-md-4 column"></div><div class="col-md-4 column"><form action="${pageContext.request.contextPath}/book/querybook" method="get" style="float: right"><table><tr><%--                            <td style="width: 170px">--%><%--                                <span style="color: red;font-weight: bold;text-align: right">${error1}</span>--%><%--                            </td>--%><td><input type="text" name="queryBookname" class="form-control" placeholder="请输入要查询的书籍名称"></td><td>&nbsp;</td><td><input type="submit" value="查询" class="btn btn-primary"></td></tr></table></form></div></div></div><div class="row clearfix "><div col-md-12 column class=" table-responsive" ><table class="table table-hover table-striped"><thead><tr><th>书籍名称</th><th>作者</th><th>出版社</th><th>书籍编号</th><th>详情</th><th>价格</th><th>书籍类别</th><th>操作</th></tr></thead><tbody>/*调用PageInfo里的list属性*/<c:forEach items="${PageInfo.list}" var="book" ><tr><td>${book.bookname}</td><td>${book.author}</td><td>${book.publish}</td><td>${book.bookid}</td><td>${book.introduction}</td><td>${book.price}</td><td>${book.booktype}</td><td><a href="${pageContext.request.contextPath}/book/toupdateBook?id=${book.bookid}">修改</a>&nbsp;|&nbsp;<a href="${pageContext.request.contextPath}/book/deletebook/${book.bookid}" onclick="ok()">删除</a><span></span></td></tr></c:forEach></tbody></table><ul class="pagination"><%--    如果当前页码-1>=0,则显示首页,即在第一页时不显示首页--%><c:if test="${PageInfo.prePage-1>=0}"><li><a href="${PageInfo.navigateFirstPage}">首页</a></li></c:if><%--            当有上一页"且"总页数>2时 显示上一页--%><c:if test="${(PageInfo.hasPreviousPage)&&(PageInfo.pages)>2}"><li><a href="${pageContext.request.contextPath}/book/allbook/${num-1}">&lt; 上一页</a></li></c:if><%--                循环显示页数--%><c:forEach items="${PageInfo.navigatepageNums}" var="num"><%--            只需要一个get请求去获得到pageIndex--%><li><a href="${pageContext.request.contextPath}/book/allbook/${num}">${num}</a></li></c:forEach><%--            当有下一页"且"总页数>2"且"当前页不是最后一页时 显示下一页--%><c:if test="${(PageInfo.hasPreviousPage)&&(PageInfo.pages)>2&&(PageInfo.pageNum!=PageInfo.navigateLastPage)}"><li><a href="${pageContext.request.contextPath}/book/allbook/${num+1}">下一页 &gt;</a></li></c:if><%--            当前页码+1<=总页数,则显尾页,即在最后一页时不显示尾页--%><c:if test="${PageInfo.pageNum+1<=PageInfo.pages}"><li><a href="${PageInfo.navigateLastPage}">尾页</a></li></c:if><span style="font-size: 20px;margin-left: 20px;color: #6363ee">共${PageInfo.pages}页</span>
<%--                <span style="font-size: 20px;margin-left: 20px;color: #6363ee">每页显示--%>
<%--                    <select>--%>
<%--                        <option value="${PageInfo.pageSize==5}">5</option>--%>
<%--                        <option value="${PageInfo.pageSize==10}">10</option>--%>
<%--                    </select>--%>
<%--                    条数据</span>--%><span style="font-size: 20px;margin-left: 20px;color: #6363ee">每页显示${PageInfo.pageSize}条信息</span><span style="font-size: 20px;margin-left: 20px;color: #6363ee">共${PageInfo.total}条信息</span></ul><form style="" action="${pageContext.request.contextPath}/book/upload" enctype="multipart/form-data" method="post"><table><td><input style="width: 190px" type="file" name="file"></td><td style="width: 100px"><input type="submit" value="点击上传"></td><td><a href="${pageContext.request.contextPath}/img/idea.png">展示图片</a>&nbsp;|&nbsp;<a href="${pageContext.request.contextPath}/book/download">点击下载</a></td></table></form></div></div>
</div>
</body>
</html>

3. 新增书籍页面 addBook.jsp

<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/25Time: 17:24To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>添加书籍</title><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>书籍列表----新增书籍</small></h1></div></div></div><form action="${pageContext.request.contextPath}/book/addBook" method="post"><div class="form-group"><label for="bkname">书籍名称</label><input type="text" class="form-control" id="bkname" name="bookname" placeholder="书籍名称" required></div><div class="form-group"><label for="author">作者</label><input type="text" class="form-control" id="author" name="author" placeholder="作者" required></div><div class="form-group"><label for="publish">出版社</label><input type="text" class="form-control" id="publish" name="publish" placeholder="出版社" required></div><div class="form-group"><label for="introduction">详情</label><input type="text" class="form-control" id="introduction" name="introduction" placeholder="书籍详情" required></div><div class="form-group"><label for="price">价格</label><input type="text" class="form-control" id="price" name="price" placeholder="价格" required></div><div class="select"><label for="booktype">书籍类别</label><input type="text" class="form-control" list="optionList" id="booktype" name="booktype" placeholder="书籍类别" required><datalist id="optionList"><option value="文学类">文学类</option><option value="历史类">历史类</option><option value="社会类">社会类</option><option value="爱情类">爱情类</option><option value="科幻类">科幻类</option><option value="社会文学类">社会文学类</option><option value="武侠类">武侠类</option><option value="亲情类">亲情类</option><option value="奇幻类">奇幻类</option><option value="政治类">政治类</option><option value="经济类">经济类</option><option value="其他类">其他类</option></datalist></div><button type="submit" class="btn btn-default btn-lg active" style="margin-left:1050px;margin-top: 30px">添加</button></form>
</div>
</body>
</html>

4. 修改书籍页面 updatebook.jsp

<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/25Time: 17:49To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>修改书籍</title><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"></head>
<body>
<div class="container"><div class="row clearfix"><div class="col-md-12 column"><div class="page-header"><h1><small>书籍列表----修改书籍</small></h1></div></div></div><form action="${pageContext.request.contextPath}/book/updateBook" method="get"><input type="hidden" name="bookid" value="${Book.bookid}"><div class="form-group"><label for="bookname">书籍名称</label><input type="text" class="form-control" id="bookname" name="bookname" value="${Book.bookname}" placeholder="书籍名称" required></div><div class="form-group"><label for="author">作者</label><input type="text" class="form-control" id="author" name="author" value="${Book.author}" placeholder="作者" required></div><div class="form-group"><label for="publish">出版社</label><input type="text" class="form-control" id="publish" name="publish" value="${Book.publish}" placeholder="出版社" required></div><div class="form-group"><label for="introduction">详情</label><input type="text" class="form-control" id="introduction" name="introduction" value="${Book.introduction}" placeholder="书籍详情" required></div><div class="form-group"><label for="price">价格</label><input type="text" class="form-control" id="price" name="price" value="${Book.price}" placeholder="价格" required></div><div class="form-group"><label for="booktype">书籍类别</label><input type="text" class="form-control" list="optionList" id="booktype" name="booktype" value="${Book.booktype}" placeholder="书籍类别" required><datalist id="optionList"><option value="文学类">文学类</option><option value="历史类">历史类</option><option value="社会类">社会类</option><option value="爱情类">爱情类</option><option value="科幻类">科幻类</option><option value="社会文学类">社会文学类</option><option value="武侠类">武侠类</option><option value="亲情类">亲情类</option><option value="奇幻类">奇幻类</option><option value="政治类">政治类</option><option value="经济类">经济类</option><option value="其他类">其他类</option></datalist></div><button type="submit" class="btn btn-default btn-lg active " style="margin-left:1050px;margin-top: 20px">修改</button></form>
</div>
</body>
</html>

5. 登录页 Login.jsp

<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/30Time: 14:20To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录</title><link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head><body>
<form action="${pageContext.request.contextPath}/book/Login" method="get"><div class="box"><div class="content"><div class="login-wrapper"><h1 style="font-family: 华文楷体;font-weight: bolder;font-size: 50px">登录</h1><div class="login-form"><div class="username form-item"><span style="font-weight: bolder;font-family: 华文宋体;font-size: 15px">用户名</span><input type="text" class="input-item" name="username" placeholder="请输入用户名"></div><div class="password form-item"><span style="font-weight: bolder;font-family: 华文宋体;font-size: 15px">密码</span><input type="password" class="input-item" name="password" placeholder="请输入密码"></div><span style="color: red;font-weight: bolder">${error1}</span><input type="submit" style="margin-bottom: 20px" class="login-btn" value="登录"><a class="astyle" href="${pageContext.request.contextPath}/book/toregisterPage" title="注册账号">没有账号?点击注册</a></div><div class="divider"><span class="line"></span><span class="divider-text">其他方式登录</span><span class="line"></span></div><div class="other-login-wrapper"><div class="other-login-item"><img src="../img/QQ.png" alt="啊!图片去月球度假了" title="使用QQ登录"></div><div class="other-login-item"><img src="../img/WeChat.png" alt="啊!图片去月球度假了" title="使用微信登录"></div></div></div></div></div>
</form>
</body></html>

6. 注册页 register.jsp

<%--Created by IntelliJ IDEA.User: 蜡笔小鑫Date: 2022/12/30Time: 15:49To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><link rel="stylesheet" href="${pageContext.request.contextPath}/css/register.css"><title>注册</title>
</head><body>
<form action="${pageContext.request.contextPath}/book/register"  method="get" ><div class="headbox"><p style="font-family: 华文新魏,serif;font-size: 40px">&nbsp;&nbsp;新用户注册</p><h1 style="font-size: 40px">USER REGISTER</h1><div class="hd_center"><div class="hd_form"><form action="${pageContext.request.contextPath}/book/register" method="get"><table style="margin-top: 40px"><tr><td class="td_left">用户名:</td><td class="td_right"><input type="text" name="username" placeholder="请输入注册用户名"></td></tr><tr></tr><tr></tr><tr><td class="td_left">密码:</td><td class="td_right"><input type="text" name="password" placeholder="请输入注册密码"></td></tr><tr></tr><tr></tr><tr><td></td><td colspan="2"><input type="submit"value="注册" target="_blank"></td></tr><tr><td></td><td><p style="text-align: right;">已有账号?<a href="${pageContext.request.contextPath}/book/toLogin" target="_blank">立即登录</a></p></td></tr></table></form></div></div></div>
</form>
</body></html>

7. css层

index.css

header {width: 1000px;height: 600px;position: relative;margin: 70px 60px auto;
}
.bigBox{width:1000px;height:600px;overflow:hidden;overflow-x: auto;white-space: nowrap;
}
.bigBox img{width: 100%;height: 100%;
}
.left{width: 70px;height: 70px;cursor: pointer;float: left;left: 0;top: 50%;background: url("../indexImg/left.png") ;
}
.right{width: 70px;height: 70px;cursor: pointer;float: right;right: 0;top: 50%;background: url("../indexImg/right.png") ;
}
#nav {bottom: 5px;left: 30%;margin: 10px 10px 150px 150px;
}#nav li {width: 30px;height: 30px;line-height: 30px;text-align: center;background: #ccc;font-size: 24px;border-radius: 9px;color: darkslategrey;font-family: 'Times New Roman', Times, serif;margin: 0 25px;float: left;cursor: pointer;list-style: none;
}#nav li:hover {background: peru;
}a{/*display: inline-block;*//*padding-left: 10px;*//*text-decoration: none;*//*color: black;*//*font-size: 30px;*/width: 250px;height: 70px;/*margin: 100px auto;*//*text-align: center;*//*line-height: 40px;*//*background: green;*//*border-radius: 5px 0px 0px 5px;*/
}.texts{width: 250px;height: 70px;text-align: center;line-height: 40px;
}
h1{font-family: 黑体, serif;font-size: xx-large;font-weight: bold;margin: 30px 50px 120px 40px;
}
.threesolid{font-size: 30px;color:#fefefe;text-shadow:0px 1px 0px #c0c0c0,0px 2px 0px #b0b0b0,0px 3px 0px #a0a0a0,0px 4px 0px #909090,0px 5px 10px rgba(0, 0, 0, .9);}@-webkit-keyframes stripe-slide {0% {background-position: 0% 0;}100% {background-position: 100% 0;}
}
@keyframes stripe-slide {0% {background-position: 0% 0;}100% {background-position: 100% 0;}
}
body {width: 100%;height: 100vh;display: flex;justify-content: center;align-items: center;flex-direction: column;font-family: sans-serif;
}
.btn {overflow: visible;margin: 0;padding: 0;border: 0;background: transparent;font: inherit;line-height: normal;cursor: pointer;-moz-user-select: text;display: block;text-decoration: none;text-transform: uppercase;padding: 16px 36px 22px;background-color: #fff;color: #666;border: 2px solid #666;border-radius: 6px;margin-bottom: 16px;transition: all 0.5s ease;
}
.btn::-moz-focus-inner {padding: 0;border: 0;
}
.btn--stripe {overflow: hidden;position: relative;
}
.btn--stripe:after {content: "";display: block;height: 7px;width: 100%;background-image: repeating-linear-gradient(45deg, #666, #666 1px, transparent 2px, transparent 5px);-webkit-backface-visibility: hidden;backface-visibility: hidden;border-top: 1px solid #666;position: absolute;left: 0;bottom: 0;background-size: 7px 7px;
}
.btn--stripe:hover {background-color: #666;color: #fff;border-color: #000;
}
.btn--stripe:hover:after {background-image: repeating-linear-gradient(45deg, #fff, #fff 1px, transparent 2px, transparent 5px);border-top: 1px solid #000;-webkit-animation: stripe-slide 12s infinite linear forwards;animation: stripe-slide 12s infinite linear forwards;
}
.btn--large {width: 50%;
}
.btn--radius {border-radius: 36px;
}

register.css

header {width: 1000px;height: 600px;position: relative;margin: 70px 60px auto;
}
.bigBox{width:1000px;height:600px;overflow:hidden;overflow-x: auto;white-space: nowrap;
}
.bigBox img{width: 100%;height: 100%;
}
.left{width: 70px;height: 70px;cursor: pointer;float: left;left: 0;top: 50%;background: url("../indexImg/left.png") ;
}
.right{width: 70px;height: 70px;cursor: pointer;float: right;right: 0;top: 50%;background: url("../indexImg/right.png") ;
}
#nav {bottom: 5px;left: 30%;margin: 10px 10px 150px 150px;
}#nav li {width: 30px;height: 30px;line-height: 30px;text-align: center;background: #ccc;font-size: 24px;border-radius: 9px;color: darkslategrey;font-family: 'Times New Roman', Times, serif;margin: 0 25px;float: left;cursor: pointer;list-style: none;
}#nav li:hover {background: peru;
}a{/*display: inline-block;*//*padding-left: 10px;*//*text-decoration: none;*//*color: black;*//*font-size: 30px;*/width: 250px;height: 70px;/*margin: 100px auto;*//*text-align: center;*//*line-height: 40px;*//*background: green;*//*border-radius: 5px 0px 0px 5px;*/
}.texts{width: 250px;height: 70px;text-align: center;line-height: 40px;
}
h1{font-family: 黑体, serif;font-size: xx-large;font-weight: bold;margin: 30px 50px 120px 40px;
}
.threesolid{font-size: 30px;color:#fefefe;text-shadow:0px 1px 0px #c0c0c0,0px 2px 0px #b0b0b0,0px 3px 0px #a0a0a0,0px 4px 0px #909090,0px 5px 10px rgba(0, 0, 0, .9);}@-webkit-keyframes stripe-slide {0% {background-position: 0% 0;}100% {background-position: 100% 0;}
}
@keyframes stripe-slide {0% {background-position: 0% 0;}100% {background-position: 100% 0;}
}
body {width: 100%;height: 100vh;display: flex;justify-content: center;align-items: center;flex-direction: column;font-family: sans-serif;
}
.btn {overflow: visible;margin: 0;padding: 0;border: 0;background: transparent;font: inherit;line-height: normal;cursor: pointer;-moz-user-select: text;display: block;text-decoration: none;text-transform: uppercase;padding: 16px 36px 22px;background-color: #fff;color: #666;border: 2px solid #666;border-radius: 6px;margin-bottom: 16px;transition: all 0.5s ease;
}
.btn::-moz-focus-inner {padding: 0;border: 0;
}
.btn--stripe {overflow: hidden;position: relative;
}
.btn--stripe:after {content: "";display: block;height: 7px;width: 100%;background-image: repeating-linear-gradient(45deg, #666, #666 1px, transparent 2px, transparent 5px);-webkit-backface-visibility: hidden;backface-visibility: hidden;border-top: 1px solid #666;position: absolute;left: 0;bottom: 0;background-size: 7px 7px;
}
.btn--stripe:hover {background-color: #666;color: #fff;border-color: #000;
}
.btn--stripe:hover:after {background-image: repeating-linear-gradient(45deg, #fff, #fff 1px, transparent 2px, transparent 5px);border-top: 1px solid #000;-webkit-animation: stripe-slide 12s infinite linear forwards;animation: stripe-slide 12s infinite linear forwards;
}
.btn--large {width: 50%;
}
.btn--radius {border-radius: 36px;
}

style.css(登录页样式)

@charset "UTF-8";
* {margin: 0;padding: 0;
}/*公共CSS*/
.box {width: 100vw;height: 100vh;background-color: rgb(29, 67, 89);
}
.box .content .login-wrapper .login-form .astyle{color: black;margin-left: 200px;text-decoration: none;
}
.box .content .login-wrapper .login-form .astyle:hover{color: #6363ee;font-weight: bolder;
}
.box .content .login-wrapper h1 {text-align: center;
}
.box .content .login-wrapper .login-form .form-item {margin: 20px 0;
}
.box .content .login-wrapper .login-form .form-item span {display: block;margin: 5px 20px;font-weight: 100;
}
.box .content .login-wrapper .login-form .form-item .input-item {width: 100%;border-radius: 40px;padding: 20px;box-sizing: border-box;font-size: 20px;font-weight: 200;
}
.box .content .login-wrapper .login-form .form-item .input-item:focus {outline: none;
}
.box .content .login-wrapper .login-form .login-btn {width: 100%;border-radius: 40px;color: #fff;border: 0;font-weight: 100;margin-top: 10px;cursor: pointer;
}
.box .content .login-wrapper .divider {width: 100%;margin: 20px 0;text-align: center;display: flex;align-items: center;justify-content: center;
}
.box .content .login-wrapper .divider span:nth-child(1) {flex: 1;
}
.box .content .login-wrapper .divider span:nth-child(3) {flex: 1;
}
.box .content .login-wrapper .divider .line {display: inline-block;max-width: 30%;width: 30%;
}
.box .content .login-wrapper .divider .divider-text {vertical-align: middle;margin: 0px 20px;line-height: 0px;display: inline-block;width: 100px;
}
.box .content .login-wrapper .other-login-wrapper {width: 100%;display: flex;justify-content: center;align-items: center;
}
.box .content .login-wrapper .other-login-item {border: 1px solid rgb(214, 222, 228);padding: 10px;margin: 10px;cursor: pointer;
}/*一般大于手机的尺寸CSS*/
@media (min-width: 767px) {.box {background-color: rgb(29, 67, 89);}.box .content {width: 85vw;height: 90vh;background: url('../img/login_two.jpg') no-repeat;background-size: 90% 100%;position: absolute;right: 15%;top: 50%;left: 50%;transform: translate(-50%, -50%);border-radius: 20px;background-color: #fff;}.box .content .login-wrapper {width: 25vw;position: absolute;right: 15%;top: 50%;transform: translateY(-50%);}.box .content .login-wrapper h1 {text-align: center;font-size: 45px;color: rgb(81, 100, 115);margin-bottom: 40px;}.box .content .login-wrapper .login-form {margin: 10px 0;}.box .content .login-wrapper .login-form .form-item span {color: rgb(81, 100, 115);}.box .content .login-wrapper .login-form .form-item .input-item {height: 60px;border: 1px solid rgb(214, 222, 228);}.box .content .login-wrapper .login-form .login-btn {height: 50px;background-color: rgb(59, 72, 89);font-size: 20px;}.box .content .login-wrapper .divider .line {border-bottom: 1px solid rgb(214, 222, 228);}.box .content .login-wrapper .other-login-item {border-radius: 20px;}.box .content .login-wrapper .other-login-item img {width: 40px;height: 40px;}
}
/*手机端CSS*/
@media (max-width: 768px) {.box .content {width: 100vw;height: 100vh;background: url("../img/login_bg_phone.png") no-repeat;background-size: 100% 100%;display: flex;align-items: flex-start;justify-content: center;}.box .content .login-wrapper {width: 70%;height: 60%;padding-top: 15%;}.box .content .login-wrapper h1 {font-size: 30px;color: #fff;}.box .content .login-wrapper .login-form .form-item {margin: 10px 0;}.box .content .login-wrapper .login-form .form-item span {color: rgb(113, 129, 141);}.box .content .login-wrapper .login-form .form-item .input-item {height: 30px;border: 1px solid rgb(113, 129, 141);background-color: transparent;color: #fff;}.box .content .login-wrapper .login-form .login-btn {height: 40px;background-color: rgb(235, 95, 93);font-size: 16px;}.box .content .login-wrapper .divider .line {border-bottom: 1px solid #fff;}.box .content .login-wrapper .divider .divider-text {color: #fff;}.box .content .login-wrapper .other-login-item {border-radius: 15px;}.box .content .login-wrapper .other-login-item img {width: 35px;height: 35px;}
}/*# sourceMappingURL=style.css.map */

8. js

index.js

// 五张图片的url
var oImg1 = "indexImg/1.jpg";
var oImg2 = "indexImg/2.jpg";
var oImg3 = "indexImg/3.jpg";
var oImg4 = "indexImg/4.jpg";
var oImg5 = "indexImg/5.jpg";
var oImg6 = "indexImg/6.jpg";
// 把5张图片存入一个数组
var arr = [oImg1, oImg2, oImg3, oImg4, oImg5 ,oImg6];window.onload = function() {//刚加载时第一张图片1号背景颜色document.getElementById("1").style.background = "peru";run()}//轮播
function run() {timer = setInterval(function() {//随机点数字时能接着变化var pic = document.getElementById("insert").name;//如果为最后一张图片则重新循环if (pic == 5) {pic = -1;}//点一个数字该数字背景颜色变化其余的不变var aLi = document.getElementsByTagName("li");for (var j = 0; j < aLi.length; j++) {aLi[j].style.backgroundColor = "#CCCCCC";}var i = parseInt(pic);//  图片地址document.getElementById("insert").src = arr[i + 1];document.getElementById("insert").name = i + 1;//数字随图片变化switch (i) {case 0:var temp = '2';break;case 1:var temp = '3';break;case 2:var temp = '4';break;case 3:var temp = '5';break;case 4:var temp = '6';break;case -1:var temp = '1';break;}document.getElementById(temp).style.background = "peru"}, 5000)
}//右箭头
function goForward() {var temp = document.getElementById("insert").name;var oBox = document.getElementById("insert");var aLi = document.getElementsByTagName("li");// 数字跟着图片一起变for (var i = 0; i < aLi.length; i++) {aLi[i].style.backgroundColor = "#CCCCCC";}switch (temp) {case "0":var n = '2';break;case "1":var n = '3';break;case "2":var n = '4';break;case "3":var n = '5';break;case "4":var n = '6';break;case "5":var n = '1';break;}document.getElementById(n).style.background = "peru"// 向右移动图片for (var j = 0; j < arr.length; j++) {if (j < 5) {if (temp == j) {oBox.src = arr[j + 1];}} else {if (temp == 5) {oBox.src = arr[0];}}}// 轮到最后一张图片时返回第一张if (temp < 5) {oBox.name = parseInt(temp) + 1;} else {oBox.name = 0;}
}//左箭头
function goBack() {var temp = document.getElementById("insert").name;var oBox = document.getElementById("insert")var aLi = document.getElementsByTagName("li");// 图片移动时数字也跟着变for (var i = 0; i < aLi.length; i++) {aLi[i].style.backgroundColor = "#CCCCCC";}switch (temp) {case "0":var n = '6';break;case "1":var n = '1';break;case "2":var n = '2';break;case "3":var n = '3';break;case "4":var n = '4';break;case "5":var n = '5';break;}document.getElementById(n).style.background = "peru"// 向左移动图片for (var j = 0; j < arr.length; j++) {if (j > 0) {if (temp == j) {oBox.src = arr[j - 1];}} else {if (temp == 0) {oBox.src = arr[5];}}}// 轮到第一张图片时返回最后一张if (temp > 0) {oBox.name = parseInt(temp) - 1;} else {oBox.name = 5;}
}//指定图片
function move(num) {var oBox = document.getElementById("insert");var temp = document.getElementById("insert").name;var aLi = document.getElementsByTagName("li");for (var i = 0; i < aLi.length; i++) {aLi[i].style.backgroundColor = "#CCCCCC";}document.getElementById(num.innerHTML).style.background = "peru"switch (num.innerHTML) {case "1":oBox.src = arr[0];oBox.name = 0;break;case "2":oBox.src = arr[1];oBox.name = 1;break;case "3":oBox.src = arr[2];oBox.name = 2;break;case "4":oBox.src = arr[3];oBox.name = 3;break;case "5":oBox.src = arr[4];oBox.name = 4;break;case "6":oBox.src = arr[5];oBox.name = 5;break;}
}

img和indexImg均为图片,可以自行添加.

uplode是文件上传的位置

3 图片展示

1. index.jsp

2. 因为拦截器的原因在这里无论点击登录还是进入书籍页面都会被拦截到登录页面 Login.jsp

3. 想要进行注册,进入注册页面 register.jsp

点击注册或立即登录都会重新跳转到登录页面Login,jsp

4. 进行登录,使用的是user表里的用户信息

5. 点击登录进入allbook首页(第一页)

其中包括了Controller层内的大部分操作:新增,修改,删除,查询书籍,回到登录页,注销用户,分页显示,文件的上传及下载

6. 新增书籍页面 addbook.jsp

7. 修改书籍页面 updatebook.jsp

8. 书籍查询

9. 分页操作

10.文件上传

11. 下载

ok ,项目展示到此结束

4 附上源码文件(百度网盘):

链接:https://pan.baidu.com/s/1IrCCDYkcxbszNR7dmceEew?pwd=gbz8 
提取码:gbz8

基于SSM框架简易项目“书籍管理系统”,超详细讲解,附源码相关推荐

  1. java计算机毕业设计ssm基于SSM框架的旅游订票系统s0s38(附源码、数据库)

    java计算机毕业设计ssm基于SSM框架的旅游订票系统s0s38(附源码.数据库) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstor ...

  2. 基于ssm框架的校园订餐系统设计与实现 毕业设计-附源码270912

    校园订餐系统的设计与实现                                                                       摘 要 信息化社会内需要与之针对性 ...

  3. 【HTML | CSS】纯CSS居然能做出这种效果,一款宝藏网页分享(超详细讲解 | 附源码)

  4. 计算机毕业设计ssm基于SSM框架在线电影评论投票系统3gr0f系统+程序+源码+lw+远程部署

    计算机毕业设计ssm基于SSM框架在线电影评论投票系统3gr0f系统+程序+源码+lw+远程部署 计算机毕业设计ssm基于SSM框架在线电影评论投票系统3gr0f系统+程序+源码+lw+远程部署 本源 ...

  5. (精品)JAVA SSM框架黄淮学院食堂仓库管理系统的设计与实现源码+论文+查重报告+效果、安装视频+ppt模板(已降重)

    项目介绍: (精品)JAVA SSM框架黄淮学院食堂仓库管理系统的设计与实现源码+论文+查重报告+效果.安装视频+ppt模板(已降重) 高清视频演示: https://www.bilibili.com ...

  6. 基于ssm的论坛系统的设计与实现【附源码】

    基于ssm的论坛系统的设计与实现 摘 要 早期的网络论坛系统已经诞生一段时间,随着互联网技术的发展,它已经从最初的简单电子公告板系统变成了一种丰富的论坛系统社区模型.人们通过论坛系统进行信息的获取.发 ...

  7. Springboot+mysql+基于VUE框架的商城综合项目设计与实现 毕业设计-附源码111612

    基于VUE框架的商城综合项目设计与实现 摘 要 随着科学技术的飞速发展,社会的方方面面.各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,商城综合项目当然也不能排除在外.商城综合项目 ...

  8. 基于SSM的家教系统的设计与实现毕业设计-附源码221752

    摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题.针对家教系统服务等问题,对 ...

  9. 微信小程序UI自动化实践:python+minium+PO模式(超详细教程附源码供下载)

    文章目录 前言 一.minium介绍 二.安装环境 1. 安装minium doc 2. 安装minium 3. 启动小程序 三.准备知识 1. 启动 2. 配置 3. 命令行运行 4. 元素定位 5 ...

最新文章

  1. 鱼眼图像的unwarping过程
  2. 富士康裁员六万,试图用机器人扭转赤字?
  3. hdu 3666 THE MATRIX PROBLEM
  4. 为Spring Cloud Config Server配置远程git仓库
  5. WPF messagebox生命周期的探讨
  6. datagrip导入csv数据配合ajax+mysql+Flask实验
  7. iis5.0+php5.0+mysql5.0配置完全手册_IIS5.0+PHP5.0+MySQL5.0配置完全手册
  8. 数据结构之DFS与BFS实现
  9. 【java】Java 8 - 移除Permgen 使用元空间
  10. mybatis配置 SqlMapConfig.xml user.xml
  11. java web 分页_Java Web(十一) 分页功能的实现
  12. 数据结构实验2-不带头结点的单链表
  13. 福昕PDF阅读器文本复制功能设置
  14. 华为交换机Hybird 与 单臂路由
  15. service常驻后台
  16. 签名证书(.keystore)生成指南
  17. 彻底理解 Linux 的搜索工具: grep 和 awk
  18. 文字识别(二)--字符识别技术总览
  19. Ubuntu 16.04系统实用插件安装方法
  20. 西安地图 百度西安高清卫星地图 最高19级 可商用地图

热门文章

  1. 微电子电路——反相器级联
  2. python实例练习(15)搜索关键词自动提交
  3. Unity3d实现Projector(喷码效果)
  4. 优动漫PAINNT——漫画原稿纸的基础知识介绍
  5. Android Studio 制作微信界面 上
  6. 帧同步优化难点及解决方案
  7. 大数据团队必须设置的五种职位
  8. ETW绕过PoC测试1--关闭你的ProcMon.exe
  9. 计算机硬件系统由 组成,计算机硬件系统由哪几部分组成?
  10. 厨神之路六--凉拌菜