首页 技术 正文
技术 2022年11月21日
0 收藏 592 点赞 2,712 浏览 194916 个字

学于黑马程序员和传智播客联合做的教学项目 感谢

黑马程序员官网

传智播客官网

个人根据教程的每天的工作进度的代码和资料 密码:cti5

b站在线视频

微信搜索"艺术行者",关注并回复关键词"企业权限管理"获取视频和教程资料!

目录

功能介绍

  1. 商品查询

  2. 商品添加

  3. 订单查询

  4. 订单分页查询

  5. 订单详情查询

  6. 用户管理

  7. 角色管理

  8. 资源权限管理

  9. 权限关联与控制

  10. AOP日志处理

数据库介绍

  1. 产品表

  1. 订单表

  1. 会员表

  1. 旅客表

  1. 用户表

  1. 角色表

  1. 资源权限表

  1. 日志表

第一天

前端使用的技术: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
@Transactionalpublic 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);
}
  • 运行服务器,打开浏览器查看效果

订单分页功能

  1. PageHelper介绍

    PageHelper是国内非常优秀的一款开源的mybatis分页插件,它支持基本主流与常用的数据库,例如mysql、oracle、mariaDB、DB2、SQLite、Hsqldb等。

    本项目在 github 的项目地址:https://github.com/pagehelper/Mybatis-PageHelper

    本项目在 gitosc 的项目地址:http://git.oschina.net/free/Mybatis_PageHelper

  2. PageHelper使用

    在 总项目的pom.xml 中添加如下依赖

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
  1. 配置

    在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>
  1. 基本使用

    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 &copy; 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框架开发的企业软件项目。

  • 如何使用
  1. 导入依赖到总工程的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>
  1. 配置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 &copy; 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 &copy; 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 List findAll();

        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 &copy; 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 &copy; 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);
      }
  • 结果

第四天完毕

第五天

  1. 权限关联与控制
  2. 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 &copy; 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 &copy; 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 &copy; 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 &copy; 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 &copy; 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在方法的权限控制上支持三种类型的注解

    1. JSR-250注解

      JSR-250需要导入依赖进行使用

    2. @Secured注解

      @Secured注解是Spring security框架自带的功能

    3. 支持表达式的注解

      表达式注解常常配合页面端标签控制权限进行使用,这里还要花费一些时间学习表达式的方法

    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 &copy; 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);
      }
  • 结果

总结

比较棘手的方面:

  1. 分析功能实现

  2. 前端JSP页面的制作
  3. dao模块编写操作数据库的指令,尤其是涉及多表操作时,需要弄清其中关联关系

  4. 配置文件的书写

    5.数据库类型和实体类数据类型的匹配

项目工作过程完毕!

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,966
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,487
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,332
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,115
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,748
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,783