Like you who love programming!
Learn SpringBoot actual combat course https://edu.csdn.net/course/detail/31433
Learn SpringCloud introductory course https://edu.csdn.net/course/detail/31451
Preface
This article takes you to develop a SpringBoot case and master the application development skills of SpringBoot integrating MyBatis-Plus, SpringMVC, Thymeleaf and interceptors.
Case Introduction
The case includes two functions:
login page and book list display: login page
login failed to
log in successfully to see the book list The
database contains two tables:
tb_user user table
tb_book books table
Integrate MyBatis-Plus
MyBatis-Plus is an enhanced framework of MyBatis, which provides general Mapper and Service interfaces.
Import dependencies
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Configuration file
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/book_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
resources:
static-locations: classpath:static/
mybatis-plus:
mapper-locations: classpath:mappers/*.xml
type-aliases-package: com.blb.day12_spring_boot.entity
User entity class
@Data
@TableName("tb_user")
public class User implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String realName;
}
Book entity
@Data
@TableName("tb_book")
public class Book {
@TableId(type = IdType.AUTO)
private Integer id;
private String bookName;
private float price;
private Integer typeId;
private String author;
private String publishOrg;
private String publishTime;
private Integer state;
private String bookImage;
}
User Mapper interface
public interface UserMapper extends BaseMapper<User> {
}
Book Mapper interface
public interface BookMapper extends BaseMapper<Book> {
}
User Service interface
public interface UserService extends IService<User> {
}
Book Service interface
public interface BookService extends IService<Book>{
}
User Service interface implementation class
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
}
Book Service interface implementation class
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
Integrate SpringMVC
Import dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Controller for page jump
/**
* 页面跳转控制器
* 例: http://localhost:8080/pages/login 跳转 login页面
*/
@Controller
@RequestMapping("pages")
public class PageController {
@RequestMapping("{page}")
public String toPage(@PathVariable("page")String page){
return page;
}
}
User login controller
/**
* 用户登录控制器
*/
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("login")
public String login(Model model, HttpSession session, String username, String password){
//使用MyBatis-Plus的通用service查询账号和密码
User user = userService.getOne(new QueryWrapper<User>().eq("username", username)
.eq("password", password));
//查询失败,提示错误
if(user == null){
model.addAttribute("msg","账号或密码错误");
return "login";
}
//查询成功,保存user对象,跳转书籍列表页面
session.setAttribute("user",user);
return "redirect:/book/list";
}
}
Book controller
/**
* 书籍控制器
*/
@Controller
@RequestMapping("book")
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("list")
public String list(Model model){
//查询所有书籍,跳转到index.html
List<Book> list = bookService.list();
model.addAttribute("books",list);
return "index";
}
}
Integrate Thymeleaf
SpringBoot does not support JSP by default. It supports a template engine technology that is better than JSP: Thymeleaf
Thymeleaf's advantages:
-
Combination of dynamic and static: Thymeleaf can run in both networked and non-networked environments, that is, it allows artists to view the static effect of the page in the browser, and it also allows the programmer to view the dynamic page effect with data on the server. This is because it supports html prototypes, and then adds additional attributes to html tags to achieve template + data display. When the browser interprets html, it ignores undefined tag attributes, so the thymeleaf template can run statically; when data is returned to the page, the Thymeleaf tag will dynamically replace the static content to make the page display dynamically.
-
Out of the box: It provides two dialects, standard and spring standard, and can directly apply templates to achieve JSTL and OGNL expression effects, avoiding the trouble of daily template, jstl, and label change. At the same time, developers can also extend and create custom dialects.
-
Multi-dialect support: Thymeleaf provides spring standard dialects and an optional module that is perfectly integrated with SpringMVC, which can quickly implement form binding, attribute editor, internationalization and other functions.
-
Perfectly integrated with SpringBoot, SpringBoot provides the default configuration of Thymeleaf, and sets the view resolver for Thymeleaf. We can operate Thymeleaf as we did before with jsp. There is almost no difference in the code, that is, there is a difference in template syntax.
Import dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Create a new HTML file in the resources/templates directory.
Add a namespace to the html tag of the page: xmlns:th=“http://www.thymeleaf.org”
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h1>Hello 登录页面</h1>
<span th:text="${msg}" style="color:red"></span>
<form action="/user/login" method="post">
<input type="text" name="username" placeholder="请输入账号"><br>
<input type="password" name="password" placeholder="请输入密码"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<table >
<thead>
<tr>
<th>编号</th>
<th>书名</th>
<th>价格</th>
<th>类型</th>
<th>作者</th>
<th>出版社</th>
<th>出版日期</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="book : ${books}">
<td th:text="${book.id}"></td>
<td th:text="${book.bookName}"></td>
<td th:text="${book.price}"></td>
<td th:text="${book.typeId}"></td>
<td th:text="${book.author}"></td>
<td th:text="${book.publishOrg}"></td>
<td th:text="${book.publishTime}"></td>
<td th:text="${book.state}"></td>
<td> </td>
</tr>
</tbody>
</table>
</body>
</html>
Two Thymeleaf tags are used on the page:
- th:text is
used to bind text content, the expression ${xx} is similar to EL, which binds the name of the data passed in the background - th:each is
used to loop through the collection content, the format is: Variable name: ${collection name}
Integrated interceptor
The login function needs to add the SpringMVC interceptor, otherwise the user can directly access the book list without verification. The
idea is:
- Save the user object to the Session after successful login
- The interceptor intercepts the user request, if there is no user object in the Session, it will force login
- Log in if there is a user object
public class MyLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获得session的user对象
User user = (User) request.getSession().getAttribute("user");
if(user == null){
//没有登录,拦截,强制登录
response.sendRedirect("/pages/login");
return false;
}
//登录,就放行
return true;
}
}
Configure interceptor
/**
* 拦截器配置
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(new MyLoginInterceptor())
//配置拦截路径 所有
.addPathPatterns("/**")
//配置不拦截路径
.excludePathPatterns("/**/login","/**/*.css","/**/*.js");
super.addInterceptors(registry);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//重写这个方法,映射静态资源文件
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/public/");
super.addResourceHandlers(registry);
}
}
End
If you need to learn other Java knowledge, poke here ultra-detailed knowledge of Java Summary