個人根據教程的每天的工作進度的代碼和資料 密碼:cti5
b站在線視頻
微信搜索"藝術行者",關注並回復關鍵詞"企業權限管理"獲取視頻和教程資料!
功能介紹
-
商品查詢
-
商品添加
-
訂單查詢
-
訂單分頁查詢
-
訂單詳情查詢
-
用戶管理
-
角色管理
-
資源權限管理
-
權限關聯與控制
-
AOP日志處理
數據庫介紹
- 產品表
- 訂單表
- 會員表
- 旅客表
- 用戶表
- 角色表
- 資源權限表
- 日志表
第一天
前端使用的技術:AdminLTE
-
簡介:AdminLTE是一款建立在bootstrap和jquery之上的開源的模板主題工具,它提供了一系列響應的、可重復使用的組件,並內置了多個模板頁面;同時自適應多種屏幕分辨率,兼容PC和移動端。通過AdminLTE,我們可以快速的創建一個響應式的Html5網站。AdminLTE框架在網頁架構與設計上,有很大的輔助作用,尤其是前端架構設計師,用好AdminLTE 不但美觀,而且可以免去寫很大CSS與JS的工作量。
-
獲取AdminLTE:
英文版:https://github.com/ColorlibHQ/AdminLTE
中文版:https://github.com/itheima2017/adminlte2-itheima
現成的都在資料里
數據庫准備工作
數據庫:Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Prod
Oracle 為每個項目創建單獨user,每個用戶有獨立表空間,oracle數據存放在表空間下。
- 使用管理員連接到數據庫,創建用戶,並分配相應的權限
create user simth identified by simth;
grant connect, resource to simth;
- 使用simth用戶連接數據庫
- 創建產品表
CREATE TABLE product(id varchar2(32) default SYS_GUID() PRIMARY KEY,
productNum VARCHAR2(50) NOT NULL,
productName VARCHAR2(50),
cityName VARCHAR2(50),
DepartureTime timestamp,
productPrice Number,
productDesc VARCHAR2(500),
productStatus INT,
CONSTRAINT product UNIQUE (id, productNum));
- 插入數據
insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,productdesc, productstatus)
values ('676C5BD1D35E429A8C2E114939C5685A', 'itcast-002', '北京三日游', '北京', to_timestamp('10-10-2018 10:10:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1200, '不錯的旅行', 1);
insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,productdesc, productstatus)
values ('12B7ABF2A4C544568B0A7C69F36BF8B7', 'itcast-003', '上海五日游', '上海', to_timestamp('25-04-2018 14:30:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1800, '魔都我來了', 0);
insert into PRODUCT (id, productnum, productname, cityname, departuretime, productprice,productdesc, productstatus)
values ('9F71F01CB448476DAFB309AA6DF9497F', 'itcast-001', '北京三日游', '北京', to_timestamp('10-10-2018 10:10:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 1200, '不錯的旅行', 1);
- MAVEN工程搭建
- 設置工程的pom.xml文件
<?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>
<artifactId>enterpriseJurisdiction-ssm</artifactId>
<modules>
<module>hacker-ssm-web</module>
</modules>
<groupId>hacker.org</groupId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<oracle.version>10.2.0.1.0</oracle.version>
<mybatis.version>3.4.5</mybatis.version>
<spring.security.version>5.0.1.RELEASE</spring.security.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency> <!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency> <!-- log end -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>${oracle.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
- 創建子模塊
- hacker-ssm-web(使用maven的web骨架)
- hacker-ssm-domain
- hacker-ssm-service
- hacker-ssm-dao
- hacker-ssm-utils
- hacker-ssm-web
- 設置hacker-ssm-web模塊的pom.xml文件
<?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>hacker.org</groupId>
<artifactId>hacker-ssm-web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>hacker-ssm-web Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.itheima.heima_ssm</groupId>
<artifactId>heima_ssm_service</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.itheima.heima_ssm</groupId>
<artifactId>heima_ssm_domain</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>heima_ssm_web</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8888</port>
</configuration>
<version>2.2</version>
</plugin>
</plugins>
</build>
</project>
- 創建java和resources目錄並標記
- hacker-ssm-dao(剩下的幾個模塊和dao模塊的創建基本一樣)
- 各模塊創建完成后
- 編寫產品實體類
package com.hacker.ssm.domain;
import java.util.Date;
public class Product {
private String id; // 主鍵
private String productNum; // 編號唯一
private String productName; // 名稱
private String cityName; // 出發城市
private Date departureTime; // 出發時間
private String departureTimeStr;
private double productPrice; // 產品價格
private String productDesc; // 產品描述
private Integer productStatus; // 狀態 0 關閉 1 開啟
private String productStatusStr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getProductNum() {
return productNum;
}
public void setProductNum(String productNum) {
this.productNum = productNum;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public Date getDepartureTime() {
return departureTime;
}
public void setDepartureTime(Date departureTime) {
this.departureTime = departureTime;
}
public String getDepartureTimeStr() {
return departureTimeStr;
}
public void setDepartureTimeStr(String departureTimeStr) {
this.departureTimeStr = departureTimeStr;
}
public double getProductPrice() {
return productPrice;
}
public void setProductPrice(double productPrice) {
this.productPrice = productPrice;
}
public String getProductDesc() {
return productDesc;
}
public void setProductDesc(String productDesc) {
this.productDesc = productDesc;
}
public Integer getProductStatus() {
return productStatus;
}
public void setProductStatus(Integer productStatus) {
this.productStatus = productStatus;
}
public String getProductStatusStr() {
return productStatusStr;
}
public void setProductStatusStr(String productStatusStr) {
this.productStatusStr = productStatusStr;
}
}
- 編寫持久層接口
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 11:51
*/
public interface IProductDao {
//查詢所有的產品信息
@Select("select * from product")
public List<Product> findAll() throws Exception;
}
- 編寫業務層接口
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:46
*/
public interface IProductService {
List<Product> findAll() throws Exception;
}
- 編寫service實現類
package org.hacker.ssm.service.impl;
import org.hacker.ssm.dao.IProductDao;
import org.hacker.ssm.domain.Product;
import org.hacker.ssm.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:47
*/
@Service
@Transactional
public class ProductServiceImpl implements IProductService {
@Autowired
private IProductDao productDao;
@Override
public List<Product> findAll() throws Exception {
return productDao.findAll();
}
}
SSM整合
Spring環境搭建
- 編寫數據庫配置文件db.properties
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@10.211.55.23:1521:orcl
jdbc.username=smith
jdbc.password=simth
- 編寫Spring配置文件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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 開啟注解掃描,管理service和dao -->
<context:component-scan base-package="org.hacker.ssm.dao"/>
<context:component-scan base-package="org.hacker.ssm.service"/>
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置連接池 -->
<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}"/>
</bean>
<!-- 交給IOC管理 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 掃描dao接口 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.hacker.ssm.dao"/>
</bean>
<!-- 配置Spring的聲明式事務管理 -->
<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
SpringMVC環境搭建
- 配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 掃描controller的注解,別的不掃描 -->
<context:component-scan base-package="org.hacker.ssm.controller"/>
<!-- 配置視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- JSP文件所在的目錄 -->
<property name="prefix" value="/pages/"/>
<!-- 文件的后綴名 -->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 設置靜態資源不過濾 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/img/" mapping="/img/**"/>
<mvc:resources location="/plugins/" mapping="/plugins/**"/>
<!-- 開啟對SpringMVC注解的支持 -->
<mvc:annotation-driven/>
<!--
支持AOP的注解支持,AOP底層使用代理技術
JDK動態代理,要求必須有接口
cglib代理,生成子類對象,proxy-target-class="true" 默認使用cglib的方式
-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
- 配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 配置加載類路徑的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!-- 配置監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 前端控制器(加載classpath:springmvc.xml 服務器啟動創建servlet) -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化參數,創建完DispatcherServlet對象,加載springmvc.xml配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 服務器啟動的時候,讓DispatcherServlet對象創建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 解決中文亂碼過濾器 -->
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- 導入log4j日志文件
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
# log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# log4j.appender.LOGFILE.File=d:\axis.log
# log4j.appender.LOGFILE.Append=true
# log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
# log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
- 編寫controller
package org.hacker.ssm.controller;
import org.hacker.ssm.service.IProductService;
import org.hacker.ssm.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:00
*/
@Controller
@RequestMapping("/product")
public class ProductController {
@Autowired
private IProductService productService;
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
ModelAndView mv = new ModelAndView();
List<Product> ps = productService.findAll();
mv.addObject("productList", ps);
mv.setViewName("product-list1");
return mv;
}
}
- 運行查看情況
clean->install 父工程 然后 clean->install web工程 如果出現異常就按照依賴關系clean->install
使用mvn tomcant7:run,可以使用maven插件,也可以配置好點擊
- 運行后,瀏覽器結果
- 導入插件,將pages里的靜態文件換為jsp文件,導入到web工程中
- 修改index.jsp代碼
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<body>
<jsp:forward page="/pages/main.jsp"></jsp:forward>
</body>
</html>
- 運行項目,查看效果
- 產品管理現在可以查詢數據庫的產品
增加產品添加功能
- 往controller類里添加增加代碼
package org.hacker.ssm.controller;
import org.hacker.ssm.service.IProductService;
import org.hacker.ssm.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:00
*/
@Controller
@RequestMapping("/product")
public class ProductController {
@Autowired
private IProductService productService;
@RequestMapping("/save.do")
public String save(Product product) {
productService.save(product);
return "redirect:finaAll.do";//重新回到list界面
}
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
ModelAndView mv = new ModelAndView();
List<Product> ps = productService.findAll();
mv.addObject("productList", ps);
mv.setViewName("product-list1");
return mv;
}
}
- 修改IProductService代碼
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:46
*/
public interface IProductService {
//從數據庫查詢所有商品
List<Product> findAll() throws Exception;
//添加商品
void save(Product product);
}
- 修改ProductServiceImpl代碼
package org.hacker.ssm.service.impl;
import org.hacker.ssm.dao.IProductDao;
import org.hacker.ssm.domain.Product;
import org.hacker.ssm.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 10:47
*/
@Service
@Transactional
public class ProductServiceImpl implements IProductService {
@Autowired
private IProductDao productDao;
@Override
public List<Product> findAll() throws Exception {
return productDao.findAll();
}
@Override
public void save(Product product) {
productDao.save();
}
}
- 修改IProductDao代碼
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 11:51
*/
public interface IProductDao {
//查詢所有的產品信息
@Select("select * from product")
public List<Product> findAll() throws Exception;
//保存商品
@Insert("insert into product(productNum,productName,cityName,departureTime,productPrice,productDesc,productStatus)" +
"values(#{productNum},#{productName},#{cityName},#{departureTime},#{productPrice},#{productDesc},#{productStatus})")
void save(Product product);
}
-
此時,運行項目,瀏覽器會出現400錯誤
出現的異常:Field error in object 'product' on field 'departureTime': rejected value [2020-04-04 07:00]; typeMismatch.product.departureTime
-
添加工具類轉換時間
package org.hacker.ssm.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtils {
//日期轉換成字符串
public static String date2String(Date date, String patt) {
SimpleDateFormat sdf = new SimpleDateFormat(patt);
String format = sdf.format(date);
return format;
}
//字符串轉換成日期
public static Date string2Date(String str, String patt) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(patt);
Date parse = sdf.parse(str);
return parse;
}
}
-
修改domina代碼,因為前端頁面獲取到的數據類型是String和數據庫表中的時間類型是Date,所以需要轉換
這里是用Spring為我們提供的注解
@DateTimeFormat將字符串轉換為Date類型
@JsonFormat將日期轉換為string類型
因為product-add.jsp獲取出發時間時,使用input標簽獲取的是一個字符串,這里需要轉換為Date類型,所以使用Spring提供的@DateTimeFormat注解
- 這里用到了utils包,根據不同的情況,給出不同的描述
- 結果
第一天的工作完畢
第二天
數據庫填充數據及創建相應的實體類
- 在數據庫創建會員表並插入數據
CREATE TABLE member
(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
NAME VARCHAR2(20),
nickname VARCHAR2(20),
phoneNum VARCHAR2(20),
email VARCHAR2(20)
);
insert into MEMBER (id, name, nickname, phonenum, email)
values ('E61D65F673D54F68B0861025C69773DB', '張三', '小三', '18888888888', 'zs@163.com');
- 在數據庫創建訂單表並插入數據
CREATE TABLE orders
(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
orderNum VARCHAR2(20) NOT NULL UNIQUE,
orderTime timestamp,
peopleCount INT,
orderDesc VARCHAR2(500),
payType INT,
orderStatus INT,
productId varchar2(32),
memberId varchar2(32),
FOREIGN KEY (productId) REFERENCES product (id),
FOREIGN KEY (memberId) REFERENCES member (id)
);
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('0E7231DC797C486290E8713CA3C6ECCC', '12345',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'676C5BD1D35E429A8C2E114939C5685A', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('5DC6A48DD4E94592AE904930EA866AFA', '54321',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'676C5BD1D35E429A8C2E114939C5685A', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('2FF351C4AC744E2092DCF08CFD314420', '67890',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('A0657832D93E4B10AE88A2D4B70B1A28', '98765',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('E4DD4C45EED84870ABA83574A801083E', '11111',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('96CC8BD43C734CC2ACBFF09501B4DD5D', '22222',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'12B7ABF2A4C544568B0A7C69F36BF8B7', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('55F9AF582D5A4DB28FB4EC3199385762', '33333',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('CA005CF1BE3C4EF68F88ABC7DF30E976', '44444',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');
insert into ORDERS (id, ordernum, ordertime, peoplecount, orderdesc, paytype, orderstatus, productid, memberid)
values ('3081770BC3984EF092D9E99760FDABDE', '55555',
to_timestamp('02-03-2018 12:00:00.000000', 'dd-mm-yyyy hh24:mi:ss.ff'), 2, '沒什么', 0, 1,
'9F71F01CB448476DAFB309AA6DF9497F', 'E61D65F673D54F68B0861025C69773DB');
- 在數據庫創建旅客表並插入數據
CREATE TABLE traveller
(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
NAME VARCHAR2(20),
sex VARCHAR2(20),
phoneNum VARCHAR2(20),
credentialsType INT,
credentialsNum VARCHAR2(50),
travellerType INT
);
insert into TRAVELLER (id, name, sex, phonenum, credentialstype, credentialsnum, travellertype)
values ('3FE27DF2A4E44A6DBC5D0FE4651D3D3E', '張龍', '男', '13333333333', 0, '123456789009876543', 0);
insert into TRAVELLER (id, name, sex, phonenum, credentialstype, credentialsnum, travellertype)
values ('EE7A71FB6945483FBF91543DBE851960', '張小龍', '男', '15555555555', 0, '987654321123456789', 1);
- 在數據庫創建旅客-會員表並插入數據
drop table order_traveller;
CREATE TABLE order_traveller(
orderId varchar2(32),
travellerId varchar2(32),
PRIMARY KEY (orderId,travellerId),
FOREIGN KEY (orderId) REFERENCES orders(id),
FOREIGN KEY (travellerId) REFERENCES traveller(id)
)
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('0E7231DC797C486290E8713CA3C6ECCC', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('2FF351C4AC744E2092DCF08CFD314420', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('3081770BC3984EF092D9E99760FDABDE', 'EE7A71FB6945483FBF91543DBE851960');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('55F9AF582D5A4DB28FB4EC3199385762', 'EE7A71FB6945483FBF91543DBE851960');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('5DC6A48DD4E94592AE904930EA866AFA', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('96CC8BD43C734CC2ACBFF09501B4DD5D', 'EE7A71FB6945483FBF91543DBE851960');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('A0657832D93E4B10AE88A2D4B70B1A28', '3FE27DF2A4E44A6DBC5D0FE4651D3D3E');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('CA005CF1BE3C4EF68F88ABC7DF30E976', 'EE7A71FB6945483FBF91543DBE851960');
insert into ORDER_TRAVELLER (orderid, travellerid)
values ('E4DD4C45EED84870ABA83574A801083E', 'EE7A71FB6945483FBF91543DBE851960');
- 編寫member實體類->traveller->order實體類
package org.hacker.ssm.domain;
/**
* @author HackerStar
* @create 2020-04-22 11:14
*/
public class Memeber {
private String id; //無意義,主鍵
private String name;//姓名
private String nickname;//昵稱
private String phoneNum;//電話號碼
private String email;//郵箱
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
package org.hacker.ssm.domain;
/**
* @author HackerStar
* @create 2020-04-22 11:28
*/
public class Traveller {
private String id;//無意義,主鍵
private String name;//姓名
private String sex;//性別
private String phoneNum;//電話號碼
private Integer credentialsType;//證件類型 0 身份證 1 護照 2 軍官證
private String credentialsTypeStr;//證件類型描述
private String credentialsNum;//證件號碼
private Integer travellerType;//旅客類型 0 成人 1 兒童
private String travellerTypeStr;//旅客類型描述
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public Integer getCredentialsType() {
return credentialsType;
}
public void setCredentialsType(Integer credentialsType) {
this.credentialsType = credentialsType;
}
public String getCredentialsTypeStr() {
return credentialsTypeStr;
}
public void setCredentialsTypeStr(String credentialsTypeStr) {
this.credentialsTypeStr = credentialsTypeStr;
}
public String getCredentialsNum() {
return credentialsNum;
}
public void setCredentialsNum(String credentialsNum) {
this.credentialsNum = credentialsNum;
}
public Integer getTravellerType() {
return travellerType;
}
public void setTravellerType(Integer travellerType) {
this.travellerType = travellerType;
}
public String getTravellerTypeStr() {
return travellerTypeStr;
}
public void setTravellerTypeStr(String travellerTypeStr) {
this.travellerTypeStr = travellerTypeStr;
}
}
package org.hacker.ssm.domain;
import java.lang.reflect.Member;
import java.util.Date;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:11
*/
public class Orders {
private String id;//無意義,主鍵
private String orderNum;//訂單編號 不為空 唯一
private Date orderTime;//下單時間
private String orderTimeStr;
private int orderStatus;//訂單狀態(1 未支付 1 已支付)
private String orderStatusStr;
private int peopleCount;//出行人數
private Product product;//產品信息
private List<Traveller> travellers;//旅客信息
private Member member;//會員信息
private Integer payType;//支付方式(0 支付寶 1 微信 2 其他)
private String payTypeStr;//支付方式描述
private String orderDesc;//訂單描述(其他信息)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public Date getOrderTime() {
return orderTime;
}
public void setOrderTime(Date orderTime) {
this.orderTime = orderTime;
}
public String getOrderTimeStr() {
return orderTimeStr;
}
public void setOrderTimeStr(String orderTimeStr) {
this.orderTimeStr = orderTimeStr;
}
public int getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(int orderStatus) {
this.orderStatus = orderStatus;
}
public String getOrderStatusStr() {
//訂單狀態(1 未支付 1 已支付)
if (orderStatus == 0) {
return "未支付";
} else if (orderStatus == 1) {
return "已支付";
}
return null;
}
public int getPeopleCount() {
return peopleCount;
}
public void setPeopleCount(int peopleCount) {
this.peopleCount = peopleCount;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public List<Traveller> getTravellers() {
return travellers;
}
public void setTravellers(List<Traveller> travellers) {
this.travellers = travellers;
}
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
public Integer getPayType() {
return payType;
}
public void setPayType(Integer payType) {
this.payType = payType;
}
public String getPayTypeStr() {
//支付方式(0 支付寶 1 微信 2 其他)
if (payType == 0) {
return "支付寶";
} else if (payType == 1) {
return "微信";
} else {
return "其他";
}
}
public void setPayTypeStr(String payTypeStr) {
this.payTypeStr = payTypeStr;
}
public String getOrderDesc() {
return orderDesc;
}
public void setOrderDesc(String orderDesc) {
this.orderDesc = orderDesc;
}
}
訂單查詢
- 在web模塊controller里編寫OrdersController
package org.hacker.ssm.controller;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:35
*/
@Controller
@RequestMapping("/orders")
public class OrdersController {
@Autowired
private IOrdersService ordersService;
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
ModelAndView mv=new ModelAndView();
List<Orders> ordersList = ordersService.findAll();
mv.addObject("ordersList",ordersList);
mv.setViewName("orders-list");
return mv;
}
}
- 在service模塊service包里編寫接口和其實現類
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Orders;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:44
*/
public interface IOrdersService {
//從訂單數據庫查詢數據
List<Orders> findAll();
}
package org.hacker.ssm.service.impl;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:45
*/
@Service
@Transactional
public class OrdersServiceImpl implements IOrdersService {
@Autowired
private IOrdersDao ordersDao;
@Override
public List<Orders> findAll() {
return ordersDao.findAll();
}
}
- 在dao模塊dao包里編寫OrdersDao
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.Orders;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:50
*/
public interface IOrdersDao {
@Select("select * from orders")
@Results({
@Result(column = "productId", property = "product", one = @One(select = "org.hacker.ssm.dao.IProductDao.findById"))
})
List<Orders> findAll();
}
- 到IProductDao里添加新的查詢代碼
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-20 11:51
*/
public interface IProductDao {
//查詢所有的產品信息
@Select("select * from product")
public List<Product> findAll() throws Exception;
@Insert("insert into product(productNum,productName,cityName,departureTime,productPrice,productDesc,productStatus) values(#{productNum},#{productName},#{cityName},#{departureTime},#{productPrice},#{productDesc},#{productStatus})")
void save(Product product);
//根據id查詢產品
@Select("select * from product where id = #{id}")
Product findById(String id);
}
- 運行服務器,打開瀏覽器查看效果
訂單分頁功能
-
PageHelper介紹
PageHelper是國內非常優秀的一款開源的mybatis分頁插件,它支持基本主流與常用的數據庫,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。
本項目在 github 的項目地址:https://github.com/pagehelper/Mybatis-PageHelper
本項目在 gitosc 的項目地址:http://git.oschina.net/free/Mybatis_PageHelper
-
PageHelper使用
在 總項目的pom.xml 中添加如下依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
-
配置
在applicationContext.xml中配置PageHelper插件
<!-- 把交給IOC管理 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 傳入PageHelper的插件 -->
<property name="plugins">
<array>
<!-- 傳入插件的對象 -->
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<prop key="helperDialect">oracle</prop>
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
-
基本使用
PageHelper.startPage 靜態方法調用(重點)
在需要進行分頁的 MyBatis 查詢方法前調用PageHelper.startPage 靜態方法,緊跟在這個方法后的第一個MyBatis 查詢方法會被進行分頁。
//獲取第1頁,10條內容,默認查詢總數
countPageHelper.startPage(1, 10);
//緊跟着的第一個select方法會被分頁
List<Country>list=countryMapper.selectIf(1);
功能實現
- 編寫Controller模塊
package org.hacker.ssm.controller;
import com.github.pagehelper.PageInfo;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:35
*/
@Controller
@RequestMapping("/orders")
public class OrdersController {
@Autowired
private IOrdersService ordersService;
//分頁
@RequestMapping("/findAll.do")
public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page,
@RequestParam(name = "pageSize", required = true, defaultValue = "4") Integer size) {
ModelAndView mv = new ModelAndView();
List<Orders> ordersList = ordersService.findAll(page, size);
PageInfo pageInfo = new PageInfo(ordersList);
mv.setViewName("orders-list");
mv.addObject("pageInfo", pageInfo);
return mv;
}
////未分頁
// @RequestMapping("/findAll.do")
// public ModelAndView findAll() throws Exception {
// ModelAndView mv = new ModelAndView();
// List<Orders> ordersList = ordersService.findAll();
// mv.addObject("ordersList", ordersList);
// mv.setViewName("orders-list");
// return mv;
// }
}
-
編寫Service模塊
-
接口
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Orders;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:44
*/
public interface IOrdersService {
//從訂單數據庫查詢數據
List<Orders> findAll();
//分頁
List<Orders> findAll(Integer page, Integer pageSize);
}
- 實現類
package org.hacker.ssm.service.impl;
import com.github.pagehelper.PageHelper;
import com.sun.glass.ui.Size;
import org.hacker.ssm.dao.IOrdersDao;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:45
*/
@Service
@Transactional
public class OrdersServiceImpl implements IOrdersService {
@Autowired
private IOrdersDao ordersDao;
@Override
public List<Orders> findAll() {
return ordersDao.findAll();
}
@Override
public List<Orders> findAll(Integer page, Integer pageSize) {
//pag是第幾頁, size是每頁顯示幾條數據
PageHelper.startPage(page, pageSize);
return ordersDao.findAll();
}
}
- 修改前端頁面
<c:forEach items="${pageInfo.list}" var="orders">
<tr>
<td><input name="ids" type="checkbox"></td>
<td>${orders.id }</td>
<td>${orders.orderNum }</td>
<td>${orders.product.productName }</td>
<td>${orders.product.productPrice }</td>
<td>${orders.orderTimeStr }</td>
<td class="text-center">${orders.orderStatusStr }</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs">訂單</button>
<button type="button" class="btn bg-olive btn-xs"
onclick="location.href='${pageContext.request.contextPath}/orders/findById.do?id=${orders.id}'">
詳情
</button>
<button type="button" class="btn bg-olive btn-xs">編輯</button>
</td>
</tr>
</c:forEach>
<div class="box-tools pull-right">
<ul class="pagination">
<li>
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=1&size=${pageInfo.pageSize}" aria-label="Previous">首頁</a>
</li>
<li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum-1}&size=${pageInfo.pageSize}">上一頁</a></li>
<c:forEach begin="1" end="${pageInfo.pages}" var="pageNum">
<li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageNum}&size=${pageInfo.pageSize}">${pageNum}</a></li>
</c:forEach>
<li><a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pageNum+1}&size=${pageInfo.pageSize}">下一頁</a></li>
<li>
<a href="${pageContext.request.contextPath}/orders/findAll.do?page=${pageInfo.pages}&size=${pageInfo.pageSize}" aria-label="Next">尾頁</a>
</li>
</ul>
</div>
- 項目結果
實現訂單詳情功能(不知道為啥查詢member數據庫總報錯????)
報錯內容
- 導入order-show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 頁面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>數據 - 企業權限管理</title>
<meta name="description" content="企業權限管理">
<meta name="keywords" content="企業權限管理">
<!-- Tell the browser to be responsive to screen width -->
<meta
content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
name="viewport">
<link rel=“stylesheet”
href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css">
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<!-- 頁面頭部 -->
<jsp:include page="header.jsp"></jsp:include>
<!-- 頁面頭部 /-->
<!-- 導航側欄 -->
<jsp:include page="aside.jsp"></jsp:include>
<!-- 導航側欄 /-->
<!-- 內容區域 -->
<div class="content-wrapper">
<!-- 內容頭部 -->
<section class="content-header">
<h1>
訂單管理 <small>全部訂單</small>
</h1>
<ol class="breadcrumb">
<li><a href="all-admin-index.html"><i
class="fa fa-dashboard"></i> 首頁</a></li>
<li><a href="all-order-manage-list.html">訂單管理</a></li>
<li class="active">訂單詳情</li>
</ol>
</section>
<!-- 內容頭部 /-->
<!-- 正文區域 -->
<section class="content"> <!--訂單信息-->
<div class="panel panel-default">
<div class="panel-heading">訂單信息</div>
<div class="row data-type">
<div class="col-md-2 title">訂單編號</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="訂單編號"
value="${orders.orderNum }" readonly="readonly">
</div>
<div class="col-md-2 title">下單時間</div>
<div class="col-md-4 data">
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right"
id="datepicker-a3" readonly="readonly"
value="${orders.orderTimeStr}">
</div>
</div>
<div class="col-md-2 title">路線名稱</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="路線名稱"
value="${orders.product.productName }" readonly="readonly">
</div>
<div class="col-md-2 title">出發城市</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="出發城市"
value="${orders.product.cityName }" readonly="readonly">
</div>
<div class="col-md-2 title">出發時間</div>
<div class="col-md-4 data">
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right"
id="datepicker-a6" value="${orders.product.departureTimeStr}"
readonly="readonly">
</div>
</div>
<div class="col-md-2 title">出游人數</div>
<div class="col-md-4 data">
<input type="text" class="form-control" placeholder="出游人數"
value="${orders.peopleCount}" readonly="readonly">
</div>
<div class="col-md-2 title rowHeight2x">其他信息</div>
<div class="col-md-10 data rowHeight2x">
<textarea class="form-control" rows="3" placeholder="其他信息">
${orders.orderDesc }
</textarea>
</div>
</div>
</div>
<!--訂單信息/--> <!--游客信息-->
<div class="panel panel-default">
<div class="panel-heading">游客信息</div>
<!--數據列表-->
<table id="dataList"
class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="">人群</th>
<th class="">姓名</th>
<th class="">性別</th>
<th class="">手機號碼</th>
<th class="">證件類型</th>
<th class="">證件號碼</th>
</tr>
</thead>
<tbody>
<c:forEach var="traveller" items="${orders.travellers}">
<tr>
<td>${traveller.travellerTypeStr}</td>
<td><input type="text" size="10" value="${traveller.name }"
readonly="readonly"></td>
<td><input type="text" size="10" value="${traveller.sex }"
readonly="readonly"></td>
<td><input type="text" size="20"
value="${traveller.phoneNum }" readonly="readonly"></td>
<td><input type="text" size="15"
value="${traveller.credentialsTypeStr}" readonly="readonly"></td>
<td><input type="text" size="28"
value="${traveller.credentialsNum }" readonly="readonly"></td>
</tr>
</c:forEach>
</tbody>
</table>
<!--數據列表/-->
</div>
<!--游客信息/--> <!--聯系人信息-->
<div class="panel panel-default">
<div class="panel-heading">聯系人信息</div>
<div class="row data-type">
<div class="col-md-2 title">會員</div>
<div class="col-md-4 data text">${orders.member.nickname }</div>
<div class="col-md-2 title">聯系人</div>
<div class="col-md-4 data text">${orders.member.name}</div>
<div class="col-md-2 title">手機號</div>
<div class="col-md-4 data text">${orders.member.phoneNum}</div>
<div class="col-md-2 title">郵箱</div>
<div class="col-md-4 data text">${orders.member.email}</div>
</div>
</div>
<!--聯系人信息/--> <!--費用信息--> <c:if test="${orders.orderStatus==1}">
<div class="panel panel-default">
<div class="panel-heading">費用信息</div>
<div class="row data-type">
<div class="col-md-2 title">支付方式</div>
<div class="col-md-4 data text">在線支付-${orders.payTypeStr}</div>
<div class="col-md-2 title">金額</div>
<div class="col-md-4 data text">¥${orders.product.productPrice}</div>
</div>
</div>
</c:if> <!--費用信息/--> <!--工具欄-->
<div class="box-tools text-center">
<button type="button" class="btn bg-default"
onclick="history.back(-1);">返回</button>
</div>
<!--工具欄/--> </section>
<!-- 正文區域 /-->
</div>
<!-- 內容區域 /-->
<!-- 底部導航 -->
<footer class="main-footer">
<div class="pull-right hidden-xs">
<b>Version</b> 1.0.8
</div>
<strong>Copyright © 2014-2017 <a
href="#">項目練習</a>.
</strong> All rights reserved. </footer>
<!-- 底部導航 /-->
</div>
<script
src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script>
<script>
$.widget.bridge('uibutton', $.ui.button);
</script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script>
<script>
$(document).ready(function() {
// 選擇框
$(".select2").select2();
// WYSIHTML5編輯器
$(".textarea").wysihtml5({
locale : 'zh-CN'
});
});
// 設置激活菜單
function setSidebarActive(tagUri) {
var liObj = $("#" + tagUri);
if (liObj.length > 0) {
liObj.parent().parent().addClass("active");
liObj.addClass("active");
}
}
$(document).ready(function() {
// 激活導航位置
setSidebarActive("order-manage");
// 列表按鈕
$("#dataList td input[type='checkbox']").iCheck({
checkboxClass : 'icheckbox_square-blue',
increaseArea : '20%'
});
// 全選操作
$("#selall").click(function() {
var clicks = $(this).is(':checked');
if (!clicks) {
$("#dataList td input[type='checkbox']").iCheck("uncheck");
} else {
$("#dataList td input[type='checkbox']").iCheck("check");
}
$(this).data("clicks", !clicks);
});
});
</script>
</body>
</html>
- 編寫controller模塊代碼
package org.hacker.ssm.controller;
import com.github.pagehelper.PageInfo;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:35
*/
@Controller
@RequestMapping("/orders")
public class OrdersController {
@Autowired
private IOrdersService ordersService;
//分頁
@RequestMapping("/findAll.do")
public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page,
@RequestParam(name = "pageSize", required = true, defaultValue = "4") Integer size) {
ModelAndView mv = new ModelAndView();
List<Orders> ordersList = ordersService.findAll(page, size);
PageInfo pageInfo = new PageInfo(ordersList);
mv.setViewName("orders-list");
mv.addObject("pageInfo", pageInfo);
return mv;
}
////未分頁
// @RequestMapping("/findAll.do")
// public ModelAndView findAll() throws Exception {
// ModelAndView mv = new ModelAndView();
// List<Orders> ordersList = ordersService.findAll();
// mv.addObject("ordersList", ordersList);
// mv.setViewName("orders-list");
// return mv;
// }
@RequestMapping("/findById.do")
public ModelAndView findById(@RequestParam(name = "id", required = true) String ordersId) {
ModelAndView mv = new ModelAndView();
Orders orders = ordersService.findById(ordersId);
mv.addObject(orders);
mv.setViewName("orders-show");
return mv;
}
}
- 編寫service模塊代碼
- 接口
- 實現類
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Orders;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:44
*/
public interface IOrdersService {
//從訂單數據庫查詢數據
List<Orders> findAll();
//分頁
List<Orders> findAll(Integer page, Integer pageSize);
Orders findById(String ordersId);
}
package org.hacker.ssm.service.impl;
import com.github.pagehelper.PageHelper;
import com.sun.glass.ui.Size;
import org.hacker.ssm.dao.IOrdersDao;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.service.IOrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:45
*/
@Service
@Transactional
public class OrdersServiceImpl implements IOrdersService {
@Autowired
private IOrdersDao ordersDao;
@Override
public List<Orders> findAll() {
return ordersDao.findAll();
}
@Override
public List<Orders> findAll(Integer page, Integer pageSize) {
//pag是第幾頁, size是每頁顯示幾條數據
PageHelper.startPage(page, pageSize);
return ordersDao.findAll();
}
@Override
public Orders findById(String ordersId) {
return ordersDao.findById(ordersId);
}
}
- 編寫dao模塊代碼
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.*;
import org.hacker.ssm.domain.Memeber;
import org.hacker.ssm.domain.Orders;
import org.hacker.ssm.domain.Product;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-22 11:50
*/
public interface IOrdersDao {
@Select("select * from orders")
@Results({
@Result(column = "productId", property = "product", one = @One(select = "org.hacker.ssm.dao.IProductDao.findById"))
})
List<Orders> findAll();
@Select("Select * from orders where id = #{ordersId}")
@Results({
@Result(property = "product", column = "productId", javaType = Product.class, one = @One(select = "org.hacker.ssm.dao.IProductDao.findById"))
,
@Result(property = "member", column = "memberId", javaType = Memeber.class, one = @One(select = "org.hacker.ssm.dao.IMemberDao.findById"))
,
@Result(property = "travellers", column = "id", javaType = java.util.List.class, many = @Many(select = "com.itheima.ssm.dao.ITravellerDao.findByOrdersId"))
})
Orders findById(String ordersId);
}
- 編寫IMemberDao
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.Member;
/**
* @author HackerStar
* @create 2020-04-23 22:13
*/
public interface IMemberDao {
@Select("Select * from member where id = #{id}")
public Member findById(String id);
}
- 編寫ITravellerDao
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.Traveller;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-23 22:15
*/
public interface ITravellerDao {
@Select("select * from traveller where id in (select travellerId from order_traveller where orderId = #{ordersId})")
public List<Traveller> findByOrdersId(String ordersId);
}
異常已經解決,問題是導入了其他包中的Member類
解決方法:導入自己domain包里的member類,然后將各個項目按依賴關系clean——>install
- 結果
第二天完畢
第三天
SSM權限操作
-
創建數據庫
-
創建用戶信息表
-- 用戶表
CREATE TABLE users(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
email VARCHAR2(50) UNIQUE NOT NULL,
username VARCHAR2(50),
PASSWORD VARCHAR2(50),
phoneNum VARCHAR2(20),
STATUS INT
)
- 編寫實體類
package org.hacker.ssm.domain;
/**
* @author HackerStar
* @create 2020-04-24 11:09
*/
public class UserInfo {
private String id;
private String username;
private String email;
private String password;
private String phoneNum;
private int status;
private String statusStr;
private List<Role> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getStatusStr() {
return statusStr;
}
public void setStatusStr(String statusStr) {
this.statusStr = statusStr;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
- 創建角色表
CREATE TABLE role(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
roleName VARCHAR2(50),
roleDescVARCHAR2(50)
)
- 編寫實體類
package org.hacker.ssm.domain;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:12
*/
public class Role {
private String id;
private String roleName;
private String roleDesc;
private List<Permission> permissions;
private List<UserInfo> users;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public List<Permission> getPermissions() {
return permissions;
}
public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
- 創建角色-用戶中間表
-- 用戶角色關聯表
CREATE TABLE users_role(
userId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(userId,roleId),
FOREIGN KEY (userId) REFERENCES users(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
- 創建資源表
CREATE TABLE permission(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
permissionName VARCHAR2(50),
url VARCHAR2(50)
)
- 編寫實體類
package org.hacker.ssm.domain;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:17
*/
public class Permission {
private String id;
private String permissionName;
private String url;
private List<Role> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPermissionName() {
return permissionName;
}
public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
- 創建權限-角色表
-- 角色權限關聯表
CREATE TABLE role_permission(
permissionId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(permissionId,roleId),
FOREIGN KEY (permissionId) REFERENCES permission(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
Spring Security概述
Spring Security 是 Spring 項目組中用來提供安全認證服務的框架。Spring Security 為基於J2EE企業應用軟件提供了全面安全服務。特別是使用領先的J2EE解決方案-Spring框架開發的企業軟件項目。
- 如何使用
- 導入依賴到總工程的pom文件中
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
- 配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 配置加載類路徑的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!-- 配置監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 前端控制器(加載classpath:springmvc.xml 服務器啟動創建servlet) -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化參數,創建完DispatcherServlet對象,加載springmvc.xml配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 服務器啟動的時候,讓DispatcherServlet對象創建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- spring security-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 解決中文亂碼過濾器 -->
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- 項目中web.xml完整代碼
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 配置加載類路徑的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml,classpath*:spring-security.xml</param-value>
</context-param>
<!-- 配置監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 前端控制器(加載classpath:springmvc.xml 服務器啟動創建servlet) -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化參數,創建完DispatcherServlet對象,加載springmvc.xml配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 服務器啟動的時候,讓DispatcherServlet對象創建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 解決中文亂碼過濾器 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- 編寫spring-security配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
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
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不攔截的資源 -->
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>
<!--
配置具體的規則
auto-config="true" 不用自己編寫登錄的頁面,框架提供默認登錄頁面
use-expressions="false" 是否使用SPEL表達式(沒學習過)
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置具體的攔截的規則 pattern="請求路徑的規則" access="訪問系統的人,必須有ROLE_USER的角色" -->
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
<!-- 定義跳轉的具體的頁面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login.do"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
/>
<!-- 關閉跨域請求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
</security:http>
<!-- 切換成數據庫中的用戶名和密碼 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密類 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
</beans>
-
導入登錄和登陸失敗頁面
-
編寫service接口及其實現類
-
編寫dao接口
package org.hacker.ssm.service;
import org.springframework.security.core.userdetails.UserDetailsService;
/**
* @author HackerStar
* @create 2020-04-24 11:34
*/
public interface IUserService extends UserDetailsService {
}
package org.hacker.ssm.service.impl;
import org.hacker.ssm.domain.Role;
import org.hacker.ssm.domain.UserInfo;
import org.hacker.ssm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:34
*/
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userDao.findByUsername(username);
List<Role> roles = userInfo.getRoles();
//處理自己的用戶對象封裝成UserDetails
User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(userInfo.getRoles()));
return user;
}
//作用就是返回一個List集合,集合中裝入的是角色描述
public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> list = new ArrayList<>();
for (Role role : roles) {
list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
}
return list;
}
}
實現用戶退出功能
在spring-security配置文件中配置
<security:logout invalidate-session="true" logut-url="/logout.do" logout-sucess-url="/login.jsp"/>
實現用戶查詢功能
-
導入頁面user-list
-
編寫controller模塊
package org.hacker.ssm.controller;
import org.hacker.ssm.domain.UserInfo;
import org.hacker.ssm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:55
*/
public class UserController {
@Autowired
private IUserService userService;
public ModelAndView findAll() {
ModelAndView mv = new ModelAndView();
List<UserInfo> userList = userService.findAll();
mv.addObject("userlist", userList);
mv.setViewName("user-list");
return mv;
}
}
- 添加代碼到service接口及其實現類
package org.hacker.ssm.service;
import org.hacker.ssm.domain.UserInfo;
import org.springframework.security.core.userdetails.UserDetailsService;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:34
*/
public interface IUserService extends UserDetailsService {
List<UserInfo> findAll();
}
package org.hacker.ssm.service.impl;
import org.hacker.ssm.dao.IUserDao;
import org.hacker.ssm.domain.Role;
import org.hacker.ssm.domain.UserInfo;
import org.hacker.ssm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:34
*/
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = null;
try {
userInfo = userDao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
List<Role> roles = userInfo.getRoles();
//處理自己的用戶對象封裝成UserDetails
User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(userInfo.getRoles()));
return user;
}
//作用就是返回一個List集合,集合中裝入的是角色描述
public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> list = new ArrayList<>();
for (Role role : roles) {
list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
}
return list;
}
@Override
public List<UserInfo> findAll() {
return userDao.findAll();
}
}
- 添加代碼到dao接口
package org.hacker.ssm.dao;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.hacker.ssm.domain.UserInfo;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author HackerStar
* @create 2020-04-24 11:41
*/
public interface IUserDao {
@Select("select * from users where username=#{username}")
@Results({
@Result(property = "roles",column = "id",javaType = java.util.List.class,many = @Many(select = "com.itheima.ssm.dao.IRoleDao.findRoleByUserId"))
})
public UserInfo findByUsername(String username) throws Exception;
@Select("select * from users")
List<UserInfo> findAll();
}
- 項目運行結果
第三天完畢
第四天
數據庫准備
insert into permission(permissionname, url) values ('user findById', '/users/findById.do');
insert into permission(permissionname, url) values ('user findAll', '/users/findAll.do');
insert into role_permission values ('1BBAA2A1C19E4D26A49F5F78543802F8', '2222');
insert into role_permission values ('1BBAA2A1C19E4D26A49F5F78543802F8', '1111');
insert into role_permission values ('558DF6F59855436FBC3CAA68D656B738', '1111');
實現角色查詢功能
-
導入role-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - AdminLTE2定制版</title> <meta name="description" content="AdminLTE2定制版"> <meta name="keywords" content="AdminLTE2定制版"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 角色管理 <small>全部角色</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li> <li class="active">全部角色</li> </ol> </section> <!-- 內容頭部 /--> <!-- 正文區域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 數據表格 --> <div class="table-box"> <!--工具欄--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/role-add.jsp'"> <i class="fa fa-file-o"></i> 新建 </button> <button type="button" class="btn btn-default" title="刷新"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具欄/--> <!--數據列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"> </th> <th class="sorting_asc">ID</th> <th class="sorting_desc">角色名稱</th> <th class="sorting_asc sorting_asc_disabled">描述</th> <th class="text-center">操作</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td><input name="ids" type="checkbox"></td> <td>${role.id }</td> <td>${role.roleName }</td> <td>${role.roleDesc }</td> <td class="text-center"> <a href="${pageContext.request.contextPath}/role/findById.do?id=${role.id}" class="btn bg-olive btn-xs">詳情</a> <a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a> </td> </tr> </c:forEach> </tbody> <!-- <tfoot> <tr> <th>Rendering engine</th> <th>Browser</th> <th>Platform(s)</th> <th>Engine version</th> <th>CSS grade</th> </tr> </tfoot>--> </table> <!--數據列表/--> </div> <!-- 數據表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 總共2 頁,共14 條數據。 每頁 <select class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> 條 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首頁</a></li> <li><a href="#">上一頁</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一頁</a></li> <li><a href="#" aria-label="Next">尾頁</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文區域 /--> </div> <!-- @@close --> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="../plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="../plugins/bootstrap/js/bootstrap.min.js"></script> <script src="../plugins/raphael/raphael-min.js"></script> <script src="../plugins/morris/morris.min.js"></script> <script src="../plugins/sparkline/jquery.sparkline.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="../plugins/knob/jquery.knob.js"></script> <script src="../plugins/daterangepicker/moment.min.js"></script> <script src="../plugins/daterangepicker/daterangepicker.js"></script> <script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="../plugins/datepicker/bootstrap-datepicker.js"></script> <script src="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="../plugins/fastclick/fastclick.js"></script> <script src="../plugins/iCheck/icheck.min.js"></script> <script src="../plugins/adminLTE/js/app.min.js"></script> <script src="../plugins/treeTable/jquery.treetable.js"></script> <script src="../plugins/select2/select2.full.min.js"></script> <script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="../plugins/bootstrap-markdown/js/markdown.js"></script> <script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="../plugins/ckeditor/ckeditor.js"></script> <script src="../plugins/input-mask/jquery.inputmask.js"></script> <script src="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="../plugins/datatables/jquery.dataTables.min.js"></script> <script src="../plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="../plugins/chartjs/Chart.min.js"></script> <script src="../plugins/flot/jquery.flot.min.js"></script> <script src="../plugins/flot/jquery.flot.resize.min.js"></script> <script src="../plugins/flot/jquery.flot.pie.min.js"></script> <script src="../plugins/flot/jquery.flot.categories.min.js"></script> <script src="../plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document) .ready( function() { // 激活導航位置 setSidebarActive("admin-datalist"); // 列表按鈕 $("#dataList td input[type='checkbox']") .iCheck( { checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全選操作 $("#selall") .click( function() { var clicks = $(this).is( ':checked'); if (!clicks) { $( "#dataList td input[type='checkbox']") .iCheck( "uncheck"); } else { $( "#dataList td input[type='checkbox']") .iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
編寫controller模塊代碼
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:28 */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList", roleList); mv.setViewName("role-list"); return mv; } }
-
-
編寫service模塊代碼
-
接口
package org.hacker.ssm.service; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:32 */ public interface IRoleService { public List<Role> findAll(); }
-
實現類
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IRoleDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:33 */ @Service @Transactional public class RoleServiceImpl implements IRoleService { @Autowired private IRoleDao roleDao; @Override public List<Role> findAll() { return roleDao.findAll(); } }
-
-
編寫dao模塊代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:43 */ public interface IRoleDao { //根據用戶id查詢出所有對應的角色 @Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception; @Select("select * from role") List<Role> findAll(); }
-
-
結果
-
導入role-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - AdminLTE2定制版</title> <meta name="description" content="AdminLTE2定制版"> <meta name="keywords" content="AdminLTE2定制版"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 角色管理 <small>角色表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li> <li class="active">角色表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/role/save.do" method="post"> <!-- 正文區域 --> <section class="content"> <!--產品信息--> <div class="panel panel-default"> <div class="panel-heading">角色信息</div> <div class="row data-type"> <div class="col-md-2 title">角色名稱</div> <div class="col-md-4 data"> <input type="text" class="form-control" name="roleName" placeholder="角色名稱" value=""> </div> <div class="col-md-2 title">角色描述</div> <div class="col-md-4 data"> <input type="text" class="form-control" name="roleDesc" placeholder="角色描述" value=""> </div> </div> </div> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
編寫controller模塊代碼
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:28 */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList", roleList); mv.setViewName("role-list"); return mv; } @RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; } }
-
-
編寫service模塊代碼
-
接口
package org.hacker.ssm.service;
import org.hacker.ssm.domain.Role;
import java.util.List;
/**
-
@author HackerStar
-
@create 2020-04-27 00:32
*/
public interface IRoleService {
public ListfindAll(); void save(Role role);
}
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IRoleDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:33 */ @Service @Transactional public class RoleServiceImpl implements IRoleService { @Autowired private IRoleDao roleDao; @Override public List<Role> findAll() { return roleDao.findAll(); } @Override public void save(Role role) { roleDao.sava(role); } }
-
-
-
編寫dao模塊代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:43 */ public interface IRoleDao { //根據用戶id查詢出所有對應的角色 @Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception; @Select("select * from role") List<Role> findAll(); @Insert("insert into role(roleName, roleDesc) values (#{roleName},#{roleDesc})") void sava(Role role); }
-
-
結果
實現資源權限管理
-
復制role-list.jsp到pages目錄下,修改部分代碼,成為permisssion-list.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - AdminLTE2定制版</title> <meta name="description" content="AdminLTE2定制版"> <meta name="keywords" content="AdminLTE2定制版"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 角色管理 <small>全部角色</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li> <li class="active">全部角色</li> </ol> </section> <!-- 內容頭部 /--> <!-- 正文區域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 數據表格 --> <div class="table-box"> <!--工具欄--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/role-add.jsp'"> <i class="fa fa-file-o"></i> 新建 </button> <button type="button" class="btn btn-default" title="刷新"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具欄/--> <!--數據列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"> </th> <th class="sorting_asc">ID</th> <th class="sorting_desc">權限名稱</th> <th class="sorting_asc sorting_asc_disabled">url</th> <%-- <th class="text-center">操作</th>--%> </tr> </thead> <tbody> <c:forEach items="${permissionList}" var="permission"> <tr> <td><input name="ids" type="checkbox"></td> <td>${permission.id }</td> <td>${permission.permissionName }</td> <td>${permission.url }</td> <%-- <td class="text-center">--%> <%-- <a href="${pageContext.request.contextPath}/permission/findById.do?id=${role.id}" class="btn bg-olive btn-xs">詳情</a>--%> <%-- <a href="${pageContext.request.contextPath}/permission/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a>--%> <%-- </td>--%> </tr> </c:forEach> </tbody> <!-- <tfoot> <tr> <th>Rendering engine</th> <th>Browser</th> <th>Platform(s)</th> <th>Engine version</th> <th>CSS grade</th> </tr> </tfoot>--> </table> <!--數據列表/--> </div> <!-- 數據表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 總共2 頁,共14 條數據。 每頁 <select class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> 條 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首頁</a></li> <li><a href="#">上一頁</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一頁</a></li> <li><a href="#" aria-label="Next">尾頁</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文區域 /--> </div> <!-- @@close --> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="../plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="../plugins/bootstrap/js/bootstrap.min.js"></script> <script src="../plugins/raphael/raphael-min.js"></script> <script src="../plugins/morris/morris.min.js"></script> <script src="../plugins/sparkline/jquery.sparkline.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="../plugins/knob/jquery.knob.js"></script> <script src="../plugins/daterangepicker/moment.min.js"></script> <script src="../plugins/daterangepicker/daterangepicker.js"></script> <script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="../plugins/datepicker/bootstrap-datepicker.js"></script> <script src="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="../plugins/fastclick/fastclick.js"></script> <script src="../plugins/iCheck/icheck.min.js"></script> <script src="../plugins/adminLTE/js/app.min.js"></script> <script src="../plugins/treeTable/jquery.treetable.js"></script> <script src="../plugins/select2/select2.full.min.js"></script> <script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="../plugins/bootstrap-markdown/js/markdown.js"></script> <script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="../plugins/ckeditor/ckeditor.js"></script> <script src="../plugins/input-mask/jquery.inputmask.js"></script> <script src="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="../plugins/datatables/jquery.dataTables.min.js"></script> <script src="../plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="../plugins/chartjs/Chart.min.js"></script> <script src="../plugins/flot/jquery.flot.min.js"></script> <script src="../plugins/flot/jquery.flot.resize.min.js"></script> <script src="../plugins/flot/jquery.flot.pie.min.js"></script> <script src="../plugins/flot/jquery.flot.categories.min.js"></script> <script src="../plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document) .ready( function() { // 激活導航位置 setSidebarActive("admin-datalist"); // 列表按鈕 $("#dataList td input[type='checkbox']") .iCheck( { checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全選操作 $("#selall") .click( function() { var clicks = $(this).is( ':checked'); if (!clicks) { $( "#dataList td input[type='checkbox']") .iCheck( "uncheck"); } else { $( "#dataList td input[type='checkbox']") .iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
-
編寫controller模塊代碼
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.service.IPermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:12 */ @Controller @RequestMapping("/permission") public class PermissionController { @Autowired private IPermissionService permissionService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Permission> permissionList = permissionService.findAll(); mv.addObject("permissionList", permissionList); mv.setViewName("permission-list"); return mv; } }
-
-
編寫service模塊代碼
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Permission; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:15 */ public interface IPermissionService { public List<Permission> findAll(); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IPermissionDao; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.service.IPermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:16 */ @Service @Transactional public class PermissionServiceImpl implements IPermissionService { @Autowired private IPermissionDao permissionDao; @Override public List<Permission> findAll() { return permissionDao.findAll(); } }
-
-
-
編寫dao模塊代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.Permission; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:18 */ public interface IPermissionDao { @Select("select * from permission") public List<Permission> findAll(); }
-
-
結果
實現資源權限添加功能
-
復制role-add.jsp到pages目錄下,修改部分代碼,成為permisssion-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - AdminLTE2定制版</title> <meta name="description" content="AdminLTE2定制版"> <meta name="keywords" content="AdminLTE2定制版"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 權限管理 <small>權限表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/permission/findAll.do">權限管理</a></li> <li class="active">權限表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/permission/save.do" method="post"> <!-- 正文區域 --> <section class="content"> <!--產品信息--> <div class="panel panel-default"> <div class="panel-heading">權限信息</div> <div class="row data-type"> <div class="col-md-2 title">權限名稱</div> <div class="col-md-4 data"> <input type="text" class="form-control" name="permissionName" placeholder="權限名稱" value=""> </div> <div class="col-md-2 title">URL</div> <div class="col-md-4 data"> <input type="text" class="form-control" name="url" placeholder="URL" value=""> </div> </div> </div> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
編寫controller模塊代碼
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:28 */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList", roleList); mv.setViewName("role-list"); return mv; } @RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; } }
-
-
編寫service模塊代碼
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Permission; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:15 */ public interface IPermissionService { public List<Permission> findAll(); void save(Permission permission); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IPermissionDao; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.service.IPermissionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:16 */ @Service @Transactional public class PermissionServiceImpl implements IPermissionService { @Autowired private IPermissionDao permissionDao; @Override public List<Permission> findAll() { return permissionDao.findAll(); } @Override public void save(Permission permission) { permissionDao.save(permission); } }
-
-
-
編寫dao模塊代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.Permission; import java.util.List; /** * @author HackerStar * @create 2020-04-27 13:18 */ public interface IPermissionDao { @Select("select * from permission") public List<Permission> findAll(); @Insert("insert into permission(permissionName, url) values (#{permissionName}, #{url})") void save(Permission permission); }
-
-
結果
第四天完畢
第五天
- 權限關聯與控制
- AOP日志
實現用戶—角色關聯
實現查詢用戶-角色
將用戶添加的功能提前實現
-
在user-list.jsp添加鏈接
-
<a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a>
-
-
導入user-role-add.jsp頁面
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 用戶管理 <small>添加角色表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用戶管理</a></li> <li class="active">添加角色表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文區域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名稱</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全選操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
編寫Controller模塊代碼
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 用戶管理 <small>添加角色表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用戶管理</a></li> <li class="active">添加角色表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文區域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名稱</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全選操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
編寫sevice模塊代碼
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.security.core.userdetails.UserDetailsService; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ public interface IUserService extends UserDetailsService { List<UserInfo> findAll(); UserInfo findById(String userId); List<Role> findOtherRoles(String userId); void save(UserInfo userInfo); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IUserDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ @Service("userService") @Transactional public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = null; try { userInfo = userDao.findByUsername(username); } catch (Exception e) { e.printStackTrace(); } List<Role> roles = userInfo.getRoles(); //處理自己的用戶對象封裝成UserDetails User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(roles)); return user; } //作用就是返回一個List集合,集合中裝入的是權限描述 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) { List<SimpleGrantedAuthority> list = new ArrayList<>(); for (Role role : roles) { list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName())); } return list; } @Override public List<UserInfo> findAll() { return userDao.findAll(); } //根據ID查詢用戶的信息 @Override public UserInfo findById(String userId) { return userDao.findById(userId); } //返回用戶未添加的角色 @Override public List<Role> findOtherRoles(String userId) { return userDao.findOtherRoles(userId); } @Override public void save(UserInfo userInfo) { userDao.save(userInfo); } }
-
-
-
編寫dao模塊代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.stereotype.Service; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:41 */ public interface IUserDao { @Select("select * from users where username=#{username}") @Results({ @Result(property = "roles", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IRoleDao.findRoleByUserId")) }) public UserInfo findByUsername(String username) throws Exception; @Select("select * from users") List<UserInfo> findAll(); @Select("select * from users where id=#{userId}") UserInfo findById(String userId); @Select("select * from role where id is not in (select roleId from users_role where userId=#{userId})") List<Role> findOtherRoles(String userId); @Insert("insert into users(email,username,password,phoneNum,status) values(#{email},#{username},#{password},#{phoneNum},#{status})") void save(UserInfo userInfo); }
-
@RequestMapingParam 前端參數和方法參數對應
@Param 方法參數和注解參數對應
- 結果
給用戶添加角色
-
導入user-role-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 用戶管理 <small>添加角色表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用戶管理</a></li> <li class="active">添加角色表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/user/addRoleToUser.do" method="post"> <!-- 正文區域 --> <section class="content"> <input type="hidden" name="userId" value="${user.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">角色名稱</th> <th class="sorting">角色描述</th> </tr> </thead> <tbody> <c:forEach items="${roleList}" var="role"> <tr> <td> <input name="ids" type="checkbox" value="${role.id}"> </td> <td>${role.id}</td> <td>${role.roleName }</td> <td>${role.roleDesc}</td> </tr> </c:forEach> </tbody> </table> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全選操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
UserContoler添加代碼
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:55 */ @Service @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; //查詢所有用戶 @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<UserInfo> userList = userService.findAll(); mv.addObject("userList", userList); mv.setViewName("user-list"); return mv; } //查詢用戶以及用戶可以添加的角色 @RequestMapping("/findUserByIdAndAllRole.do") public ModelAndView findUserByIdAndAllRole(@RequestParam(name = "id", required = true) String userId) { ModelAndView mv = new ModelAndView(); //根據用戶id查詢用戶 UserInfo userInfo = userService.findById(userId); //根據用戶id查詢可以添加的角色 List<Role> otherRoles = userService.findOtherRoles(userId); mv.addObject("user", userInfo); mv.addObject("roleList", otherRoles); mv.setViewName("user-role-add"); return mv; } //用戶添加 @RequestMapping("/save.do") public String save(UserInfo userInfo) throws Exception { userService.save(userInfo); return "redirect:findAll.do"; } //給用戶添加角色 @RequestMapping("addRoleToUser.do") public String addRoleToUser(@RequestParam(name = "userId", required = true) String userId, @RequestParam(name = "ids", required = true) String[] roleIds) { userService.addRoleToUser(userId, roleIds); return "redirect:findAll.do"; } }
-
-
UserService模塊添加代碼
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.security.core.userdetails.UserDetailsService; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ public interface IUserService extends UserDetailsService { List<UserInfo> findAll(); UserInfo findById(String userId); List<Role> findOtherRoles(String userId); void save(UserInfo userInfo); void addRoleToUser(String userId, String[] roleIds); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IUserDao; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.hacker.ssm.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:34 */ @Service("userService") @Transactional public class UserServiceImpl implements IUserService { @Autowired private IUserDao userDao; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = null; try { userInfo = userDao.findByUsername(username); } catch (Exception e) { e.printStackTrace(); } List<Role> roles = userInfo.getRoles(); //處理自己的用戶對象封裝成UserDetails User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(roles)); return user; } //作用就是返回一個List集合,集合中裝入的是權限描述 public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) { List<SimpleGrantedAuthority> list = new ArrayList<>(); for (Role role : roles) { list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName())); } return list; } @Override public List<UserInfo> findAll() { return userDao.findAll(); } //根據ID查詢用戶的信息 @Override public UserInfo findById(String userId) { return userDao.findById(userId); } //返回用戶未添加的角色 @Override public List<Role> findOtherRoles(String userId) { return userDao.findOtherRoles(userId); } @Override public void save(UserInfo userInfo) { userDao.save(userInfo); } @Override public void addRoleToUser(String userId, String[] roleIds) { for (String roleId : roleIds) { userDao.addRoleToUser(userId, roleId); } } }
-
-
-
UserDao模塊添加代碼
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Role; import org.hacker.ssm.domain.UserInfo; import org.springframework.stereotype.Service; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:41 */ public interface IUserDao { @Select("select * from users where username=#{username}") @Results({ @Result(property = "roles", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IRoleDao.findRoleByUserId")) }) public UserInfo findByUsername(String username) throws Exception; @Select("select * from users") List<UserInfo> findAll(); @Select("select * from users where id=#{userId}") UserInfo findById(String userId); @Select("select * from role where id not in (select roleId from users_role where userId=#{userId})") List<Role> findOtherRoles(String userId); @Insert("insert into users(email,username,password,phoneNum,status) values(#{email},#{username},#{password},#{phoneNum},#{status})") void save(UserInfo userInfo); @Insert("insert into users_role(userId, roleId) values (#{userId},#{roleId})") void addRoleToUser(@Param("userId") String userId, @Param("roleId") String roleId); }
-
注:此處需要到IRoleDao接口里添加findRoleById代碼
@Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception;
- 結果
角色權限關聯
和用戶-角色關聯差不多
展示權限
-
修改user-list頁面成為role-list頁面
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 用戶管理 <small>全部用戶</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/user/findAll.do">用戶管理</a></li> <li class="active">全部用戶</li> </ol> </section> <!-- 內容頭部 /--> <!-- 正文區域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 數據表格 --> <div class="table-box"> <!--工具欄--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/user-add.jsp'"> <i class="fa fa-file-o"></i> 新建 </button> <button type="button" class="btn btn-default" title="刷新"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具欄/--> <!--數據列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"> </th> <th class="sorting_asc">ID</th> <th class="sorting_desc">用戶名</th> <th class="sorting_asc sorting_asc_disabled">郵箱</th> <th class="sorting_desc sorting_desc_disabled">聯系電話</th> <th class="sorting">狀態</th> <th class="text-center">操作</th> </tr> </thead> <tbody> <c:forEach items="${userList}" var="user"> <tr> <td><input name="ids" type="checkbox"></td> <td>${user.id }</td> <td>${user.username }</td> <td>${user.email }</td> <td>${user.phoneNum }</td> <td>${user.statusStr }</td> <td class="text-center"> <a href="${pageContext.request.contextPath}/user/findById.do?id=${user.id}" class="btn bg-olive btn-xs">詳情</a> <a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}" class="btn bg-olive btn-xs">添加角色</a> </td> </tr> </c:forEach> </tbody> <!-- <tfoot> <tr> <th>Rendering engine</th> <th>Browser</th> <th>Platform(s)</th> <th>Engine version</th> <th>CSS grade</th> </tr> </tfoot>--> </table> <!--數據列表/--> </div> <!-- 數據表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 總共2 頁,共14 條數據。 每頁 <select class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> 條 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首頁</a></li> <li><a href="#">上一頁</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一頁</a></li> <li><a href="#" aria-label="Next">尾頁</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文區域 /--> </div> <!-- @@close --> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="http://#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="../plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="../plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="../plugins/bootstrap/js/bootstrap.min.js"></script> <script src="../plugins/raphael/raphael-min.js"></script> <script src="../plugins/morris/morris.min.js"></script> <script src="../plugins/sparkline/jquery.sparkline.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="../plugins/knob/jquery.knob.js"></script> <script src="../plugins/daterangepicker/moment.min.js"></script> <script src="../plugins/daterangepicker/daterangepicker.js"></script> <script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="../plugins/datepicker/bootstrap-datepicker.js"></script> <script src="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="../plugins/fastclick/fastclick.js"></script> <script src="../plugins/iCheck/icheck.min.js"></script> <script src="../plugins/adminLTE/js/app.min.js"></script> <script src="../plugins/treeTable/jquery.treetable.js"></script> <script src="../plugins/select2/select2.full.min.js"></script> <script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="../plugins/bootstrap-markdown/js/markdown.js"></script> <script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="../plugins/ckeditor/ckeditor.js"></script> <script src="../plugins/input-mask/jquery.inputmask.js"></script> <script src="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="../plugins/datatables/jquery.dataTables.min.js"></script> <script src="../plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="../plugins/chartjs/Chart.min.js"></script> <script src="../plugins/flot/jquery.flot.min.js"></script> <script src="../plugins/flot/jquery.flot.resize.min.js"></script> <script src="../plugins/flot/jquery.flot.pie.min.js"></script> <script src="../plugins/flot/jquery.flot.categories.min.js"></script> <script src="../plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document) .ready( function() { // 激活導航位置 setSidebarActive("admin-datalist"); // 列表按鈕 $("#dataList td input[type='checkbox']") .iCheck( { checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全選操作 $("#selall") .click( function() { var clicks = $(this).is( ':checked'); if (!clicks) { $( "#dataList td input[type='checkbox']") .iCheck( "uncheck"); } else { $( "#dataList td input[type='checkbox']") .iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
-
添加代碼到RoleController模塊
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:28 */ @Controller @RequestMapping("/role") public class RoleController { @Autowired private IRoleService roleService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<Role> roleList = roleService.findAll(); mv.addObject("roleList", roleList); mv.setViewName("role-list"); return mv; } @RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; } @RequestMapping("/findRoleByIdAndAllPermission.do") public ModelAndView findRoleByIdAndAllPermission(@RequestParam(value = "id", required = true) String roleId) { ModelAndView mv = new ModelAndView(); //根據roleId查詢role Role role = roleService.findById(roleId); //根據roleId查詢可以添加的權限 List<Permission> permissionList = roleService.findOtherPermission(roleId); mv.addObject("role", role); mv.addObject("permissionList", permissionList); mv.setViewName("role-permission-add"); return mv; } }
-
-
添加代碼到RoleService模塊
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:32 */ public interface IRoleService { public List<Role> findAll(); void save(Role role); Role findById(String roleId); List<Permission> findOtherPermission(String roleId); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.IRoleDao; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import org.hacker.ssm.service.IRoleService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-27 00:33 */ @Service @Transactional public class RoleServiceImpl implements IRoleService { @Autowired private IRoleDao roleDao; @Override public List<Role> findAll() { return roleDao.findAll(); } @Override public void save(Role role) { roleDao.sava(role); } @Override public Role findById(String roleId) { return roleDao.findById(roleId); } @Override public List<Permission> findOtherPermission(String roleId) { return roleDao.findOtherPermission(roleId); } }
-
-
-
添加代碼到RoleDao模塊
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.*; import org.hacker.ssm.domain.Permission; import org.hacker.ssm.domain.Role; import java.util.List; /** * @author HackerStar * @create 2020-04-24 11:43 */ public interface IRoleDao { //根據用戶id查詢出所有對應的權限 @Select("select * from role where id in (select roleId from users_role where userId=#{userId})") public List<Role> findRoleByUserId(String userId) throws Exception; @Select("select * from role") List<Role> findAll(); @Insert("insert into role(roleName, roleDesc) values (#{roleName},#{roleDesc})") void sava(Role role); @Select("select * from role where roleId = #{roleId}") @Results({ @Result(property = "permissions", column = "id", javaType = java.util.List.class, many = @Many(select = "org.hacker.ssm.dao.IPermissionDao.findPermissionByRoleId")) }) Role findById(String roleId); @Select("select * from permission where id not in (select permissionId from role_permission where roleId=#{roleId})") List<Permission> findOtherPermission(String roleId); }
-
-
結果
實現權限添加功能
-
修改user-role-add.jsp頁面成為role-permission-add.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-purple sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 角色管理 <small>添加權限表單</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li> <li class="active">添加權限表單</li> </ol> </section> <!-- 內容頭部 /--> <form action="${pageContext.request.contextPath}/role/addPermissionToRole.do" method="post"> <!-- 正文區域 --> <section class="content"> <input type="hidden" name="roleId" value="${role.id}"> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"> <input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">權限名稱</th> <th class="sorting">權限描述</th> </tr> </thead> <tbody> <c:forEach items="${permissionList}" var="permission"> <tr> <td> <input name="ids" type="checkbox" value="${permission.id}"> </td> <td>${permission.id}</td> <td>${permission.permissionName }</td> <td>${permission.url}</td> </tr> </c:forEach> </tbody> </table> <!--訂單信息/--> <!--工具欄--> <div class="box-tools text-center"> <button type="submit" class="btn bg-maroon">保存</button> <button type="button" class="btn bg-default" onclick="history.back(-1);">返回</button> </div> <!--工具欄/--> </section> <!-- 正文區域 /--> </form> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">項目練習</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); // 全選操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } </script> </body> </html>
-
-
給RoleController模塊添加代碼
-
@RequestMapping("/save.do") public String save(Role role) { roleService.save(role); return "redirect:findAll.do"; }
-
-
給RoleService模塊添加代碼
-
接口
-
void save(Role role);
-
-
實現類
-
@Override public void save(Role role) { roleDao.sava(role); }
-
-
-
給RoleDao模塊添加代碼
-
@Insert("insert into role(roleName, roleDesc) values (#{roleName},#{roleDesc})") void sava(Role role);
-
-
結果
方法權限控制
-
在服務器端我們可以通過Spring security提供的注解來對方法來進行權限控制。
-
Spring Security在方法的權限控制上支持三種類型的注解
-
JSR-250注解
JSR-250需要導入依賴進行使用
-
@Secured注解
@Secured注解是Spring security框架自帶的功能
-
支持表達式的注解
表達式注解常常配合頁面端標簽控制權限進行使用,這里還要花費一些時間學習表達式的方法
Spring Security允許我們在定義URL訪問或方法訪問所應有的權限時使用Spring EL表達式,在定義所需的訪問權限時如果對應的表達式返回結果為true則表示擁有對應 的權限,反之則無。Spring Security可用表達式對象的基類是SecurityExpressionRoot,其為我們提供了如下在使用Spring EL表達式對URL或方法進行權限控制時通用的內置表達式。
表達式 描述
hasRole([role]) 當前用戶是否擁有指定角色。
hasAnyRole([role1,role2]) 多個角色是一個以逗號進行分隔的字符串。如果當前用戶擁有指定角色中的任意一個則返回true。
hasAuthority([auth]) 等同於hasRole
hasAnyAuthority([auth1,auth2]) 等同於hasAnyRole
Principle 代表當前用戶的principle對象
authentication 直接從SecurityContext獲取的當前Authentication對象
permitAll 總是返回true,表示允許所有的
denyAll 總是返回false,表示拒絕所有的
isAnonymous() 當前用戶是否是一個匿名用戶
isRememberMe() 表示當前用戶是否是通過Remember-Me自動登錄的
isAuthenticated() 表示當前用戶是否已經登錄認證成功了。
isFullyAuthenticated() 如果當前用戶既不是一個匿名用戶,同時又不是通過Remember-Me自動登錄的,則返回true。 -
這三種注解默認都是沒有啟用的,需要單獨通過global-method-security元素的對應屬性進行啟用。
使用@Secured注解
-
在spring-security.xml配置文件中配置一個標簽
-
<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>
-
-
在指定方法上添加注解@Secured
-
//分頁 @RequestMapping("/findAll.do") @Secured("ROLE_ADMIN") public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") Integer page, @RequestParam(name = "pageSize", required = true, defaultValue = "4") Integer size) { ModelAndView mv = new ModelAndView(); List<Orders> ordersList = ordersService.findAll(page, size); PageInfo pageInfo = new PageInfo(ordersList); mv.setViewName("orders-list"); mv.addObject("pageInfo", pageInfo); return mv; }
-
-
結果(創建simth用戶,只給他分配了USER權限,沒有給他分配ADMIN權限)
配置403錯誤頁面
- 在web.xml中配置錯誤頁面標簽
<error-page>
<error-code>403</error-code>
<location>/403.jsp</location>
</error-page>
- 新建403.jsp頁面
<%--
Created by IntelliJ IDEA.
User: XinxingWang
Date: 2020/4/29
Time: 11:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>權限不足</title>
</head>
<body>
權限不足!
</body>
</html>
- 結果
頁面端標簽控制權限
頁面端標簽控制權限常常配合表達式控制權限進行使用,這里還要花費一些時間學習表達式的方法
使用頁面端標簽控制權限注解
-
在總工程的pom.xml配置文件中添加依賴
-
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring.security.version}</version> </dependency>
-
-
在aside.jsp頁面和main.jsp頁面導入標簽
-
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
-
-
在用戶名那里導入讀取當前用戶的標簽
- 結果
AOP日志
記錄用戶的訪問的操作信息
數據庫准備
-
-
在Oracle數據庫中添加創建sysLog數據庫
-
CREATE TABLE sysLog ( id VARCHAR2(32) default SYS_GUID() PRIMARY KEY, visitTime timestamp, username VARCHAR2(50), ip VARCHAR2(30), url VARCHAR2(50), executionTime int, method VARCHAR2(200) )
-
代碼實現
-
創建實體類
-
package org.hacker.ssm.domain; import java.util.Date; /** * @author HackerStar * @create 2020-04-29 16:19 */ public class SysLog { private String id; private Date visitTime; private String visitTimeStr; private String username; private String ip; private String url; private Long executionTime; private String method; public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getVisitTime() { return visitTime; } public void setVisitTime(Date visitTime) { this.visitTime = visitTime; } public String getVisitTimeStr() { return visitTimeStr; } public void setVisitTimeStr(String visitTimeStr) { this.visitTimeStr = visitTimeStr; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Long getExecutionTime() { return executionTime; } public void setExecutionTime(Long executionTime) { this.executionTime = executionTime; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }
-
-
導入syslog-list.jsp
-
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <!-- 頁面meta --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>數據 - 項目練習</title> <meta name="description" content="項目練習"> <meta name="keywords" content="項目練習"> <!-- Tell the browser to be responsive to screen width --> <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/morris/morris.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/select2/select2.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css"> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <!-- 頁面頭部 --> <jsp:include page="header.jsp"></jsp:include> <!-- 頁面頭部 /--> <!-- 導航側欄 --> <jsp:include page="aside.jsp"></jsp:include> <!-- 導航側欄 /--> <!-- 內容區域 --> <div class="content-wrapper"> <!-- 內容頭部 --> <section class="content-header"> <h1> 日志管理 <small>全部日志</small> </h1> <ol class="breadcrumb"> <li><a href="${pageContext.request.contextPath}/index.jsp"><i class="fa fa-dashboard"></i> 首頁</a></li> <li><a href="${pageContext.request.contextPath}/sysLog/findAll.do">日志管理</a></li> <li class="active">全部日志</li> </ol> </section> <!-- 內容頭部 /--> <!-- 正文區域 --> <section class="content"> <!-- .box-body --> <div class="box box-primary"> <div class="box-header with-border"> <h3 class="box-title">列表</h3> </div> <div class="box-body"> <!-- 數據表格 --> <div class="table-box"> <!--工具欄--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具欄/--> <!--數據列表--> <table id="dataList" class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"></th> <th class="sorting_asc">ID</th> <th class="sorting">訪問時間</th> <th class="sorting">訪問用戶</th> <th class="sorting">訪問IP</th> <th class="sorting">資源URL</th> <th class="sorting">執行時間</th> <th class="sorting">訪問方法</th> </tr> </thead> <tbody> <c:forEach items="${sysLogs}" var="syslog"> <tr> <td><input name="ids" type="checkbox"></td> <td>${syslog.id}</td> <td>${syslog.visitTimeStr }</td> <td>${syslog.username }</td> <td>${syslog.ip }</td> <td>${syslog.url}</td> <td>${syslog.executionTime}毫秒</td> <td>${syslog.method}</td> </tr> </c:forEach> </tbody> </table> <!--數據列表/--> <!--工具欄--> <div class="pull-left"> <div class="form-group form-inline"> <div class="btn-group"> <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"> <i class="fa fa-refresh"></i> 刷新 </button> </div> </div> </div> <div class="box-tools pull-right"> <div class="has-feedback"> <input type="text" class="form-control input-sm" placeholder="搜索"> <span class="glyphicon glyphicon-search form-control-feedback"></span> </div> </div> <!--工具欄/--> </div> <!-- 數據表格 /--> </div> <!-- /.box-body --> <!-- .box-footer--> <div class="box-footer"> <div class="pull-left"> <div class="form-group form-inline"> 總共2 頁,共14 條數據。 每頁 <select class="form-control"> <option>10</option> <option>15</option> <option>20</option> <option>50</option> <option>80</option> </select> 條 </div> </div> <div class="box-tools pull-right"> <ul class="pagination"> <li><a href="#" aria-label="Previous">首頁</a></li> <li><a href="#">上一頁</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">下一頁</a></li> <li><a href="#" aria-label="Next">尾頁</a></li> </ul> </div> </div> <!-- /.box-footer--> </div> </section> <!-- 正文區域 /--> </div> <!-- 內容區域 /--> <!-- 底部導航 --> <footer class="main-footer"> <div class="pull-right hidden-xs"> <b>Version</b> 1.0.8 </div> <strong>Copyright © 2014-2017 <a href="#">研究院研發部</a>. </strong> All rights reserved. </footer> <!-- 底部導航 /--> </div> <script src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script> <script> $.widget.bridge('uibutton', $.ui.button); </script> <script src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script> <script src="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script> <script src="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script> <script src="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script> <script src="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script> <script src="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script> <script src="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script> <script src="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script> <script> $(document).ready(function() { // 選擇框 $(".select2").select2(); // WYSIHTML5編輯器 $(".textarea").wysihtml5({ locale : 'zh-CN' }); }); // 設置激活菜單 function setSidebarActive(tagUri) { var liObj = $("#" + tagUri); if (liObj.length > 0) { liObj.parent().parent().addClass("active"); liObj.addClass("active"); } } $(document).ready(function() { // 激活導航位置 setSidebarActive("order-manage"); // 列表按鈕 $("#dataList td input[type='checkbox']").iCheck({ checkboxClass : 'icheckbox_square-blue', increaseArea : '20%' }); // 全選操作 $("#selall").click(function() { var clicks = $(this).is(':checked'); if (!clicks) { $("#dataList td input[type='checkbox']").iCheck("uncheck"); } else { $("#dataList td input[type='checkbox']").iCheck("check"); } $(this).data("clicks", !clicks); }); }); </script> </body> </html>
-
-
在controller模塊下創建編寫切面類處理日志類,用來獲取訪問的信息
-
package org.hacker.ssm.controller; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Date; /** * @author HackerStar * @create 2020-04-29 16:26 */ @Component @Aspect public class LogAop { private Date startTime;//訪問時間 private Class executionClass;//訪問的類 private Method executionMethod;//訪問的方法 @Autowired private HttpServletRequest request; @Autowired private ISysLogService sysLogService; @Before("execution(* org.hacker.ssm.controller.*.*(..))") public void doBefore(JoinPoint jp) throws NoSuchMethodException { startTime = new Date();//訪問的初始時間 executionClass = jp.getTarget().getClass();//獲取訪問的類 String methodName = jp.getSignature().getName();//獲取訪問的方法的名字 Object[] args = jp.getArgs();//獲取訪問的方法的參數 if (args == null || args.length == 0) {//方法沒有參數 executionMethod = executionClass.getMethod(methodName);//獲取訪問的方法 } else {//方法有參數,將args元素遍歷,獲取對應的Class,裝到Class數組中 Class[] classArgs = new Class[args.length]; for (int i = 0; i < args.length; i++) { classArgs[i] = args[i].getClass();//獲取訪問的方法 } executionMethod = executionClass.getMethod(methodName, classArgs); } } @After("execution(* org.hacker.ssm.controller.*.*(..))") public void doAfter(JoinPoint jp) { //獲取類上的@RequestMapping對象 if (executionClass != SysLogController.class) { RequestMapping classAnnotation = (RequestMapping) executionClass.getAnnotation(RequestMapping.class); if (classAnnotation != null) { //獲取方法上的@RequestMapping對象 RequestMapping methodAnnotation = executionMethod.getAnnotation(RequestMapping.class); if (methodAnnotation != null) { SysLog sysLog = new SysLog();//封裝的實體類 String url = ""; //它的值應該是類上的@RequestMapping的value+方法上的@RequestMapping的value url = classAnnotation.value()[0] + methodAnnotation.value()[0]; //獲取訪問時長 Long exectiontime = new Date().getTime() - startTime.getTime(); //獲取ip String ip = request.getRemoteAddr(); //獲取用戶名 SecurityContext context = SecurityContextHolder.getContext(); User principal = (User) context.getAuthentication().getPrincipal(); String username = principal.getUsername(); //將sysLog對象屬性封裝 sysLog.setVisitTime(startTime); sysLog.setExecutionTime(exectiontime); sysLog.setUsername(username); sysLog.setMethod("[類名]" + executionClass.getName() + "[方法名]" + executionMethod.getName()); sysLog.setIp(ip); sysLog.setUrl(url); //將訪問記錄實體類保存到數據庫 sysLogService.save(sysLog); } } } } }
-
編寫SysLogController模塊用來和前端頁面交互
-
package org.hacker.ssm.controller; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:37 */ @RequestMapping("/sysLog") @Controller public class SysLogController { @Autowired private ISysLogService sysLogService; @RequestMapping("/findAll.do") public ModelAndView findAll() { ModelAndView mv = new ModelAndView(); List<SysLog> sysLogs = sysLogService.findAll(); mv.addObject("sysLogs", sysLogs); mv.setViewName("sysLog-list"); return mv; } }
-
-
-
編寫SysLogService模塊
-
接口
-
package org.hacker.ssm.service; import org.hacker.ssm.domain.SysLog; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:41 */ public interface ISysLogService { public List<SysLog> findAll(); void save(SysLog sysLog); }
-
-
實現類
-
package org.hacker.ssm.service.impl; import org.hacker.ssm.dao.ISysLogDao; import org.hacker.ssm.domain.SysLog; import org.hacker.ssm.service.ISysLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:43 */ @Service @Transactional public class SysLogServiceImpl implements ISysLogService { @Autowired private ISysLogDao sysLogDao; @Override public List<SysLog> findAll() { return sysLogDao.findAll(); } @Override public void save(SysLog sysLog) { sysLogDao.save(sysLog); } }
-
-
-
編寫SysLogDao模塊
-
package org.hacker.ssm.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.hacker.ssm.domain.SysLog; import java.util.List; /** * @author HackerStar * @create 2020-04-29 16:43 */ public interface ISysLogDao { @Select("select * from sysLog") List<SysLog> findAll(); @Insert("insert into syslog(visitTime,username,ip,url,executionTime,method) values(#{visitTime},#{username},#{ip},#{url},#{executionTime},#{method})") void save(SysLog sysLog); }
-
-
結果
總結
比較棘手的方面:
- 分析功能實現
- 前端JSP頁面的制作
- dao模塊編寫操作數據庫的指令,尤其是涉及多表操作時,需要弄清其中關聯關系
- 配置文件的書寫
5.數據庫類型和實體類數據類型的匹配
項目工作過程完畢!