我有话说:
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 项目简介
- JDK1.8; mysql8.0.31; mybatis3.5.2; mybatis–spring2.0.2; spring–webmvc及springjdbc都是5.1.9.RELEASE(个人认为目前是用的最舒服的一版)
2.开发软件:
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 '用户密码rn',
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 预先准备操作
1. 右键单击Book模块,选择框架支持,选择web应用程序(4.0版本);也可以在选择Maven项目是使用web–app模板,但是不推荐.
然后在项目中会多出来一个web的文件夹,注意:文件夹图标的小圆点一定要是亮着的,否则去Facet中调整选择到当前的项目.
<?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>
启动Tomcat后浏览器进入名为$Title$的index.jsp页面,并显示$END信息,表示Tomcat配置没问题
2.3 开始配置项目
java文件夹下属于源码文件,resources文件夹下属于资源文件,web下是前端的一些配置文件及页面.
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;
}
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);
// 通过书名查询书籍,因为可能是一个集合,所以用List
List<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 configuration
PUBLIC "-//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>
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/beans
http://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 = mysql
reasonable = 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/beans
http://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 version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//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 user
where 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>
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);
}
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;
}
@Override
public int addBook(Book book) {
return bookMapper.addBook(book);
}
@Override
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
@Override
public int updateBook(Book book) {
return bookMapper.updateBook(book);
}
@Override
public Book queryBookById(int id) {
return bookMapper.queryBookById(id);
}
@Override
public PageInfo<Book> queryBookByName(String bookname) {
List<Book> list = bookMapper.queryBookByName(bookname);
return new PageInfo<>(list);
}
@Override
public User findUserByNameAndPassword(User user) {
return bookMapper.findUserByNameAndPassword(user);
}
@Override
public 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);
}
@Override
public 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/beans
http://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/beans
http://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
在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(); //设置页面不缓存,清空buffer
response.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;
}
}
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 {
@Override
public 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文件
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 蜡笔小鑫
Date: 2022/12/29
Time: 15:11
To 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/25
Time: 14:38
To 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}">< 上一页</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}">下一页 ></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>
|
<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/25
Time: 17:24
To 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>
<%--
Created by IntelliJ IDEA.
User: 蜡笔小鑫
Date: 2022/12/25
Time: 17:49
To 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/30
Time: 14:20
To 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/30
Time: 15:49
To 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">
新用户注册
</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均为图片,可以自行添加.
3 图片展示
1. index.jsp
3. 想要进行注册,进入注册页面 register.jsp
点击注册或立即登录都会重新跳转到登录页面Login,jsp
4. 进行登录,使用的是user表里的用户信息
5. 点击登录进入allbook首页(第一页)
其中包括了Controller层内的大部分操作:新增,修改,删除,查询书籍,回到登录页,注销用户,分页显示,文件的上传及下载
6. 新增书籍页面 addbook.jsp
8. 书籍查询
9. 分页操作
10.文件上传
11. 下载
ok ,项目展示到此结束
4 附上源码文件(百度网盘):
链接:https://pan.baidu.com/s/1IrCCDYkcxbszNR7dmceEew?pwd=gbz8
提取码:gbz8
原文地址:https://blog.csdn.net/m0_74135466/article/details/128593695
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_37816.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!