基于SSM框架的图书管理系统

一、项目展示

1. 访问链接

项目已部署在服务器,点击即可访问

http://42.192.184.23:8080/ssmbuild

  • 账号 yolin
  • 密码 123456

2. 登录页

使用session对象存储用户登录信息,使用SpringMvc自带拦截器拦截非法请求。Ajax动态监听用户操作,判断用户是否存在于数据库系统并返回消息。

3.CRUD

C3P0连接池连接数据库,mybatis操作数据库;搜索采用模糊查询。

二、环境搭建

1. 环境

  • MySQL 5.5.36
  • Tomcat 7.0.991
  • IDEA
  • Maven 3.6.3

2. 创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create database ssmbuild;

use ssmbuild;

create table books(
bookID int(10) not null auto_increment primary key comment '书id',
bookName varchar(100) not null comment '书名',
bookCounts int(11) not null comment '数量',
detail varchar(200) not null comment '描述'
) engine=innodb default charset=utf8

insert into books (bookID,bookName,bookCounts,detail)values
(1,'Java',1,'从入门到入土'),
(2,'MySql',10,'从删库到跑路'),
(3,'Linux',5,'从入门到放弃');

3. 创建Maven项目,导入依赖

①. 配置阿里仓库

不能正常导入Maven依赖时将下面代码加入pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<repositories>
<repository>
<id>alimaven</id>
<name>Maven Aliyun Mirror</name>
<url>https://repo.maven.apache.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

②. 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!--    依赖:junit,数据库驱动,连接池,servlet,jsp,mybatis,mybatis-spring,spring-->

<dependencies>
<!-- Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</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</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</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.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- Spring-->
<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.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>

③. 防止资源导出失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

三、项目结构分析

xyz.yolin.pojo
    |__Books.java
    |__User.java
xyz.yolin.dao
    |__BookMapper.java
    |__BookMapper.xml
xyz.yolin.service
    |__BookService.java
    |__BookServiceImpl.java
xyz.yolin.controller
    |__BookController.java
xyz.yolin.config
    |__LoginInterceptor.java

四、Mybatis层

1. 数据库配置文件database.properties

1
2
3
4
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123

2. 编写数据库对应实体类xyz.yolin.pojo.Books

1
2
3
4
5
6
7
8
9
10

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookId;
private String bookName;
private int bookCounts;
private String detail;
}

3. 编写MyBatis核心配置文件mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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="xyz.yolin.pojo"/>
</typeAliases>

<mappers>
<mapper class="xyz.yolin.dao.BookMapper"/>
</mappers>
</configuration>

通过配置文件关联到实体类的Mapper文件,该配置文件配置了每个类对数据库所需进行的sql语句映射。

4. 编写Mapper接口BookMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface BookMapper {
//增加一本书
int addBook(Books books);

//删除一本书
int deleteBook(@Param("bookId") int id);

//更新一本书
int updateBook(Books book);

//查询一本书
Books queryBook(@Param("bookId") int id);

//查询全部的书
List<Books> queryAllBook();

//根据书名查询图书
List<Books> queryBookByName(String bookName);
}

@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应

5. 编写接口对应的文件BookMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="xyz.yolin.dao.BookMapper">
<insert id="addBook" parameterType="Books">
insert into books (bookId,bookName,bookCounts,detail)
values (#{bookId},#{bookName},#{bookCounts},#{detail});
</insert>
<delete id="deleteBook" parameterType="int">
delete from books where BookID=#{bookId};
</delete>
<update id="updateBook" parameterType="Books">
update books set bookName=#{bookName},bookCounts=#{bookCounts},
detail=#{detail} where bookID=#{bookId};
</update>
<select id="queryBook" resultType="Books">
select * from books where bookID=#{bookId};
</select>
<select id="queryAllBook" resultType="Books">
select * from books;
</select>
<select id="queryBookByName" resultType="Books">
select * from books where bookName=#{bookName};
</select>
</mapper>

写完后需要回到第3步将Mapper.xml绑定到配置文件中

6. 编写Service层的接口和实现类

接口BookService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface BookService {
//增加一本书
int addBook(Books books);

//删除一本书
int deleteBook(int id);

//更新一本书
int updateBook(Books book);

//查询一本书
Books queryBook(int id);

//查询全部的书
List<Books> queryAllBook();

//根据书名查书籍
List<Books> queryBookByName(String bookName);
}

实现类BookServiceImpl.Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class BookServiceImpl implements BookService {
//service层调用dao层的操作,设置一个set接口,方便Spring托管
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}

@Override
public int addBook(Books books) {
return bookMapper.addBook(books);
}

@Override
public int deleteBook(int id) {
return bookMapper.deleteBook(id);
}

@Override
public int updateBook(Books book) {
return bookMapper.updateBook(book);
}

@Override
public Books queryBook(int id) {
return bookMapper.queryBook(id);
}

@Override
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}

@Override
public List<Books> queryBookByName(String name) {
return bookMapper.queryBookByName(name);
}
}

五、Spring层

1. 编写Spring整合MyBatis的配置文件:Spring-dao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1.关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/>

<!-- 2.连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

<!-- c3p0连接池的私有属性 -->
<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>

<!-- 3.sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="xyz.yolin.dao"/>
</bean>
</beans>

有了MapperScannerConfigurer就不需要我们去为每个映射接口去声明一个bean了,像之前写一个Dao的实现类。

  • MapperFactoryBean是一个用于根据Mapper接口生成Mapper对象的类,通过MapperFactoryBean可以配置接口文件以及注入SqlSessionFactory,从而完成一个bean的实例化
  • MapperScannerConfigurer是用于以自动扫描形式来配置MyBatis中映射器的类,可通过配置包路径自动扫描包接口生成映射器。

2. Spring整合service层spring-service.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1.扫描service下的包-->
<context:component-scan base-package="xyz.yolin.service"/>

<!-- 2.将我们所有的业务类注入到Spring,可通过配置或注解实现-->
<bean id="BookServiceImpl" class="xyz.yolin.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>

<!-- 3.声明式事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>

六、Spring MVC层

1. 给项目增加web支持,编写web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--启动级别-1-->
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!-- 过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

2.Springmvc-servlet.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="xyz.yolin.controller"/>
<!--让Spring MVC不处理静态资源-->
<mvc:default-servlet-handler/>
<!--支持mvc注解驱动-->
<mvc:annotation-driven/>
<!--添加视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>

3. Spring配置整合文件:applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config/>
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="springmvc-servlet.xml"/>
</beans>

七、测试

Junit测试查询所有书籍

八、Controller和视图层

1. 编写Controller类BookController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;

//查询全部书籍,返回页面
@RequestMapping("/allBook")
public String list(Model model){
List<Books> books = bookService.queryAllBook();
model.addAttribute("list",books);
return "allBooks";
}
//跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addBook";
}
//添加书籍的请求
@RequestMapping("/addBook")
public String addBook(Books books){
bookService.addBook(books);
return "redirect:/book/allBook";
}
//跳转到修改页面
@RequestMapping("updateBook")
public String toUpdatePaper(int id,Model model){
Books books = bookService.queryBook(id);
model.addAttribute("book",books);
return "updateBook";
}
//修改书籍
@RequestMapping("updateBookMsg")
public String updateBookMsg(Books book){
int i = bookService.updateBook(book);
if (i>0){
System.out.println("数据修改成功");
}
return "redirect:/book/allBook";
}
//删除书籍
@RequestMapping("/todeleteBook")
public String deleteBook(int id){
System.out.println(id);
int i = bookService.deleteBook(id);
return "redirect:/book/allBook";
}
//查询书籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName,Model model){
List<Books> books = bookService.queryBookByName(queryBookName);
if(books.size()==0){
System.out.println("没有相关书籍");
model.addAttribute("err","没有相关书籍");
}
model.addAttribute("list",books);
return "allBooks";
}
}

@Qualifier注解的用处:当一个接口有多个实现的时候,为了指名具体调用哪个类的实现

2. 编写首页 index.jsp

1
2
3
4
5
6
7
8
9
10
11
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
</h3>
</body>
</html>

${pageContext.request.contextPath} 是JSP取得绝对路径的方法,等价于 <%=request.getContextPath()%>

3. 书籍列表页面 allbook.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<!-- 引入 Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="page-header">
<h1>书籍列表</h1>
<br>
</div>
</div>

<div class="row">
<div class="col-md-4 column">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>&nbsp;
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/allBook">显示所有书籍</a>
</div>
<div class="col-md-4 column"></div>
<br>
<div class="col-md-4 column" style="float: right;">
<%--查询书籍--%>
<form action="${pageContext.request.contextPath}/book/queryBook" method="post">
<input type="text" name="queryBookName" placeholder="请输入要查询的书籍名称" required>
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
<br>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead>

<%--使用foreach遍历书籍--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookId}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
<td>
<a href="${pageContext.request.contextPath}/book/updateBook?id=${book.bookId}">修改</a>
&nbsp|&nbsp
<a href="${pageContext.request.contextPath}/book/todeleteBook?id=${book.bookId}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<h3>${err}</h3>
</div>
</body>
</html>

4. 添加书籍页面 addBook.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="page-header">
<h1>新增书籍</h1>
<br>
</div>
</div>
<form role="form" action="${pageContext.request.contextPath}/book/addBook" method="post">
<div class="form-group">
<label >书籍ID:</label>
<input type="text" class="form-control" name="bookId" placeholder="书籍ID" >
</div>
<div class="form-group">
<label >书籍名称:</label>
<input type="text" class="form-control" name="bookName" placeholder="书籍名称" required>
</div>
<div class="form-group">
<label>书籍数量:</label>
<input type="text" class="form-control" name="bookCounts" placeholder="书籍数量" required>
</div>
<div class="form-group">
<label >书籍描述</label>
<input type="text" class="form-control" name="detail" placeholder="添加书籍相关内容" required>
</div>
<div class="form-group" align="center">
<input type="submit" class="btn btn-default" value="添加">
</div>
</form>
</div>
</body>
</html>

5. 修改书籍页面 updateBook.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="page-header">
<h1>修改书籍</h1>
<br>
</div>
</div>

<form role="form" action="${pageContext.request.contextPath}/book/updateBookMsg" method="post">
<%--前端传递隐藏域--%>
<input type="hidden" class="form-control" name="bookId" value="${book.bookId}">
<div class="form-group">
<label >书籍名称:</label>
<input type="text" class="form-control" name="bookName" value="${book.bookName}" required>
</div>
<div class="form-group">
<label>书籍数量:</label>
<input type="text" class="form-control" name="bookCounts" value="${book.bookCounts}" required>
</div>
<div class="form-group">
<label >书籍描述</label>
<input type="text" class="form-control" name="detail" value="${book.detail}" required>
</div>
<div class="form-group" align="center">
<input type="submit" class="btn btn-default" value="修改">
</div>
</form>
</div>

</body>
</html>

九、内容完善(登录、拦截器)

1.实现用户登录功能

添加用户登录界面 login.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.bdstatic.com/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<style>

body{
background-color: #e9e9e9;
}
.container{
height:400px;
width:600px;
background-color:#FFF;
box-shadow: 18px 18px 30px rgba(0,0,0,0.4),
-18px -18px 30px rgba(255,255,255,0.5);
margin:80px auto;
border-radius:10px;
border:1px solid #FFF;
}


.usrform{
width:500px;
margin:60px auto;
}
input{
/*text-indent:10px;*/
display:block;
width:320px;
height:35px;
border-radius:10px;

margin:20px auto;
outline:none;
text-align:center;
border:0.5px solid gray;
}
input:hover{
border:0.5px solid gray;
}
.btn{
width: 100px;
cursor:pointer;
color:#FFF;
background-image:linear-gradient(135deg,#ABCDFF 10%,gray 100%);
}
.btn:hover{
background-image:linear-gradient(135deg,lightgray 10%,gray 100%);
border-style:none;
}

.loginbtn{
margin: 20px 40%;
border: 1px solid black;
}
a{
text-decoration: none;
}
.fontCont{
height: 25px;
width: 325px;
padding: 0;
margin-top: -20px;
margin-left: 85px;
text-align: center;
/*border: 1px solid black;*/
color: red;
}
</style>
<script>
function a1() {
$.post({
url:"${pageContext.request.contextPath}/book/login",
data:{'username':$("#name").val()},
success:function (data) {
if(data.toString()=='OK'){
$("#userInfo").css("color","green");
}else{
$("#userInfo").css("color","red");
}
$("#userInfo").html(data);
}
});
}

function a2() {
$.post({
url:"${pageContext.request.contextPath}/book/login",
data:{'password':$("#pwd").val()},
success:function (data) {
if(data.toString()=='OK'){
$("#pwdInfo").css("color","green");
}else{
$("#pwdInfo").css("color","red");
}
$("#pwdInfo").html(data);
}
});
}
</script>
</head>
<body>
<h3 align="center" style="height: 60px">${msg}</h3>
<div class="container">
<div class="usrform">
<form action="${pageContext.request.contextPath}/book/logininfo" method="post" >
<div style="width: 100%;height: 100px;border: 1px solid aliceblue">
<label style="margin: 30px;position: absolute" >账号</label>
<input id="name" type="text" class="usr" name="username" required onblur="a1()"/>
<div class="fontCont"><p id="userInfo" class="fon"></p></div>
</div>
<div style="width: 100%;height: 100px;border: 1px solid aliceblue">
<label style="margin: 30px;position: absolute">密码</label>
<input id="pwd" type="password" class="pwd" name="password" required onblur="a2()"/>
<div class="fontCont"><p id="pwdInfo" class="fon"></p></div>
</div>
<div style="width: 100%;height: 50px;"><input type="submit" class="btn loginbtn" value="登陆"></div>
</form>
</div>
</div>
</body>
</html>

index.jsp页面添加内容

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
<a href="${pageContext.request.contextPath}/book/tologin">进入书籍登陆页面</a>
</h3>
</body>
</html>

验证登录的操作

完成BookMapper接口代码和配置文件中sql语句的编写,再到Service中组合。

(具体代码省略)

编写Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@RequestMapping("/tologin")
public String tologin(){
return "login";
}
//判断用户登录
@RequestMapping("/logininfo")
public String logininfo(HttpSession session,User user, Model model){
System.out.println("用户:"+user);
User user1 = bookService.checkLogin(user.getUsername());
System.out.println("数据库:"+user1);
if (user1!=null&&user1.getPassword().equals(user.getPassword())){
//把用户信息存在session中
session.setAttribute("userInfo",user);
return "redirect:/book/allBook";
}else {
model.addAttribute("msg","密码错误,登录失败,请重新登陆");
}
return "login";
}

//ajax
@RequestMapping("/login")
@ResponseBody
public String login(String username,String password){
System.out.println(username);
String name=username;
String pwd=password;
String msg="";
System.out.println(name.length());
if(name.length()<=3||name.length()>10){
return "账号输入有误,应为4~10位";
}
User user1 = bookService.checkLogin(name);
if(name!=null){
if(user1!=null){
return "OK";
}else{
return "用户不存在";
}
}
return msg;
}

2. 拦截器

编写类LoginInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if(request.getRequestURI().contains("tologin")){
return true;
}
if(request.getRequestURI().contains("login")){
return true;
}
if(session.getAttribute("userInfo")!=null){
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}

springmvc-servlet.xml添加拦截器

1
2
3
4
5
6
7
<mvc:interceptors>
<mvc:interceptor>
<!--包括这个请求下面的所有请求-->
<mvc:mapping path="/book/**"/>
<bean class="xyz.yolin.config.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

至此,基本功能已经实现,还需继续完善!

请我喝杯咖啡吧~

支付宝
微信