從零到一搭建SpringBoot專案
一、新建springboot專案
1、
new-->Project-->Spring Initralizr
Group:com.ruovea
Artifact:spbshiro
springboot version:2.0.4
2、
將
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
改成
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3、此時專案結構
maven clean一下,右鍵SpbshiroApplication執行,專案就跑起來了,就是這麼簡單,真正做到了開箱即用。
二、RestFul Api介面
1、在controller包下新建HomeController
package com.ruovea.spbshiro.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@RequestMapping("/")
public String home(){
return "Hello, spbshiro!";
}
}
注:RestController和Controller註解的區別是:RestController是返回的內容就是返回的內容,相當於加個@ResponseBody,而controller一般是返回的頁面
此時開啟網頁,輸入 http://localhost:8080/
就會看到Hello,Zbook!
三、整合Thymleaf
1、
上面的可以當作是提供服務的介面,假設我們要開發一個web應用,springboot預設是整合的thymleaf。
springboot是約定大於配置的,我們來看看關於thymleaf的約定
(1)預設靜態檔案(js,css,jpg等)放在resources下面的static資料夾下面
(2)頁面檔案放在templates資料夾下面
我們採用bootstrap來渲染頁面,如下圖
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>登入</title>
<!-- 新 Bootstrap 核心 CSS 檔案 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<form action="login_in" method="post" class="form-horizontal" role="form" >
<div class="form-group">
<h2 class="col-sm-offset-5 col-sm-4">使用者登入</h2>
</div>
<div class="form-group">
<label for="username" class="col-sm-offset-3 col-sm-2 control-label">使用者名稱:</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="username" name="username" placeholder="請輸入使用者名稱" />
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-offset-3 col-sm-2 control-label">密碼:</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="password" name="password" placeholder="請輸入密碼" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-5 col-sm-4">
<button type="submit" class="btn btn-default">登入</button>
</div>
</div>
</form>
</div>
<!-- jQuery檔案。務必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 檔案 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
2、寫一個LoginController
package com.ruovea.spbshiro.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("/login")
public String login(){
return "login";
}
}
3、加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
4、
重啟, http://localhost:8081/login
則會看到登入頁面
四、整合mybatis
1、
springboot的配置檔案分為兩種:application.properties和application.yml
我們把它改成application.yml這種更直觀
spring:
application:
name: spbtoken
output:
ansi:
enabled: always
profiles:
active: dev
thymeleaf:
encoding: UTF-8
prefix: classpath:/templates/
server:
tomcat:
uri-encoding: UTF-8
max-connections: 500
min-spare-threads: 25
max-threads: 300
accept-count: 200
port: 8081
mybatis:
type-aliases-package: com.ruovea.spbshiro.mapper
mapper-locations: classpath:mapping/*.xml
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
logging:
level:
com.zb.mapper: debug
---
#開發配置
spring:
profiles: dev
datasource:
url: jdbc:mysql://dburl:3306/javalearn?serverTimezone=GMT
username: javalearn
password: javalearn2020
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
filters: stat
maxActive: 20
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
2、新增依賴
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>RELEASE</version>
</dependency>
<!-- 分頁外掛 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
3、建表
CREATE datebase javalearn;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`mobile` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
`nickname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(1, 'admin', '123456', '13918891675','[email protected]', '男', '管理員');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(2, 'lisi2', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(3, 'lisi3', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(4, 'lisi4', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(5, 'lisi5', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(6, 'lisi6', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(7, 'lisi7', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(8, 'lisi8', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(9, 'lisi9', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(10, 'lisi10', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(11, 'lisi11', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(12, 'lisi12', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(13, 'lisi13', '123456', '13918891675','[email protected]', 'm', 'lisi1');
insert into `user`(id, username, password, mobile, email,sex, nickname) VALUES(14, 'lisi14', '123456', '13918891675','[email protected]', 'm', 'lisi1');
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rolename` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`create_time` DATE DEFAULT NULL,
`update_time` DATE DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`permissionname` varchar(255) DEFAULT NULL,
`resourceType` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`permission` varchar(255) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`create_time` DATE DEFAULT NULL,
`update_time` DATE DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `user_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`role_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `role_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` varchar(255) DEFAULT NULL,
`permission_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (1, 'admin', '管理員', 'use', '2018-08-10', '2018-08-10');
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (2, 'manage', '經理', 'use', '2018-08-10', '2018-08-10');
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (3, 'user', '普通使用者', 'use', '2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (1,'使用者管理','menu', 'userlist','user:list','use','2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (2,'使用者修改','menu', 'useredit','user:edit','use','2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (3,'使用者刪除','menu', 'userdelete','user:delete','use','2018-08-10', '2018-08-10');
INSERT INTO `user_role` (id, user_id, role_id) VALUES (1, 1 ,1);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (2, 1 ,2);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (3, 1 ,3);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (4, 2 ,2);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (5, 3 ,3);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (6, 4 ,3);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (1, 1, 1);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (2, 1, 2);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (3, 1, 3);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (4, 2, 1);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (5, 2, 2);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (6, 3, 1);
4、用mybatisgenerator自動生成檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 資料庫驅動:選擇你的本地硬碟上面的資料庫驅動包-->
<classPathEntry location="D:\MavenRepository\mysql\mysql-connector-java\5.1.6\mysql-connector-java-5.1.6.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<!-- 是否去除自動生成的註釋 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--資料庫連結URL,使用者名稱、密碼 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://dburl:3306/javalearn?serverTimezone=GMT"
userId="javalearn"
password="javalearn2020">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!-- 生成模型的包名和位置-->
<javaModelGenerator targetPackage="com.ruovea.spbshiro.model" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成對映檔案的包名和位置-->
<sqlMapGenerator targetPackage="mapping" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成DAO的包名和位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.ruovea.spbshiro.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名-->
<table tableName="boot_user" domainObjectName="User" enableCountByExample="false"
enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
<!-- 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名-->
<!-- <table tableName="boot_permission" domainObjectName="Permission" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false">-->
<!-- </table>-->
<!-- <!– 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名–>-->
<!-- <table tableName="boot_role" domainObjectName="Role" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false">-->
<!-- </table>-->
<!-- <!– 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名–>-->
<!-- <table tableName="boot_role_permission" domainObjectName="RolePermission" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false">-->
<!-- </table>-->
<!-- <!– 要生成的表 tableName是資料庫中的表名或檢視名 domainObjectName是實體類名–>-->
<!-- <table tableName="boot_user_role" domainObjectName="UserRole" enableCountByExample="false"-->
<!-- enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"-->
<!-- selectByExampleQueryId="false">-->
<!-- </table>-->
</context>
</generatorConfiguration>
5、在pom裡面新增plugin
<!-- mybatis generator 自動生成程式碼外掛 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
6、用mvn mybatis-generator:generate -e命令生成檔案
此時目錄結構
7、寫dao和service,controller,mapper
mapper增加了幾個方法
@Select("Select * from user")
List<User> selectAll();
@Select("Select * from user where username = #{username} and password = #{password}")
User selectByUsernamePass(@Param("username") String username, @Param("password") String password);
@Select("Select * from user where username = #{username}")
User selectByUsername(@Param("username") String username);
dao和service都是正常呼叫,下面是controller
package com.ruovea.spbtoken.controller;
import com.github.pagehelper.PageInfo;
import com.ruovea.spbtoken.model.User;
import com.ruovea.spbtoken.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/user")
@ResponseBody
public User getUserById(int id){
User user = userService.selectByPrimaryKey(id);
return user;
}
@RequestMapping("/userlist")
public String getUserList(Model model, PageInfo pageInfo){
int pageNum = (pageInfo.getPageNum() == 0)? 1 : pageInfo.getPageNum();
int pageSize = (pageInfo.getPageSize() == 0)? 10 : pageInfo.getPageSize();
PageInfo<User> result = userService.selectAll(pageNum, pageSize);
model.addAttribute("users", result.getList());
model.addAttribute("pageInfo", result);
return "userlist";
}
@RequestMapping("/userdelete")
public String userdelete(int id){
userService.deleteByPrimaryKey(id);
return "redirect:/userlist";
}
@RequestMapping("/useredit")
public String useredit(int id, Model model){
User user = userService.selectByPrimaryKey(id);
model.addAttribute("user", user);
return "useredit";
}
@RequestMapping(value = "/userupdateoradd", method = RequestMethod.POST)
public String userUpdateOrAdd(User user){
if(user.getId() == 0){
userService.insertSelective(user);
} else {
userService.updateByPrimaryKeySelective(user);
}
return "redirect:/userlist";
}
}
頁面userlist.html
package com.ruovea.spbtoken.controller;
import com.github.pagehelper.PageInfo;
import com.ruovea.spbtoken.model.User;
import com.ruovea.spbtoken.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/user")
@ResponseBody
public User getUserById(int id){
User user = userService.selectByPrimaryKey(id);
return user;
}
@RequestMapping("/userlist")
public String getUserList(Model model, PageInfo pageInfo){
int pageNum = (pageInfo.getPageNum() == 0)? 1 : pageInfo.getPageNum();
int pageSize = (pageInfo.getPageSize() == 0)? 10 : pageInfo.getPageSize();
PageInfo<User> result = userService.selectAll(pageNum, pageSize);
model.addAttribute("users", result.getList());
model.addAttribute("pageInfo", result);
return "userlist";
}
@RequestMapping("/userdelete")
public String userdelete(int id){
userService.deleteByPrimaryKey(id);
return "redirect:/userlist";
}
@RequestMapping("/useredit")
public String useredit(int id, Model model){
User user = userService.selectByPrimaryKey(id);
model.addAttribute("user", user);
return "useredit";
}
@RequestMapping(value = "/userupdateoradd", method = RequestMethod.POST)
public String userUpdateOrAdd(User user){
if(user.getId() == 0){
userService.insertSelective(user);
} else {
userService.updateByPrimaryKeySelective(user);
}
return "redirect:/userlist";
}
}
8,在ZbookApplication上加上註解掃描
@ComponentScan(basePackages = {"com.ruovea"})
@MapperScan("com.ruovea.spbtoken.mapper")
9、順便把分頁加上(依賴包之前已經加了)
service層
@Override
public PageInfo<User> selectAll(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userDao.selectAll();
PageInfo<User> pageInfo = new PageInfo<>(users);
return pageInfo;
}
controller層
public String getUserList(Model model, PageInfo pageInfo){
int pageNum = (pageInfo.getPageNum() == 0)? 1 : pageInfo.getPageNum();
int pageSize = (pageInfo.getPageSize() == 0)? 10 : pageInfo.getPageSize();
PageInfo<User> result = userService.selectAll(pageNum, pageSize);
model.addAttribute("users", result.getList());
model.addAttribute("pageInfo", result);
return "userlist";
}
頁面修改:
<div id="example" style="text-align: center"> <ul id="pageLimit"></ul> </div>
<input type="hidden" id="pageNum" name="pageNum" th:value="${pageInfo.pageNum}" />
<input type="hidden" id="pages" name="pages" th:value="${pageInfo.pages}" />
<script src="/js/bootstrap-paginator.min.js"></script>
<script>
$('#pageLimit').bootstrapPaginator({
currentPage: $("#pageNum").val(),
totalPages: $("#pages").val(),
size: "normal",
bootstrapMajorVersion: 3,
alignment: "right",
numberOfPages: 5,
itemTexts: function (type, page, current) {
switch (type) {
case "first": return "首頁";
case "prev": return "上一頁";
case "next": return "下一頁";
case "last": return "末頁";
case "page": return page;
}
},
onPageClicked: function (event, originalEvent, type, page){//給每個頁首繫結一個事件,其實就是ajax請求,其中page變數為當前點選的頁上的數字。
window.location.href = "userlist?pageNum=" + page;
}
});
$(function(){
$(".delete_a").click(function(){
var userId=$(this).attr("value");
if(confirm("確認刪除嗎?")){
window.location.href="/userdelete?id=" + userId;
return ;
}
});
});
</script>
此時目錄
此時重啟,輸入 http://localhost:8081/userlist
就會看到user列表,也可以分頁。
五、簡單登入,用filter實現
1、
package com.ruovea.spbtoken.filter;
import com.ruovea.spbtoken.model.User;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"})
public class SessionFilter implements Filter {
String NO_LOGIN = "您還未登入";
String[] includeUrls = new String[]{"/login","/login_in"};
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
HttpSession session = request.getSession();
String url = request.getRequestURI();
boolean needFilter = isNeedFilter(url);
//靜態資源放行
if(url.endsWith(".css")||url.endsWith(".js")||url.endsWith(".jpg")
||url.endsWith(".gif")||url.endsWith(".png")){
filterChain.doFilter(servletRequest, servletResponse);
return;
}
if(!needFilter){
filterChain.doFilter(servletRequest, servletResponse);
} else {
User user = (User)session.getAttribute(session.getId());
if(user != null){
filterChain.doFilter(servletRequest, servletResponse);
} else {
String requestType = request.getHeader("X-Requested-With");
//判斷是否是ajax請求
if(requestType!=null && "XMLHttpRequest".equals(requestType)){
response.getWriter().write(this.NO_LOGIN);
}else{
//重定向到登入頁(需要在static資料夾下建立此html檔案)
response.sendRedirect(request.getContextPath()+"/login");
}
return;
}
}
}
public boolean isNeedFilter(String uri) {
for (String includeUrl : includeUrls) {
if(includeUrl.equals(uri)) {
return false;
}
}
return true;
}
@Override
public void destroy() {
}
}
2、在ZbookApplication上加註解
@ServletComponentScan
3、在LoginController下寫登入邏輯
package com.ruovea.spbtoken.controller;
import com.ruovea.spbtoken.model.User;
import com.ruovea.spbtoken.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(){
return "login";
}
@RequestMapping(value = "/login_in", method = RequestMethod.POST)
public String login_in(User user, HttpServletRequest request, Model model){
User user1 = userService.validateUser(user.getUsername(), user.getPassword());
if(user1 == null){
return "login";
}
HttpSession session = request.getSession();
session.setAttribute(session.getId(), user1);
return "redirect:/userlist";
}
@RequestMapping("/logout")
public String logout(HttpServletRequest request){
request.getSession().removeAttribute(request.getSession().getId());
return "login";
}
}
現在就可以簡單的登入了
4、修改頁面讓頁面顯示使用者名稱和退出
<div>
<a href="logout" style="display: inline-block; float: right">退出</a>
<p th:text="${#httpSession.getAttribute(#httpSession.getId()).username}" style="display: inline-block; float: right"></p>
<p style="display: inline-block; float: right">您好,</p>
</div>
六、許可權
許可權管理我們使用現在比較流行的shiro,原理就不說了,直接說怎麼使用
1、加依賴包
<!--shiro許可權-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2、建表
shiro需要5張表:使用者、角色、許可權、使用者角色關聯表,角色許可權關聯表
使用者表已建立,現在續建4張表
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rolename` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`create_time` DATE DEFAULT NULL,
`update_time` DATE DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`permissionname` varchar(255) DEFAULT NULL,
`resourceType` varchar(255) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
`permission` varchar(255) DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
`create_time` DATE DEFAULT NULL,
`update_time` DATE DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `user_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`role_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `role_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role_id` varchar(255) DEFAULT NULL,
`permission_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (1, 'admin', '管理員', 'use', '2018-08-10', '2018-08-10');
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (2, 'manage', '經理', 'use', '2018-08-10', '2018-08-10');
insert into `role`(id, rolename, description, status, create_time, update_time) VALUES (3, 'user', '普通使用者', 'use', '2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (1,'使用者管理','menu', 'userlist','user:list','use','2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (2,'使用者修改','menu', 'useredit','user:edit','use','2018-08-10', '2018-08-10');
INSERT INTO `permission` (id, permissionname, resourceType, url, permission, status, create_time, update_time) VALUES (3,'使用者刪除','menu', 'userdelete','user:delete','use','2018-08-10', '2018-08-10');
INSERT INTO `user_role` (id, user_id, role_id) VALUES (1, 1 ,1);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (2, 1 ,2);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (3, 1 ,3);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (4, 2 ,2);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (5, 3 ,3);
INSERT INTO `user_role` (id, user_id, role_id) VALUES (6, 4 ,3);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (1, 1, 1);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (2, 1, 2);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (3, 1, 3);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (4, 2, 1);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (5, 2, 2);
INSERT INTO `role_permission` (id, role_id, permission_id) VALUES (6, 3, 1);
3、載入bean
package com.ruovea.spbshiro.ShiroConfig;
import java.util.LinkedHashMap;
import java.util.Map;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
/**
* Shiro 配置
*
Apache Shiro 核心通過 Filter 來實現,就好像SpringMvc 通過DispachServlet 來主控制一樣。
既然是使用 Filter 一般也就能猜到,是通過URL規則來進行過濾和許可權校驗,所以我們需要定義一系列關於URL的規則和訪問許可權。
*/
@Configuration
public class ShiroConfiguration {
private static final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);
@Bean
public FilterRegistrationBean delegatingFilterProxy(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
DelegatingFilterProxy proxy = new DelegatingFilterProxy();
proxy.setTargetFilterLifecycle(true);
proxy.setTargetBeanName("shiroFilter");
filterRegistrationBean.setFilter(proxy);
return filterRegistrationBean;
}
/**
* ShiroFilterFactoryBean 處理攔截資原始檔問題。
* 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,以為在
* 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
*
Filter Chain定義說明
1、一個URL可以配置多個Filter,使用逗號分隔
2、當設定多個過濾器時,全部驗證通過,才視為通過
3、部分過濾器可指定引數,如perms,roles
*
*/
@Bean("shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager){
logger.info("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必須設定 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//攔截器.
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
//配置退出過濾器,其中的具體的退出程式碼Shiro已經替我們實現了
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/*/*.js", "anon");
filterChainDefinitionMap.put("/*/*.css", "anon");
filterChainDefinitionMap.put("/login_in", "anon");
filterChainDefinitionMap.put("/login", "anon");
//<!-- 過濾鏈定義,從上向下順序執行,一般將 /**放在最為下邊 -->:這是一個坑呢,一不小心程式碼就不好使了;
//<!-- authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不設定預設會自動尋找Web工程根目錄下的"/login.jsp"頁面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登入成功後要跳轉的連結
shiroFilterFactoryBean.setSuccessUrl("/userlist");
//未授權介面;
shiroFilterFactoryBean.setUnauthorizedUrl("/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager