目錄
- SSM權限管理系統
- 項目搭建
- 主頁搭建
- 員工列表
- 添加權限
- 權限控制
- 菜單權限管理
- 系統日志
- Excel導入導出
SSM權限管理系統
項目搭建
1.創建Maven-webapp工程
2.SSM框架集成
2.1添加依賴,即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>com.itlike</groupId>
<artifactId>PromissionPro</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>PromissionPro 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>
<!--定義版本號 ${org.springframework.version}-->
<org.springframework.version>5.0.7.RELEASE</org.springframework.version>
<org.mybatis.version>3.4.6</org.mybatis.version>
</properties>
<dependencies>
<!--單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
</dependency>
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--mysql驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.14</version>
</dependency>
<!-- common-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--spring-test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<!--spring-core-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-context-support-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-expression-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-tx-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring-webmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<!--aspectj weaver-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<!-- cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${org.mybatis.version}</version>
</dependency>
<!--mybatis-spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.4</version>
</dependency>
<!--jackson-databind-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<!--jackson-annotations-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
</dependency>
<!--slf4j-api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<!--slf4j-log4j12-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--commons-fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.4</version>
</dependency>
<!--shiro-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
<build>
<finalName>PromissionPro</finalName>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
</dependencies>
</plugin>
</plugins>
<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.1.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.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</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>
</build>
</project>
2.2添加配置文件
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/promission?characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234
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
">
<!--注解掃描-->
<context:component-scan base-package="com.itlike"/>
<!--導入mybatis-->
<import resource="classpath:application-mybatis.xml"/>
<!--導入springMVC-->
<import resource="classpath:application-mvc.xml"/>
<!--導入shiro-->
<import resource="classpath:application-shiro.xml"/>
<!-- aop配置 日志配置 -->
<bean id="SystemAspect" class="com.itlike.aspect.SystemAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.itlike.service.*.*(..))" id="servicePoint" />
<aop:aspect ref="SystemAspect">
<aop:after method="writeLog" pointcut-ref="servicePoint"/>
</aop:aspect>
</aop:config>
</beans>
application-mvc.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:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
">
<mvc:annotation-driven />
<!--靜態資源處理 -->
<mvc:default-servlet-handler/>
<!--視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp" />
</bean>
<!--配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.itlike.interceptor.RequestInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!--配置文件上傳解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>1040000</value>
</property>
</bean>
</beans>
application-mybatis.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
">
<!--spring-Mybatis整合-->
<!--加載數據庫屬性文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--連接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init"
destroy-method="close">
<property name="initialSize" value="5"/>
<property name="driverClassName" value="${jdbc.driver}" />
<!--屬性文件當中的名稱不能和name名稱一樣-->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 配置事務管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 數據源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 開啟注解事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Mybatis的工廠 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 核心配置文件的位置 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
<!--配置mapper映射文件的路徑-->
<property name="mapperLocations" value="classpath:com.itlike.mapper/*Mapper.xml"/>
</bean>
<!-- 配置Mapper接口掃描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
<!-- 配置Mapper掃描包 -->
<property name="basePackage" value="com.itlike.mapper" />
</bean>
</beans>
2.3配置web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="false">
<absolute-ordering/>
<display-name>web</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 攔截到所有請求,使用spring一個bean來進行處理 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 是否filter中的init和 destroy-->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置前端控制器-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--加載的主配置文件-->
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!-- 項目啟動就加載框架 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 編碼過濾器 -->
<filter>
<filter-name>CharacterEncoding</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>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
3.添加代碼生成器
添加代碼生成器插件pom依賴
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
</dependencies>
</plugin>
添加代碼生成器配置文件,即generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
<context id="mysql" defaultModelType="hierarchical"
targetRuntime="MyBatis3Simple">
<!-- 自動識別數據庫關鍵字,
默認false,如果設置為true,
根據SqlReservedWords中定義的關鍵字列表;
一般保留默認值,
遇到數據庫關鍵字(Java關鍵字),
使用columnOverride覆蓋 -->
<property name="autoDelimitKeywords" value="false" />
<!-- 生成的Java文件的編碼 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 格式化java代碼 -->
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<!-- 格式化XML代碼 -->
<property name="xmlFormatter"
value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />
<!-- beginningDelimiter和endingDelimiter:指明數據庫的用於標記數據庫對象名的符號,
比如ORACLE就是雙引號,MYSQL默認是`反引號; -->
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<!--阻止生成日期和注釋-->
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 數據庫連接信息 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql:///employee" userId="root" password="123456">
</jdbcConnection>
<!-- java類型處理器 用於處理數據庫中的類型到Java中的類型,
默認使用JavaTypeResolverDefaultImpl;
注意一點,默認會先嘗試使用Integer,Long,Short等來對應DECIMAL和
NUMERIC數據類型; -->
<javaTypeResolver
type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!-- true:使用BigDecimal對應DECIMAL和 NUMERIC數據類型 f
alse:默認, scale>0;length>18:使用BigDecimal;
scale=0;length[10,18]:使用Long; scale=0;length[5,9]:
使用Integer; scale=0;length<5:使用Short; -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--
配置domain生成策略
targetProject:把自動生成的domian放在哪個工程里面
targetPackage:哪個包下
-->
<javaModelGenerator targetPackage="com.itlike.domain"
targetProject="src/main/java">
<!-- for MyBatis3/MyBatis3Simple
自動為每一個生成的類創建一個構造方法,
構造方法包含了所有的field;而不是使用setter; -->
<property name="constructorBased" value="false" />
<!-- for MyBatis3 / MyBatis3Simple
是否創建一個不可變的類,如果為true,
那么MBG會創建一個沒有setter方法的類,
取而代之的是類似constructorBased的類 -->
<property name="immutable" value="false" />
<!-- 設置是否在getter方法中,
對String類型字段調用trim()方法 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--
配置mapper.xml的生成策略
targetPackage:把自動生成的mapper放在哪個工程里面
targetProject:哪個包下
-->
<sqlMapGenerator targetPackage="com.itlike.mapper"
targetProject="src/main/java">
<!-- 在targetPackage的基礎上,
根據數據庫的schema再生成一層package,
最終生成的類放在這個package下,默認為false -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!--
mapper接口生成策略
-->
<javaClientGenerator targetPackage="com.itlike.mapper"
type="XMLMAPPER" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table tableName="employee"></table>
</context>
</generatorConfiguration>
創建員工表sql語句
CREATE TABLE `employee` (
`id` bigint(20) NOT NULL,
`username` varchar(50) DEFAULT NULL,
`password` varchar(100) DEFAULT NULL,
`realname` varchar(50) DEFAULT NULL,
`tel` varchar(50) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`inputtime` datetime DEFAULT NULL,
`state` tinyint(1) DEFAULT NULL,
`admin` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
生成員工mapper,雙擊maven插件
主頁搭建
EasyUI主頁
1.在目錄當中引入EasyUI相關JS與css
2.在首頁當中引入所需要的js與css
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/plugins/easyui/uimaker/easyui.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/plugins/easyui/uimaker/icon.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/static/plugins/easyui/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/plugins/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/plugins/easyui/easyui-lang-zh_CN.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/index.js"></script>
3.編寫body首頁框架格式
<body class="easyui-layout">
<div data-options="region:'north'" style="height:100px; background: #ec4e00; padding: 20px 20px">
<img src="main_logo.png" alt="">
</div>
<div data-options="region:'south'" style="height:50px; border-bottom: 3px solid #ec4e00">
<p align="center" style="font-size: 14px">撩課學院</p>
</div>
<div data-options="region:'west',split:true" style="width:300px;">
<div id="aa" class="easyui-accordion" data-options="fit:true">
<div title="菜單" data-options="iconCls:'icon-save',selected:true" style="overflow:auto;padding:10px;">
<!--tree-->
<ul id="tree"></ul>
</div>
<div title="公告" data-options="iconCls:'icon-reload'" style="padding:10px;">
</div>
</div>
</div>
<div data-options="region:'center'" style="background:#eee;">
<!--標簽-->
<div id="tabs" style="overflow: hidden" >
</div>
</div>
</body>
4.創建首頁index.js引入
$(function () {
$("#tabs").tabs({
fit:true
})
$('#tree').tree({
url:'/getTreeData',
lines:true,
onSelect: function(node){
/*在添加之前, 做判斷 判斷這個標簽是否存在 */
var exists = $("#tabs").tabs("exists",node.text);
if(exists){
/*存在,就讓它選中*/
$("#tabs").tabs("select",node.text);
}else {
if (node.url !=''&& node.url !=null){
/*如果不存在 ,添加新標簽*/
$("#tabs").tabs("add",{
title:node.text,
/*href:node.attributes.url,*/ /*href 引入的是body當中*/
content:"<iframe src="+node.url+" frameborder='0' width='100%' height='100%'></iframe>",
closable:true
})
}
}
},
onLoadSuccess: function (node, data) {
console.log(data[0].children[0].id);
if (data.length > 0) {
//找到第一個元素
var n = $('#tree').tree('find', data[0].children[0].id);
//調用選中事件
$('#tree').tree('select', n.target);
}
}
});
});
員工列表
1.在tree當中指定跳轉的地址--暫時用tree.json文件代替
[
{
"id": 1,
"text": "系統管理",
"children": [
{
"id":2,
"text": "員工管理",
"url": "/employee"
},
{
"id":3,
"text": "角色權限管理",
"url": "/role"
},
{
"id":4,
"text": "菜單管理",
"url": "/menu"
}
]
}
]
**index.js**
$(function () {
$("#tabs").tabs({
fit:true
})
$('#tree').tree({
url:"static/tree.json",
lines:true,
onSelect: function(node){
/*在添加之前, 做判斷 判斷這個標簽是否存在 */
var exists = $("#tabs").tabs("exists",node.text);
if(exists){
/*存在,就讓它選中*/
$("#tabs").tabs("select",node.text);
}else {
if (node.url !=''&& node.url !=null){
/*如果不存在 ,添加新標簽*/
$("#tabs").tabs("add",{
title:node.text,
/*href:node.attributes.url,*/ /*href 引入的是body當中*/
content:"<iframe src="+node.url+" frameborder='0' width='100%' height='100%'></iframe>",
closable:true
})
}
}
}
});
});
2.創建頁面跳轉控制器,接收請求跳轉到Employee頁面
@Controller
public class PageLocation {
@RequestMapping("/employee")
public String employee(){
return "employee";
}
@RequestMapping("/department")
public String department(){
return "department";
}
}
3.在Employee頁面中引入公共的EasyUI相關js編寫數據表格
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/employee.js"></script>
4.創建Employee.js引入設置-數據表格
數據加載
**employee.js**
$(function () {
/*員式數據列表*/
$("#dg").datagrid({
url:"/employeeList",
columns:[[
{field:'username',title:'姓名',width:100,align:'center'},
{field:'inputtime',title:'入職時間',width:100,align:'center'},
{field:'tel',title:'電話',width:100,align:'center'},
{field:'email',title:'郵箱',width:100,align:'center'},
{field:'department',title:'部門',width:100,align:'center',formatter: function(value,row,index){
if (value){
return value.name;
}
}},
{field:'state',title:'狀態',width:100,align:'center',formatter: function(value,row,index){
if(row.state){
return "在職";
}else {
return "<font style='color: red'>離職</font>"
}
}},
{field:'admin',title:'管理員',width:100,align:'center',formatter: function(value,row,index){
if(row.admin){
return "是";
}else {
return "否"
}
}},
]],
fit:true,
fitColumns:true,
rownumbers:true,
pagination:true,
singleSelect:true,
striped:true,
toolbar:"#tb",
onClickRow:function (rowIndex,rowData) {
/*判斷當前行是否是離職狀態*/
if(!rowData.state){
/*離職,把離職按鈕禁用*/
$("#delete").linkbutton("disable");
}else {
/*離職,把離職按鈕啟用*/
$("#delete").linkbutton("enable");
}
}
});
})
控制層
@Controller
public class EmployeeController {
/*注入業務層*/
@Autowired
private EmployeeService employeeService;
@RequestMapping("/employee")
public String employee(){
return "employee";
}
@RequestMapping("/employeeList")
@ResponseBody
public PageListRes employeeList(QueryVo vo){
System.out.println(vo);
/*調用業務層查詢員工*/
PageListRes pageListRes = employeeService.getEmployee(vo);
return pageListRes;
}
})
業務層
@Service
@Transactional
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Override
public PageListRes getEmployee(QueryVo vo) {
/*調用mapper 查詢員工 */
Page<Object> page = PageHelper.startPage(vo.getPage(), vo.getRows());
List<Employee> employees = employeeMapper.selectAll(vo);
/*封裝成pageList*/
PageListRes pageListRes = new PageListRes();
pageListRes.setTotal(page.getTotal());
pageListRes.setRows(employees);
return pageListRes;
}
})
日期格式化
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date inputtime;
格式化狀態和管理員
5.創建部門表
建表語句
CREATE TABLE `department` (
`id` bigint(20) NOT NULL,
`name` varchar(10) DEFAULT NULL COMMENT '部門名稱 ',
`sn` varchar(20) DEFAULT NULL COMMENT '部門編號',
`manager_id` bigint(20) DEFAULT NULL,
`parent_id` bigint(20) DEFAULT NULL,
`state` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `manager_id` (`manager_id`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `department_ibfk_1` FOREIGN KEY (`manager_id`) REFERENCES `employee` (`id`),
CONSTRAINT `department_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
employee表添加字段dept_id
在代碼生成器當中生成相關domain和mapper
修改employee的domian
@Setter@Getter@ToString
public class Employee {
private Long id;
private String username;
private String password;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date inputtime;
private String tel;
private String email;
private Boolean state;
private Boolean admin;
private Department department;
}
6.查詢部門
EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.itlike.mapper.EmployeeMapper" >
<resultMap id="BaseResultMap" type="com.itlike.domain.Employee" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="inputtime" property="inputtime" jdbcType="TIMESTAMP" />
<result column="tel" property="tel" jdbcType="VARCHAR" />
<result column="email" property="email" jdbcType="VARCHAR" />
<result column="state" property="state" jdbcType="BIT" />
<result column="admin" property="admin" jdbcType="BIT" />
<association property="department" javaType="com.itlike.domain.Department" columnPrefix="d_">
<result property="id" column="id"/>
<result property="name" column="name"/>
</association>
</resultMap>
<!--員工關聯部門查詢-->
<select id="selectAll" resultMap="BaseResultMap" >
select
e.id,
e.username,
e.inputtime,
e.tel,
e.email,
e.state,
e.admin,
d.id as d_id,
d.`name` as d_name
from employee as e
LEFT JOIN department as d
ON e.dep_id = d.id
<include refid="where_sql"/>
order by e.id desc
</select>
</mapper>
$(function () {
/*員式數據列表*/
$("#dg").datagrid({
url:"/employeeList",
columns:[[
{field:'username',title:'姓名',width:100,align:'center'},
{field:'inputtime',title:'入職時間',width:100,align:'center'},
{field:'tel',title:'電話',width:100,align:'center'},
{field:'email',title:'郵箱',width:100,align:'center'},
{field:'department',title:'部門',width:100,align:'center',formatter: function(value,row,index){
if (value){
return value.name;
}
}},
{field:'state',title:'狀態',width:100,align:'center',formatter: function(value,row,index){
if(row.state){
return "在職";
}else {
return "<font style='color: red'>離職</font>"
}
}},
{field:'admin',title:'管理員',width:100,align:'center',formatter: function(value,row,index){
if(row.admin){
return "是";
}else {
return "否"
}
}},
]]
});
})
7.列表添加工具欄目
1.添加標簽
<div id="tb">
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" id="add">添加</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true" id="edit">編輯</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true" id="delete">刪除</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-reload',plain:true" id="reload">刷新</a>
</div>
2.處理Js
toolbar: '#tb',
8.添加對話框彈出
對話框標簽
<table align="center" style="border-spacing: 0px 10px">
<tr>
<td>用戶名:</td>
<td><input type="text" class="easyui-validatebox" data-options="required:true"></td>
</tr>
<tr>
<td>真實姓名:</td>
<td><input type="text" class="easyui-validatebox" data-options="required:true"></td>
</tr>
<tr>
<td>手機:</td>
<td><input type="text" class="easyui-validatebox" data-options="required:true"></td>
</tr>
<tr>
<td>郵箱:</td>
<td><input type="text" class="easyui-validatebox" data-options="required:true,validType:'email'" ></td>
</tr>
<tr>
<td>入職日期:</td>
<td><input type="text" class="easyui-datebox" required="required"></td>
</tr>
<tr>
<td>部門:</td>
<td><select id="department"></select></td>
</tr>
<tr>
<td>是否管理員:</td>
<td><select id="state"></select></td>
</tr>
</table>
部門列表展示
/*部門選擇 下拉列表*/
$("#department").combobox({
width:150,
panelHeight:'auto',
editable:false,
url:'departList',
textField:'name',
valueField:'id',
onLoadSuccess:function () { /*數據加載完畢之后回調*/
$("#department").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
}
});
設置placehode
$("#department").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
是否管理員下拉列表展示
/*管理員下拉列表選擇*/
$("#state").combobox({
width:150,
panelHeight:'auto',
textField:'label',
valueField:'value',
data:[{
label:'是',
value:'true'
},{
label:'否',
value:'false'
}]
});
$("#state").combobox({"select","否"});
9.保存
表單標簽上填寫name
<form id="employeeForm">
<%--添加一個隱藏域 編輯--%>
<input type="hidden" name="id">
<table align="center" style="border-spacing: 0px 10px">
<tr>
<td>用戶名:</td>
<td><input type="text" name="username" class="easyui-validatebox" data-options="required:true"></td>
</tr>
<tr id="password">
<td>密碼:</td>
<td><input type="text" name="password" class="easyui-validatebox"></td>
</tr>
<tr>
<td>手機:</td>
<td><input type="text" name="tel" class="easyui-validatebox" ></td>
</tr>
<tr>
<td>郵箱:</td>
<td><input type="text" name="email" class="easyui-validatebox" ></td>
</tr>
<tr>
<td>入職日期:</td>
<td><input type="text" name="inputtime" class="easyui-datebox"></td>
</tr>
<tr>
<td>部門:</td>
<td><input id="department" name="department.id" placeholder="請選擇部門"/></td>
</tr>
<tr>
<td>是否管理員:</td>
<td><input id="state" name="admin" placeholder="是否為管理員"/></td>
</tr>
<tr>
<td>選擇角色:</td>
<td><input id="role" name="role.rid" placeholder="請選擇角色"/></td>
</tr>
</table>
</form>
下拉列表設置默認值時, 默認value也要設置上去
保存時判斷添加還是編輯
監聽保存按鈕,提交表單
/*對話框*/
$("#dialog").dialog({
width:350,
height:400,
closed:true,
buttons:[{
text:'保存',
handler:function(){
/*判斷當前是添加 還是編輯*/
var id = $("[name='id']").val();
var url;
if(id){
/*編輯*/
url = "updateEmployee";
}else {
/*添加*/
url= "saveEmployee";
}
/*提交表單*/
$("#employeeForm").form("submit",{
url:url,
onSubmit:function(param){
/*獲取選中的角色*/
var values = $("#role").combobox("getValues");
for(var i = 0; i < values.length; i++){
var rid = values[i];
param["roles["+i+"].rid"] = rid;
}
},
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#dialog").dialog("close");
/*重新加載數據表格*/
$("#dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
});
}
},{
text:'關閉',
handler:function(){
$("#dialog").dialog("close");
}
}]
});
10.編輯
監聽編輯按鈕點擊
/*監聽編輯按鈕點擊*/
$("#edit").click(function () {
/*獲取當前選中的行*/
var rowData = $("#dg").datagrid("getSelected");
console.log(rowData);
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*取消密碼驗證*/
$("[name='password']").validatebox({required:false});
$("#password").hide();
/*彈出對話框*/
$("#dialog").dialog("setTitle","編輯員工");
$("#dialog").dialog("open");
/*回顯部門*/
rowData["department.id"] = rowData["department"].id;
/*回顯管理員*/
rowData["admin"] = rowData["admin"]+"";
/*回顯角色*/
/*根據當前用戶的id,查出對應的角色*/
$.get("/getRoleByEid?id="+rowData.id,function (data) {
/*設置下拉列表數據回顯*/
$("#role").combobox("setValues",data);
});
/*選中數據的回示*/
$("#employeeForm").form("load",rowData);
});
更新業務邏輯
/*接收更新員工請求*/
@RequestMapping("/updateEmployee")
@ResponseBody
@RequiresPermissions("employee:edit")
public AjaxRes updateEmployee(Employee employee){
AjaxRes ajaxRes = new AjaxRes();
try {
/*調用業務層,更新員工*/
employeeService.updateEmployee(employee);
ajaxRes.setMsg("更新成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
ajaxRes.setSuccess(false);
ajaxRes.setMsg("更新失敗");
}
return ajaxRes;
}
11.離職
離職按鈕點擊
/*設置離職按鈕點擊*/
$("#delete").click(function () {
/*獲取當前選中的行*/
var rowData = $("#dg").datagrid("getSelected");
console.log(rowData);
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*提醒用戶,是否做離職操作*/
$.messager.confirm("確認","是否做離職操作",function (res) {
if(res){
/*做離職操作*/
$.get("/updateState?id="+rowData.id,function (data) {
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*重新加載數據表格*/
$("#dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
});
}
});
});
業務處理
/*接收離職操作請求*/
@RequestMapping("/updateState")
@ResponseBody
@RequiresPermissions("employee:delete")
public AjaxRes updateState(Long id){
AjaxRes ajaxRes = new AjaxRes();
try {
/*調用業務層,設置員工離職狀態*/
employeeService.updateState(id);
ajaxRes.setMsg("更新成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
System.out.println(e);
ajaxRes.setSuccess(false);
ajaxRes.setMsg("更新失敗");
}
return ajaxRes;
}
12.離職按鈕禁用
給數據表格綁定選中事件
/*員式數據列表*/
$("#dg").datagrid({
url:"/employeeList",
columns:[[
{field:'username',title:'姓名',width:100,align:'center'},
{field:'inputtime',title:'入職時間',width:100,align:'center'},
{field:'tel',title:'電話',width:100,align:'center'},
{field:'email',title:'郵箱',width:100,align:'center'},
{field:'department',title:'部門',width:100,align:'center',formatter: function(value,row,index){
if (value){
return value.name;
}
}},
{field:'state',title:'狀態',width:100,align:'center',formatter: function(value,row,index){
if(row.state){
return "在職";
}else {
return "<font style='color: red'>離職</font>"
}
}},
{field:'admin',title:'管理員',width:100,align:'center',formatter: function(value,row,index){
if(row.admin){
return "是";
}else {
return "否"
}
}},
]],
fit:true,
fitColumns:true,
rownumbers:true,
pagination:true,
singleSelect:true,
striped:true,
toolbar:"#tb",
onClickRow:function (rowIndex,rowData) {
/*判斷當前行是否是離職狀態*/
if(!rowData.state){
/*離職,把離職按鈕禁用*/
$("#delete").linkbutton("disable");
}else {
/*離職,把離職按鈕啟用*/
$("#delete").linkbutton("enable");
}
}
});
添加按鈕js插件(記得是因為EasyUI帶有小bug)
base.js
/**
* linkbutton方法擴展
* @param {Object} jq
*/
$.extend($.fn.linkbutton.methods, {
/**
* 激活選項(覆蓋重寫)
* @param {Object} jq
*/
enable: function(jq){
return jq.each(function(){
var state = $.data(this, 'linkbutton');
if ($(this).hasClass('l-btn-disabled')) {
var itemData = state._eventsStore;
//恢復超鏈接
if (itemData.href) {
$(this).attr("href", itemData.href);
}
//回復點擊事件
if (itemData.onclicks) {
for (var j = 0; j < itemData.onclicks.length; j++) {
$(this).bind('click', itemData.onclicks[j]);
}
}
//設置target為null,清空存儲的事件處理程序
itemData.target = null;
itemData.onclicks = [];
$(this).removeClass('l-btn-disabled');
}
});
},
/**
* 禁用選項(覆蓋重寫)
* @param {Object} jq
*/
disable: function(jq){
return jq.each(function(){
var state = $.data(this, 'linkbutton');
if (!state._eventsStore)
state._eventsStore = {};
if (!$(this).hasClass('l-btn-disabled')) {
var eventsStore = {};
eventsStore.target = this;
eventsStore.onclicks = [];
//處理超鏈接
var strHref = $(this).attr("href");
if (strHref) {
eventsStore.href = strHref;
$(this).attr("href", "javascript:void(0)");
}
//處理直接耦合綁定到onclick屬性上的事件
var onclickStr = $(this).attr("onclick");
if (onclickStr && onclickStr != "") {
eventsStore.onclicks[eventsStore.onclicks.length] = new Function(onclickStr);
$(this).attr("onclick", "");
}
//處理使用jquery綁定的事件
var eventDatas = $(this).data("events") || $._data(this, 'events');
if (eventDatas["click"]) {
var eventData = eventDatas["click"];
for (var i = 0; i < eventData.length; i++) {
if (eventData[i].namespace != "menu") {
eventsStore.onclicks[eventsStore.onclicks.length] = eventData[i]["handler"];
$(this).unbind('click', eventData[i]["handler"]);
i--;
}
}
}
state._eventsStore = eventsStore;
$(this).addClass('l-btn-disabled');
}
});
}
});
13.分頁控制
EasyUI中可以自動的提交分頁參數直接接收分頁參數
@RequestMapping("/employeeList")
@ResponseBody
public PageListRes employeeList(QueryVo vo){
System.out.println(vo);
/*調用業務層查詢員工*/
PageListRes pageListRes = employeeService.getEmployee(vo);
return pageListRes;
}
業務處理
@Override
public PageListRes getEmployee(QueryVo vo) {
/*調用mapper 查詢員工 */
Page<Object> page = PageHelper.startPage(vo.getPage(), vo.getRows());
List<Employee> employees = employeeMapper.selectAll(vo);
/*封裝成pageList*/
PageListRes pageListRes = new PageListRes();
pageListRes.setTotal(page.getTotal());
pageListRes.setRows(employees);
return pageListRes;
}
14.高級查詢
在toolbar上添加搜索框
<input type="text" name="keyword" style="width: 200px; height: 30px;padding-left: 5px;">
<a class="easyui-linkbutton" iconCls="icon-search" id="searchbtn">查詢</a>
監聽搜索點擊
/*監聽搜索按鈕點擊*/
$("#searchbtn").click(function () {
/*獲取搜索的內容*/
var keyword = $("[name='keyword']").val();
/*重新加載列表 把參數keyword傳過去*/
$("#dg").datagrid("load",{keyword:keyword});
});
接收參數處理
@Setter@Getter@ToString
public class QueryVo {
private int page;
private int rows;
private String keyword;
}
@Override
public PageListRes getEmployee(QueryVo vo) {
/*調用mapper 查詢員工 */
Page<Object> page = PageHelper.startPage(vo.getPage(), vo.getRows());
List<Employee> employees = employeeMapper.selectAll(vo);
/*封裝成pageList*/
PageListRes pageListRes = new PageListRes();
pageListRes.setTotal(page.getTotal());
pageListRes.setRows(employees);
return pageListRes;
}
<sql id="where_sql">
<where>
<if test="keyword !=null and keyword !=''">
and e.username like concat('%',#{keyword},'%')
or e.tel like concat('%',#{keyword},'%')
or e.email like concat('%',#{keyword},'%')
</if>
</where>
</sql>
<!--員工關聯部門查詢-->
<select id="selectAll" resultMap="BaseResultMap" >
select
e.id,
e.username,
e.inputtime,
e.tel,
e.email,
e.state,
e.admin,
d.id as d_id,
d.`name` as d_name
from employee as e
LEFT JOIN department as d
ON e.dep_id = d.id
<include refid="where_sql"/>
order by e.id desc
</select>
添加權限
1.建立角色與權限的表
為多對多關系
- 角色表
CREATE TABLE `employee` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`inputtime` datetime DEFAULT NULL,
`tel` varchar(20) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`state` tinyint(1) DEFAULT NULL,
`admin` tinyint(1) DEFAULT NULL,
`dep_id` bigint(20) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `dep_id` (`dep_id`),
CONSTRAINT `employee_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
- 權限表
CREATE TABLE `permission` (
`pid` bigint(20) NOT NULL,
`pname` varchar(50) DEFAULT NULL,
`presource` varchar(50) DEFAULT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 角色與權限中間表
CREATE TABLE `employee_role_rel` (
`eid` bigint(20) NOT NULL,
`rid` bigint(20) NOT NULL,
PRIMARY KEY (`eid`,`rid`),
KEY `rid` (`rid`),
CONSTRAINT `employee_role_rel_ibfk_1` FOREIGN KEY (`eid`) REFERENCES `employee` (`id`),
CONSTRAINT `employee_role_rel_ibfk_2` FOREIGN KEY (`rid`) REFERENCES `role` (`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
使用代碼生成器生成相關mapper
2.建立角色頁面
角色數據列表
<table id="emp_dg"></table>
<div id="toolbar">
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" id="add">添加</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true" id="edit">編輯</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true" id="remove">離職</a>
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-reload',plain:true" id="reload">刷新</a>
</div>
添加角色權限對話框
<div id="dialog">
<form id="myform">
<table align="center" style="border-spacing: 20px 30px">
<input type="hidden" name="id">
<tr align="center">
<td>角色編號: <input type="text" name="username" class="easyui-validatebox" ></td>
<td>角色名稱: <input type="text" name="username" class="easyui-validatebox" ></td>
</tr>
<tr>
<td><div id="role_data1"></div></td>
<td><div id="role_data2"></div></td>
</tr>
</table>
</form>
</div>
3.加載權限數據實現點擊添加權限,點擊刪除權限
/*角色數據列表*/
$("#role_dg").datagrid({
url:"/getRoles",
columns:[[
{field:'rnum',title:'角色編號',width:100,align:'center'},
{field:'rname',title:'角色名稱',width:100,align:'center'},
]],
fit:true,
fitColumns:true,
rownumbers:true,
pagination:true,
singleSelect:true,
striped:true,
toolbar:"#toolbar",
});
/*權限列表*/
$("#role_data1").datagrid({
title:"所有權限",
width:250,
height:400,
fitColumns:true,
singleSelect:true,
url:'/permissionList',
columns:[[
{field:'pname',title:'權限名稱',width:100,align:'center'},
]],
onClickRow:function (rowIndex,rowData) {/*點擊一行時,回調*/
/*判斷是否已經存在該權限*/
/*取出所有的已選權限*/
var allRows = $("#role_data2").datagrid("getRows");
/*取出每一個進行判斷*/
for(var i = 0; i<allRows.length; i++){
/*取出每一行*/
var row = allRows[i];
if(rowData.pid == row.pid){/*已經存在該權限*/
/*讓已經存在權限成為選中的狀態*/
/*獲取已經成為選中狀態當前角標*/
var index = $("#role_data2").datagrid("getRowIndex",row);
/*讓該行成為選中狀態*/
$("#role_data2").datagrid("selectRow",index);
return;
}
}
/*把當前選中的,添加到已選權限*/
$("#role_data2").datagrid("appendRow",rowData);
}
});
/*選中權限列表*/
$("#role_data2").datagrid({
title:"已選權限",
width:250,
height:400,
singleSelect:true,
fitColumns:true,
columns:[[
{field:'pname',title:'權限名稱',width:100,align:'center'},
]],
onClickRow:function (rowIndex,rowData) {
/*刪除當中選中的一行*/
$("#role_data2").datagrid("deleteRow",rowIndex);
}
});
4.添加角色權限
定義角色權限關系:一個角色有多個權限
@Getter@Setter@ToString
public class Role {
private Long rid;
private String rnum;
private String rname;
/*一個角色可以有多個權限*/
private List<Permission> permissions = new ArrayList<>();
}
點擊保存時,如果沒有隱藏字段id,則為添加操作
保存時, 參數傳遞;默認只傳遞input中的內容,還需要在提交表單時, 把添加的權限信息提交過去
/*添加/編輯對話框*/
$("#dialog").dialog({
width:600,
height:650,
buttons:[{
text:'保存',
handler:function(){
/*判斷當前是保存操作還是編輯操作*/
var rid = $("[name='rid']").val();
var url;
if(rid){
/*編輯*/
url="updateRole"
}else {
/*保存*/
url="saveRole";
}
/*提交表單*/
$("#myform").form("submit",{
url:url,
onSubmit:function(param){ /*傳遞額外參數 已選擇的權限*/
/*獲取已經選擇的權限*/
var allRows = $("#role_data2").datagrid("getRows");
/*遍歷出每一個權限*/
for(var i = 0; i< allRows.length; i++){
/*取出每一個權限 */
var row = allRows[i];
/*給它封裝到集合中*/
param["permissions["+i+"].pid"] = row.pid;
}
},
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#dialog").dialog("close");
/*重新加載數據表格*/
$("#role_dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
});
}
},{
text:'關閉',
handler:function(){
$("#dialog").dialog("close");
}
}],
closed:true
});
接收參數,保存角色與權限
/*接收 保存角色請求地址*/
@RequestMapping("/saveRole")
@ResponseBody
public AjaxRes saveRole(Role role){
AjaxRes ajaxRes = new AjaxRes();
try {
/*調用業務層, 保存角色和權限*/
roleService.saveRole(role);
ajaxRes.setMsg("保存成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
ajaxRes.setSuccess(false);
ajaxRes.setMsg("保存失敗");
}
return ajaxRes;
}
@Override
public void saveRole(Role role) {
/*1.保存角色*/
roleMapper.insert(role);
/*2.保存角色與權限之間關系*/
for (Permission permission : role.getPermissions()) {
roleMapper.insertRoleAndPermissionRel(role.getRid(),permission.getPid());
}
}
5.角色列表
/*角色數據列表*/
$("#role_dg").datagrid({
url:"/getRoles",
columns:[[
{field:'rnum',title:'角色編號',width:100,align:'center'},
{field:'rname',title:'角色名稱',width:100,align:'center'},
]],
fit:true,
fitColumns:true,
rownumbers:true,
pagination:true,
singleSelect:true,
striped:true,
toolbar:"#toolbar",
});
6.編輯角色權限
編輯回顯
/*監聽編輯點擊*/
$("#edit").click(function () {
/*獲取當前選中的行*/
var rowData = $("#role_dg").datagrid("getSelected");
console.log(rowData);
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*加載當前角色下的權限*/
var options = $("#role_data2").datagrid("options");
options.url = "/getPermissionByRid?rid="+rowData.rid;
/*重新加載數據*/
$("#role_data2").datagrid("load");
/*選中數據的回示*/
$("#myform").form("load",rowData);
/*設置標題*/
$("#dialog").dialog("setTitle","編輯角色");
/*打開對話框 */
$("#dialog").dialog("open");
});
添加時清空數據
/*添加角色*/
$("#add").click(function () {
/*清空表單*/
$("#myform").form("clear");
/*清空已選權限*/
$("#role_data2").datagrid("loadData",{rows:[]});
/*設置標題*/
$("#dialog").dialog("setTitle","添加角色");
/*打開對話框 */
$("#dialog").dialog("open");
});
打破關系重新保存
/*更新角色*/
@Override
public void updateRole(Role role) {
/*打破角色與權限之間的之前關系*/
roleMapper.deletePermissionRel(role.getRid());
/*更新角色*/
roleMapper.updateByPrimaryKey(role);
/*重新建立與權限的關系*/
/*重新保存角色與權限之間關系*/
for (Permission permission : role.getPermissions()) {
roleMapper.insertRoleAndPermissionRel(role.getRid(),permission.getPid());
}
}
5.刪除角色權限
監聽刪除按鈕
/*監聽刪除點擊*/
$("#remove").click(function () {
/*獲取當前選中的行*/
var rowData = $("#role_dg").datagrid("getSelected");
console.log(rowData);
if(!rowData){
$.messager.alert("提示","選擇一行數據進行刪除");
return;
}
$.get("deleteRole?rid="+rowData.rid,function (data) {
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*重新加載數據表格*/
$("#role_dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
});
});
處理業務邏輯
/*接收刪除的請求*/
@RequestMapping("/deleteRole")
@ResponseBody
public AjaxRes deleteRole(Long rid){
AjaxRes ajaxRes = new AjaxRes();
try {
/*調用刪除角色的業務*/
roleService.deleteRole(rid);
ajaxRes.setMsg("刪除角色成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
ajaxRes.setSuccess(false);
ajaxRes.setMsg("刪除角色失敗");
}
return ajaxRes;
}
/*刪除角色的業務*/
@Override
public void deleteRole(Long rid) {
/*1.刪除關聯的權限*/
roleMapper.deletePermissionRel(rid);
/*2.刪除對應的角色*/
roleMapper.deleteByPrimaryKey(rid);
}
6.員工添加角色
添加員工時, 添加角色下拉列表
/*回顯角色*/
/*根據當前用戶的id,查出對應的角色*/
$.get("/getRoleByEid?id="+rowData.id,function (data) {
/*設置下拉列表數據回顯*/
$("#role").combobox("setValues",data);
});
保存時, 保存時傳遞角色信息
/*提交表單*/
$("#employeeForm").form("submit",{
url:saveEmployee,
onSubmit:function(param){
/*獲取選中的角色*/
var values = $("#role").combobox("getValues");
for(var i = 0; i < values.length; i++){
var rid = values[i];
param["roles["+i+"].rid"] = rid;
}
},
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#dialog").dialog("close");
/*重新加載數據表格*/
$("#dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
});
7.員工編輯
回顯數據
/*監聽編輯按鈕點擊*/
$("#edit").click(function () {
/*獲取當前選中的行*/
var rowData = $("#dg").datagrid("getSelected");
console.log(rowData);
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*取消密碼驗證*/
$("[name='password']").validatebox({required:false});
$("#password").hide();
/*彈出對話框*/
$("#dialog").dialog("setTitle","編輯員工");
$("#dialog").dialog("open");
/*回顯部門*/
// 當rowData["department"]為空時,會異常
if(rowData["department"] != null)
{
rowData["department.id"] = rowData["department"].id;
}
else
rowData["department.id"] = rowData["department"]+"";
/*回顯管理員*/
rowData["admin"] = rowData["admin"]+"";
/*回顯角色*/
/*根據當前用戶的id,查出對應的角色*/
$.get("/getRoleByEid?id="+rowData.id,function (data) {
/*設置下拉列表數據回顯*/
$("#role").combobox("setValues",data);
});
/*選中數據的回示*/
$("#employeeForm").form("load",rowData);
});
保存編輯
/*更新員工*/
@Override
public void updateEmployee(Employee employee) {
/*打破與角色之間關系*/
employeeMapper.deleteRoleRel(employee.getId());
/*更新員工*/
employeeMapper.updateByPrimaryKey(employee);
/*重新建立角色的關系*/
for (Role role : employee.getRoles()) {
employeeMapper.insertEmployeeAndRoleRel(employee.getId(),role.getRid());
}
}
權限控制
登錄認證
整合Shiro(添加pom依賴)
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
1.登錄攔截,如果沒有登錄,跳轉到登錄頁面
1.在web.xml當中配置過濾器攔截所有請求,進行處理
<!-- 攔截到所有請求,使用spring一個bean來進行處理 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 是否filter中的init和destroy-->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.在spring當中配置shiro過濾器和安全管理器
<!-- 配置shiro過濾器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<!-- 配置shiro過濾器pattern -->
<property name="filterChainDefinitions">
<value>
/static/** = anon <!--不需要登錄驗證-->
/login.jsp = anon <!--不需要登錄驗證-->
/**=authc <!--除指定請求外,其它所有的請求都需要身份驗證-->
</value>
</property>
</bean>
<!-- 配置shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></bean>
2.登錄認證流程
1.表單發送請求
$(function () {
$("#loginBtn").click(function () {
/*Ajax發送請求, 是沒有辦法跳轉服務當中的請求
* 只能通過在瀏覽器當中來跳轉
* */
$.post("/login",$("form").serialize(),function (data) {
/*把data json格式的字符串 轉成 json 數據*/
data = $.parseJSON(data);
if (data.success){
/*跳轉到首頁*/
window.location.href = "/index.jsp"
} else {
alert(data.msg);
}
});
});
});
2.指定登錄認證路徑
<!-- 配置登錄認證的路徑 -->
<property name="loginUrl" value="/login" />
3.創建登錄realm和重新配置過濾器
public class EmployeeRealm extends AuthorizingRealm {
@Autowired
private EmployeeService employeeService;
/*認證*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("來到了認證-------");
/*獲取身份信息*/
String username = (String)token.getPrincipal();
System.out.println(username);
/*根據用戶名當中查詢有沒有當前用戶*/
Employee employee = employeeService.getEmployeeWithUserName(username);
System.out.println(employee);
if (employee == null){
return null;
}
/*認證*/
/*參數: 主體,正確的密碼,鹽,當前realm名稱*/
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
employee,
employee.getPassword(),
ByteSource.Util.bytes(employee.getUsername()),
this.getName());
return info;
}
/*授權
web doGetAuthorizationInfo 什么時候調用
1.發現訪問路徑對應的方法上面 有授權注解 就會調用doGetAuthorizationInfo
2.頁面當中有授權標簽 也會調用doGetAuthorizationInfo
* */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授權調用-------------------");
/*獲取用戶的身份信息*/
Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
/*根據當前用,查詢角色和權限*/
List<String> roles = new ArrayList<>();
List<String> permissions = new ArrayList<>();
/*判斷當前用戶是不是管理員 如果是管理員 擁有所有的權限*/
if(employee.getAdmin()){
/*擁有所有的權限*/
permissions.add("*:*");
}else {
/*查詢角色*/
roles = employeeService.getRolesById(employee.getId());
/*查詢權限*/
permissions = employeeService.getPermissionById(employee.getId());
}
/*給授權信息*/
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);
return info;
}
}
4.配置realm數據源(在application-shiro.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
">
<bean id="myFormFilter" class="com.itlike.web.filter.MyFormFilter"/>
<!-- 配置shiro過濾器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--
index
其它的請求 會判斷 當前有沒有認證過
默認情況 , 沒有認證,會跳轉到login.jsp
如果配置了 loginUrl 沒有認證 執行對應的login請求
login
loginUrl:如果發現請求是loginUrl值 會去做認證
配置登錄認證的路徑
-->
<property name="loginUrl" value="/login"/>
<!--重新配置表單監聽的過濾器-->
<property name="filters">
<map>
<entry key="authc" value-ref="myFormFilter"/>
</map>
</property>
<!--配置安全管理器-->
<property name="securityManager" ref="securityManager"></property>
<!-- 配置shiro過濾器pattern -->
<property name="filterChainDefinitions">
<value>
/static/** = anon <!--不需要登錄驗證-->
/login.jsp = anon <!--不需要登錄驗證-->
/logout = logout <!--取消認證-->
/**=authc <!--除指定請求外,其它所有的請求都需要身份驗證-->
</value>
</property>
</bean>
<!--自定義realm-->
<bean id="employeeRealm" class="com.itlike.web.realm.EmployeeRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<!-- 憑證匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 散列算法 -->
<property name="hashAlgorithmName" value="md5"/>
<!-- 散列次數 -->
<property name="hashIterations" value="2"></property>
</bean>
<!-- 緩存管理器 -->
<bean id="ehCache" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
<!-- 配置shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--注入realm-->
<property name="realm" ref="employeeRealm"/>
<!--注入緩存-->
<property name="cacheManager" ref="ehCache"/>
</bean>
<!--
配置為true即使用cglib繼承的方式,
false為jdk的接口動態代理 控制器沒有實現接口
-->
<aop:config proxy-target-class="true" ></aop:config>
<!-- 使用第三方去掃描shiro的注解 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor ">
<property name="securityManager" ref="securityManager"></property>
</bean>
</beans>
5.創建表單認證過濾器
public class MyFormFilter extends FormAuthenticationFilter {
/*當認證成功時,會調用*/
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
/*響應給瀏覽器*/
response.setCharacterEncoding("utf-8");
System.out.println("認證成功");
AjaxRes ajaxRes = new AjaxRes();
ajaxRes.setSuccess(true);
ajaxRes.setMsg("登錄成功");
/*把對象轉成json格式字符串*/
String jsonString = new ObjectMapper().writeValueAsString(ajaxRes);
response.getWriter().print(jsonString);
return false;
}
/*當認證失敗時, 會調用*/
protected boolean onLoginFailure(AuthenticationToken token,
AuthenticationException e,
ServletRequest request,
ServletResponse response) {
System.out.println("認證失敗");
AjaxRes ajaxRes = new AjaxRes();
ajaxRes.setSuccess(false);
if (e!=null){
/*獲取異常名稱*/
String name = e.getClass().getName();
if(name.equals(UnknownAccountException.class.getName())){
/*沒有帳號*/
ajaxRes.setMsg("帳號不正確");
} else if(name.equals(IncorrectCredentialsException.class.getName())){
/*密碼錯誤*/
ajaxRes.setMsg("密碼不正確");
}else {
/*未知異常*/
ajaxRes.setMsg("未知錯誤");
}
}
try {
/*把對象轉成json格式字符串*/
String jsonString = new ObjectMapper().writeValueAsString(ajaxRes);
response.setCharacterEncoding("utf-8");
response.getWriter().print(jsonString);
} catch (IOException e1) {
e1.printStackTrace();
}
/*響應給瀏覽器*/
return false;
}
}
登錄授權
-
當我們在控制器方法寫了 @RequiresPermissions,Shiro在訪問時, 就會判斷有沒有該權限
-
如果沒有,就不會執行對應方法
實現過程
1.在配置文件當中添加Shiro注解掃描
<!-- 配置為true即使用cglib繼承的方式, false為jdk的接口動態代理 控制器沒有實現接口 --> <aop:config proxy-target-class="true" ></aop:config> <!-- 使用第三方去掃描shiro的注解 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor "> <property name="securityManager" ref="securityManager"></property> </bean>
2.在realm中添加授權信息
public class EmployeeRealm extends AuthorizingRealm {
@Autowired
private EmployeeService employeeService;
/*認證*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("來到了認證-------");
/*獲取身份信息*/
String username = (String)token.getPrincipal();
System.out.println(username);
/*根據用戶名當中查詢有沒有當前用戶*/
Employee employee = employeeService.getEmployeeWithUserName(username);
System.out.println(employee);
if (employee == null){
return null;
}
/*認證*/
/*參數: 主體,正確的密碼,鹽,當前realm名稱*/
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
employee,
employee.getPassword(),
ByteSource.Util.bytes(employee.getUsername()),
this.getName());
return info;
}
/*授權
web doGetAuthorizationInfo 什么時候調用
1.發現訪問路徑對應的方法上面 有授權注解 就會調用doGetAuthorizationInfo
2.頁面當中有授權標簽 也會調用doGetAuthorizationInfo
* */
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授權調用-------------------");
/*獲取用戶的身份信息*/
Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
/*根據當前用,查詢角色和權限*/
List<String> roles = new ArrayList<>();
List<String> permissions = new ArrayList<>();
/*判斷當前用戶是不是管理員 如果是管理員 擁有所有的權限*/
if(employee.getAdmin()){
/*擁有所有的權限*/
permissions.add("*:*");
}else {
/*查詢角色*/
roles = employeeService.getRolesById(employee.getId());
/*查詢權限*/
permissions = employeeService.getPermissionById(employee.getId());
}
/*給授權信息*/
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
info.addStringPermissions(permissions);
return info;
}
}
沒有權限結果處理
@ExceptionHandler(AuthorizationException.class)
public void handleShiroException(HandlerMethod method,HttpServletResponse response) throws Exception{ /*method 發生異常的方法*/
/*跳轉到一個界面 界面提示沒有 權限*/
/*判斷 當前的請求是不是Json請求 如果是 返回json給瀏覽器 讓它自己來做跳轉*/
/*獲取方法上的注解*/
ResponseBody methodAnnotation = method.getMethodAnnotation(ResponseBody.class);
if (methodAnnotation != null){
//Ajax
AjaxRes ajaxRes = new AjaxRes();
ajaxRes.setSuccess(false);
ajaxRes.setMsg("你沒有權限操作");
String s = new ObjectMapper().writeValueAsString(ajaxRes);
response.setCharacterEncoding("utf-8");
response.getWriter().print(s);
}else {
response.sendRedirect("nopermission.jsp");
}
}
權限按鈕控制
- 引入Shiro的標簽庫
- 在需要權限控制的地方添加對應的shiro標簽
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>
<shiro:hasPermission name="employee:add">
<a href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" id="add">添加</a>
</shiro:hasPermission>
密碼散列
在保存用戶時, 給用戶密碼進行加密處理
/*把密碼進行加密*/
把用戶名作為鹽值,進行2次散列
Md5Hash md5Hash = new Md5Hash(employee.getPassword(), employee.getUsername(), 2);
employee.setPassword(md5Hash.toString());
在認證當中添加密碼處理
/*認證*/
/*參數: 主體,正確的密碼,鹽,當前realm名稱*/
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
employee,
employee.getPassword(),
ByteSource.Util.bytes(employee.getUsername()),
this.getName());
添加憑證匹配器
<!-- 配置realm數據源 -->
<bean id="employeeRealm" class="com.itlike.realm.EmployeeRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<!-- 憑證匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 散列算法 -->
<property name="hashAlgorithmName" value="md5"/>
<!-- 散列次數 -->
<property name="hashIterations" value="2"></property>
</bean>
權限緩存
- 進入頁面時, 頁面當中寫了Shiro的標簽,每一個標簽都要去到授權當中進行一次授權查詢
- 授權查詢只使用一次即可, 所以使用緩存,把對應的內容緩存起來,下次再去, 直接從緩存當中進行查詢
使用步驟:
1.添加緩存pom依賴
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
2.添加shiro緩存配置
添加shiro-ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
配置約束
3.application-shiro中配置緩存管理器
<!-- 緩存管理器 -->
<bean id="ehCache" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"/>
</bean>
4.把緩存管理器添加到安全管理器當中
<!-- 配置shiro安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="employeeRealm" />
<property name="cacheManager" ref="ehCache"/>
</bean>
菜單權限管理
菜單頁面
頁面搭建
1.創建菜單表
CREATE TABLE `menu` (
`id` bigint(20) NOT NULL,
`text` varchar(10) DEFAULT NULL,
`url` varchar(30) DEFAULT NULL,
`parent_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `menu` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.生成Mapper,添加父菜單字段
@Setter@Getter@ToString
public class Menu {
private Long id;
private String text;
private String url;
private Menu parent;
private Permission permission;
private List<Menu> children = new ArrayList<>();
}
3.創建Menu頁面
<!-- 數據表格 -->
<table id="menu_datagrid">
<thead>
<tr>
<th>名稱</th>
<th>url</th>
<th>父菜單</th>
</tr>
</thead>
</table>
<!-- 數據表格CRUD按鈕 -->
<div id="menu_toolbar">
<div>
<a class="easyui-linkbutton" iconCls="icon-add" plain="true" id="add">新增</a>
<a class="easyui-linkbutton" iconCls="icon-edit" plain="true" id="edit">編輯</a>
<a class="easyui-linkbutton" iconCls="icon-remove" plain="true" id="del">刪除</a>
<a class="easyui-linkbutton" iconCls="icon-reload" plain="true" id="reload">刷新</a>
</div>
</div>
<div id="menu_dialog">
<form id="menu_form" method="post">
<table align="center" style="margin-top: 15px;">
<input type="hidden" name="id">
<tr>
<td>名稱</td>
<td><input type="text" name="text"></td>
</tr>
<tr>
<td>url</td>
<td><input type="text" name="url"></td>
</tr>
<tr>
<td>父菜單</td>
<td><input type="text" id="parentMenu" name="parent.id" class="easyui-combobox" placeholder="請選擇父菜單"/></td>
</tr>
</table>
</form>
</div>
<!-- 對話框保存取消按鈕 -->
<div id="menu_dialog_bt">
<a class="easyui-linkbutton" iconCls="icon-save" plain="true" id="save">保存</a>
<a class="easyui-linkbutton" iconCls="icon-cancel" plain="true" id="cancel">取消</a>
</div>
4.創建Menu.js
$(function () {
$("#menu_datagrid").datagrid({
url:"/menuList",
columns:[[
{field:'text',title:'名稱',width:1,align:'center'},
{field:'url',title:'跳轉地址',width:1,align:'center'},
{field:'parent',title:'父菜單',width:1,align:'center',formatter:function(value,row,index){
return value?value.text:'';
}
}
]],
fit:true,
rownumbers:true,
singleSelect:true,
striped:true,
pagination:true,
fitColumns:true,
toolbar:'#menu_toolbar'
});
/*
* 初始化新增/編輯對話框
*/
$("#menu_dialog").dialog({
width:300,
height:240,
closed:true,
buttons:'#menu_dialog_bt'
});
/*加載選擇父菜單*/
$("#parentMenu").combobox({
width:150,
panelHeight:'auto',
editable:false,
url:'parentList',
textField:'text',
valueField:'id',
onLoadSuccess:function () { /*數據加載完畢之后回調*/
$("#parentMenu").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
}
});
/*添加菜單*/
$("#add").click(function () {
$("#menu_dialog").dialog("setTitle","添加菜單");
$("#menu_form").form("clear");
$("#menu_dialog").dialog("open");
});
/*保存菜單*/
$("#save").click(function () {
/*判斷當前是添加 還是編輯*/
var id = $("[name='id']").val();
var url;
if(id){
var parent_id = $("[name='parent.id']").val();
if (id == parent_id) {
$.messager.alert("溫馨提示","不能設置自己為父菜單");
return;
}
/*編輯*/
url = "updateMenu";
}else {
/*添加*/
url= "saveMenu";
}
/*提交表單*/
$("#menu_form").form("submit",{
url:url,
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#menu_dialog").dialog("close");
$("#parentMenu").combobox("reload");
$("#menu_datagrid").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
});
});
/*編輯菜單*/
$("#edit").click(function () {
$("#menu_form").form("clear");
/*獲取當前選中的行*/
var rowData = $("#menu_datagrid").datagrid("getSelected");
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*父菜單回顯*/
if(rowData.parent){
rowData["parent.id"] = rowData.parent.id;
}else {/*回顯的placeholder*/
$("#parentMenu").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
}
/*彈出對話框*/
$("#menu_dialog").dialog("setTitle","編輯菜單");
$("#menu_dialog").dialog("open");
/*選中數據的回示*/
$("#menu_form").form("load",rowData);
});
$("#cancel").click(function () {
$("#menu_dialog").dialog("close");
});
$("#del").click(function () {
/*獲取當前選中的行*/
var rowData = $("#menu_datagrid").datagrid("getSelected");
if(!rowData){
$.messager.alert("提示","選擇一行數據進行刪除");
return;
}
/*提醒用戶,是否做刪除操作*/
$.messager.confirm("確認","是否做刪除操作",function (res) {
if(res){
/*做離職操作*/
$.get("/deleteMenu?id="+rowData.id,function (data) {
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*重新加載下拉列表數據*/
$("#parentMenu").combobox("reload");
/*重新加載數據表格*/
$("#menu_datagrid").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
});
}
});
});
});
菜單列表
1.接收菜單請求
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public PageListRes getMenuList(QueryVo vo) {
/*調用mapper 查詢菜單 */
Page<Object> page = PageHelper.startPage(vo.getPage(), vo.getRows());
List<Menu> menus = menuMapper.selectAll();
/*封裝成pageList*/
PageListRes pageListRes = new PageListRes();
pageListRes.setTotal(page.getTotal());
pageListRes.setRows(menus);
return pageListRes;
}
}
2.底層實現
<resultMap id="BaseResultMap" type="com.itlike.domain.Menu" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="text" property="text" jdbcType="VARCHAR" />
<result column="url" property="url" jdbcType="VARCHAR" />
<association property="parent" javaType="com.itlike.domain.Menu" columnPrefix="m_">
<result property="id" column="id"/>
<result property="text" column="text"/>
<result property="url" column="url"/>
</association>
<association property="permission" javaType="com.itlike.domain.Permission">
<result property="pid" column="pid"/>
<result property="pname" column="pname"/>
<result property="presource" column="presource"/>
</association>
<collection property="children" ofType="com.itlike.domain.Menu" select="listChildMenu" column="id"/>
</resultMap>
<!-- /*查詢所有菜單*/-->
<select id="selectAll" resultMap="BaseResultMap" >
SELECT
m1.id,
m1.text,
m1.url,
m2.id as m_id,
m2.text as m_text,
m2.url as m_url
from menu as m1
LEFT JOIN menu as m2
ON m1.parent_id = m2.id
order by m1.id desc
</select>
3.頁面處理
formatter這個屬性屬於列參數,意思就是對當前列的數據進行格式化操作,它是一個函數,有三個參數,value,row,index,
value:代表當前單元格中的值,
row:代表當前行,
index:代表當前行的下標,
可以使用return 返回你想要的數據顯示在單元格中;
formatter:function(value,row,index){
return value?value.text:'';
}
菜單添加
獲取所有父菜單
<tr>
<td>父菜單</td>
<td><input type="text" id="parentMenu" name="parent.id" class="easyui-combobox" placeholder="請選擇父菜單"/></td>
</tr>
$(function () {
/*加載選擇父菜單*/
$("#parentMenu").combobox({
width:150,
panelHeight:'auto',
editable:false,
url:'parentList',
textField:'text',
valueField:'id',
onLoadSuccess:function () { /*數據加載完畢之后回調*/
$("#parentMenu").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
}
});
});
保存菜單
監聽保存點擊
/*保存菜單*/
$("#save").click(function () {
/*判斷當前是添加 還是編輯*/
var id = $("[name='id']").val();
var url;
if(id){
var parent_id = $("[name='parent.id']").val();
if (id == parent_id) {
$.messager.alert("溫馨提示","不能設置自己為父菜單");
return;
}
/*編輯*/
url = "updateMenu";
}else {
/*添加*/
url= "saveMenu";
}
/*提交表單*/
$("#menu_form").form("submit",{
url:url,
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#menu_dialog").dialog("close");
$("#parentMenu").combobox("reload");
$("#menu_datagrid").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
});
});
業務處理
/*保存菜單*/
@RequestMapping("/saveMenu")
@ResponseBody
public AjaxRes saveMenu(Menu menu){
AjaxRes ajaxRes = new AjaxRes();
try {
/*調用業務層,保存菜單*/
menuService.saveMenu(menu);
ajaxRes.setMsg("保存成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
ajaxRes.setSuccess(false);
ajaxRes.setMsg("保存失敗");
System.out.println(e);
}
return ajaxRes;
}
編輯菜單
/*編輯菜單*/
$("#edit").click(function () {
$("#menu_form").form("clear");
/*獲取當前選中的行*/
var rowData = $("#menu_datagrid").datagrid("getSelected");
if(!rowData){
$.messager.alert("提示","選擇一行數據進行編輯");
return;
}
/*父菜單回顯*/
if(rowData.parent){
rowData["parent.id"] = rowData.parent.id;
}else {/*回顯的placeholder*/
$("#parentMenu").each(function(i){
var span = $(this).siblings("span")[i];
var targetInput = $(span).find("input:first");
if(targetInput){
$(targetInput).attr("placeholder", $(this).attr("placeholder"));
}
});
}
/*彈出對話框*/
$("#menu_dialog").dialog("setTitle","編輯菜單");
$("#menu_dialog").dialog("open");
/*選中數據的回示*/
$("#menu_form").form("load",rowData);
});
刪除菜單
監聽刪除按鈕
$("#del").click(function () {
/*獲取當前選中的行*/
var rowData = $("#menu_datagrid").datagrid("getSelected");
if(!rowData){
$.messager.alert("提示","選擇一行數據進行刪除");
return;
}
/*提醒用戶,是否做刪除操作*/
$.messager.confirm("確認","是否做刪除操作",function (res) {
if(res){
/*做離職操作*/
$.get("/deleteMenu?id="+rowData.id,function (data) {
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*重新加載下拉列表數據*/
$("#parentMenu").combobox("reload");
/*重新加載數據表格*/
$("#menu_datagrid").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
});
}
});
});
處理業務邏輯
@Override
public AjaxRes deleteMenu(Long id) {
AjaxRes ajaxRes = new AjaxRes();
try {
/*1.打破菜單關系*/
menuMapper.updateMenuRel(id);
/*2.刪除記錄*/
menuMapper.deleteByPrimaryKey(id);
ajaxRes.setMsg("刪除成功");
ajaxRes.setSuccess(true);
}catch (Exception e){
ajaxRes.setSuccess(false);
ajaxRes.setMsg("刪除失敗");
System.out.println(e);
}
return ajaxRes;
}
<!--根據id刪除菜單-->
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from menu
where id = #{id,jdbcType=BIGINT}
</delete>
<!--根基id更新菜單-->
<update id="updateByPrimaryKey" parameterType="com.itlike.domain.Menu" >
update menu
set text = #{text},
url = #{url},
parent_id = #{parent.id}
where id = #{id}
</update>
菜單權限
在**menu**數據表中, 添加外鍵, 每一個菜單對應一個權限,通過判斷用戶有沒有該權限來控制菜單的顯示隱藏
設置菜單對應權限並取出
1.在menu表中添加權限外鍵
2.在菜單domain當中添加權限對象
tree數據加載
$(function () {
$("#tabs").tabs({
fit:true
})
$('#tree').tree({
url:"/getTreeData",
lines:true,
onSelect: function(node){
/*在添加之前, 做判斷 判斷這個標簽是否存在 */
var exists = $("#tabs").tabs("exists",node.text);
if(exists){
/*存在,就讓它選中*/
$("#tabs").tabs("select",node.text);
}else {
if (node.url !=''&& node.url !=null){
/*如果不存在 ,添加新標簽*/
$("#tabs").tabs("add",{
title:node.text,
/*href:node.attributes.url,*/ /*href 引入的是body當中*/
content:"<iframe src="+node.url+" frameborder='0' width='100%' height='100%'></iframe>",
closable:true
})
}
}
},
onLoadSuccess: function (node, data) {
console.log(data[0].children[0].id);
if (data.length > 0) {
//找到第一個元素
var n = $('#tree').tree('find', data[0].children[0].id);
//調用選中事件
$('#tree').tree('select', n.target);
}
}
});
});
3.查詢菜單時, 把對應權限查出來, 檢查權限
@Override
public List<Menu> getTreeData() {
List<Menu> treeData = menuMapper.getTreeData();
/*
判斷當前用戶有沒有對應的權限
如果沒有就從集合當中移除
*/
/*獲取用戶 判斷用戶是否是管理員 是管理就不需要做判斷*/
Subject subject = SecurityUtils.getSubject();
/*當前的用戶*/
Employee employee = (Employee)subject.getPrincipal();
if (!employee.getAdmin()){
/*做檢驗權限*/
checkPermission(treeData);
}
return treeData;
}
public void checkPermission(List<Menu> menus){
//獲取主體
Subject subject = SecurityUtils.getSubject();
//遍歷所有的菜單及子菜單
Iterator<Menu> iterator = menus.iterator();
while (iterator.hasNext()){
Menu menu = iterator.next();
if (menu.getPermission() !=null){
//判斷當前menu是否有權限對象,如果說沒有 當前遍歷的菜單從集合當中移除
String presource = menu.getPermission().getPresource();
if (!subject.isPermitted(presource)){
//當前遍歷的菜單從集合當中移除
iterator.remove();
continue;
}
}
/*判斷是否有子菜單 有子菜單也要做權限檢驗*/
if (menu.getChildren().size() > 0){
checkPermission(menu.getChildren());
}
}
}
<resultMap id="BaseResultMap" type="com.itlike.domain.Menu" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="text" property="text" jdbcType="VARCHAR" />
<result column="url" property="url" jdbcType="VARCHAR" />
<association property="parent" javaType="com.itlike.domain.Menu" columnPrefix="m_">
<result property="id" column="id"/>
<result property="text" column="text"/>
<result property="url" column="url"/>
</association>
<association property="permission" javaType="com.itlike.domain.Permission">
<result property="pid" column="pid"/>
<result property="pname" column="pname"/>
<result property="presource" column="presource"/>
</association>
<collection property="children" ofType="com.itlike.domain.Menu" select="listChildMenu" column="id"/>
</resultMap>
<!--獲取樹形菜單數據
分步查詢 先查根菜單
根據根菜單的id 查詢出子菜單
-->
<select id="getTreeData" resultMap="BaseResultMap">
select * from menu as m
LEFT JOIN permission as p
on m.permission_id = p.pid where parent_id is null
</select>
<!--根據根菜單的id 查詢出子菜單-->
<select id="listChildMenu" resultMap="BaseResultMap">
select * from menu as m
LEFT JOIN permission as p
on m.permission_id = p.pid where parent_id = #{id}
</select>
系統日志
建立日志表和對應mapper
CREATE TABLE `systemlog` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`optime` datetime DEFAULT NULL,
`ip` varchar(20) DEFAULT NULL,
`function` varchar(255) DEFAULT NULL,
`params` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加攔截器,記錄當前請求的ip
創建本地線程變量
public class RequestUtil {
public static ThreadLocal<HttpServletRequest> local = new ThreadLocal();
public static HttpServletRequest getRequest(){
return local.get();
}
public static void setRequest(HttpServletRequest request){
local.set(request);
}
}
配置攔截器攔截所有請求
<!--配置攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.itlike.interceptor.RequestInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
創建攔截器把當前請求寫入到本地線程變量
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("來到了攔截器...");
RequestUtil.setRequest(request);
return true;
}
}
Systemlog systemlog = new Systemlog();
//設置ip地址 request 添加攔截器 獲取請求對象
HttpServletRequest request = RequestUtil.getRequest();
if (request != null){
String IP = request.getRemoteAddr();
System.out.println(IP);
systemlog.setIp(IP);
}
創建日志切面、在切面中獲取ip、獲取當前執行的方法及參數
public class SystemAspect {
@Autowired
private SystemlogMapper systemlogMapper;
public void writeLog(JoinPoint joinPoint) throws JsonProcessingException {
System.out.println("記錄日志");
//設置時間
Systemlog systemlog = new Systemlog();
systemlog.setOptime(new Date());
//設置ip地址 request 添加攔截器 獲取請求對象
HttpServletRequest request = RequestUtil.getRequest();
if (request != null){
String IP = request.getRemoteAddr();
System.out.println(IP);
systemlog.setIp(IP);
}
//方法
//獲取目標執行方法的全路徑
String name = joinPoint.getTarget().getClass().getName();
//獲取方法名稱
String signature = joinPoint.getSignature().getName();
String func = name+":"+signature;
systemlog.setFunction(func);
//獲取方法參數
String params = new ObjectMapper().writeValueAsString(joinPoint.getArgs());
systemlog.setParams(params);
systemlogMapper.insert(systemlog);
}
}
添加切面
<!-- aop配置 日志配置 -->
<bean id="SystemAspect" class="com.itlike.aspect.SystemAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.itlike.service.*.*(..))" id="servicePoint" />
<aop:aspect ref="SystemAspect">
<aop:after method="writeLog" pointcut-ref="servicePoint"/>
</aop:aspect>
</aop:config>
Excel導入導出
介紹
操作Excel的方式jxl和poi
官方文檔
https://poi.apache.org/components/spreadsheet/quick-guide.html#CellContents
參考文檔
https://www.cnblogs.com/huajiezh/p/5467821.html
依賴
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
導出
// Excel導出
$("#excelOut").click(function () {
window.open('/downloadExcel')
});
@RequestMapping("/downloadExcel")
@ResponseBody
public void downloadExcel(HttpServletResponse response){
try {
System.out.println("---------downloadExcel---------");
//1.從數據庫當中取列表數據
QueryVo queryVo = new QueryVo();
queryVo.setPage(1);
queryVo.setRows(10);
PageListRes plr = employeeService.getEmployee(queryVo);
List<Employee> employees = (List<Employee>)plr.getRows();
//2.創建Excel 寫到excel當中
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("員工數據");
//創建一行
HSSFRow row = sheet.createRow(0);
//設置行的每一列的數據
row.createCell(0).setCellValue("編號");
row.createCell(1).setCellValue("用戶名");
row.createCell(2).setCellValue("入職日期");
row.createCell(3).setCellValue("電話");
row.createCell(4).setCellValue("郵件");
HSSFRow employeeRow = null;
/*取出每一個員工來去設置數據*/
for(int i = 0; i < employees.size(); i++){
Employee employee = employees.get(i);
employeeRow = sheet.createRow(i+1);
employeeRow.createCell(0).setCellValue(employee.getId());
employeeRow.createCell(1).setCellValue(employee.getUsername());
if (employee.getInputtime() !=null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String format = sdf.format(employee.getInputtime());
employeeRow.createCell(2).setCellValue(format);
}else {
employeeRow.createCell(2).setCellValue("");
}
employeeRow.createCell(3).setCellValue(employee.getTel());
employeeRow.createCell(4).setCellValue(employee.getEmail());
}
//3.響應給瀏覽器
String fileName = new String("員工數據.xls".getBytes("utf-8"), "iso8859-1");
response.setHeader("content-Disposition","attachment;filename="+fileName);
wb.write(response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
導入
上傳界面
<div id="excelUpload">
<form method="post" enctype="multipart/form-data">
<tabel>
<tr>
<td><input type="file" name="excel" style="width: 180px; margin-top: 20px; margin-left: 5px;"></td>
<td><a href="javascript:void(0);" id="downloadTml">下載模板</a></td>
</tr>
</tabel>
</form>
</div>
$("#excelUpload").dialog({
width:260,
height:180,
title:"導入Excel",
buttons:[{
text:'保存',
handler:function(){
}
},{
text:'關閉',
handler:function(){
$("#excelUpload").dialog("close");
}
}],
closed:true
})
$("#excelImpot").click(function () {
$("#excelUpload").dialog("open");
});
下載模板
/*下載Excel模板*/
$("#downloadTml").click(function () {
window.open('/downloadExcelTpl')
});
/*下載模板*/
@RequestMapping("downloadExcelTpl")
@ResponseBody
public void downloadExcelTpl(HttpServletRequest request, HttpServletResponse response){
FileInputStream is = null;
try {
String fileName = new String("EmployeeTpl.xls".getBytes("utf-8"), "iso8859-1");
response.setHeader("content-Disposition","attachment;filename="+fileName);
/*獲取文件路徑*/
String realPath = request.getSession().getServletContext().getRealPath("static/ExcelTml.xls");
is = new FileInputStream(realPath);
IOUtils.copy(is,response.getOutputStream());
}catch (Exception e){
e.printStackTrace();
}finally {
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
上傳Excel處理
上傳模板
// 打開上傳窗口
$("#excelIn").click(function () {
$("#excelUpload").dialog("open");
});
// Excel導入
$("#excelUpload").dialog({
width:260,
height:180,
title:"導入Excel",
buttons:[{
text:'保存',
handler:function(){
$("#uploadForm").form("submit",{
url:"uploadExcelFile",
success:function (data) {
data = $.parseJSON(data);
if (data.success){
$.messager.alert("溫馨提示",data.msg);
/*關閉對話框 */
$("#excelUpload").dialog("close");
/*重新加載數據表格*/
$("#dg").datagrid("reload");
} else {
$.messager.alert("溫馨提示",data.msg);
}
}
})
}
},{
text:'關閉',
handler:function(){
$("#excelUpload").dialog("close");
}
}],
closed:true
});
業務處理
/*配置文件上傳解析器 mvc配置當中*/
@RequestMapping("/uploadExcelFile")
@ResponseBody
@RequiresPermissions("employee:add")
public AjaxRes uploadExcelFile(MultipartFile excel){
AjaxRes ajaxRes = new AjaxRes();
try {
ajaxRes.setMsg("導入成功");
ajaxRes.setSuccess(true);
HSSFWorkbook wb = new HSSFWorkbook(excel.getInputStream());
HSSFSheet sheet = wb.getSheetAt(0);
/*獲取最大的行號*/
int lastRowNum = sheet.getLastRowNum();
Row employeeRow = null;
if(1 <= lastRowNum)
{
employeeRow = sheet.getRow(0);
if(!getCellValue(employeeRow.getCell(1)).toString().equals("用戶名"))
throw new Exception("格式錯誤");
else if(!getCellValue(employeeRow.getCell(2)).toString().equals("入職日期"))
throw new Exception("格式錯誤");
else if(!getCellValue(employeeRow.getCell(3)).toString().equals("電話"))
throw new Exception("格式錯誤");
else if(!getCellValue(employeeRow.getCell(4)).toString().equals("郵件"))
throw new Exception("格式錯誤");
}
for (int i=1; i <= lastRowNum; i++){
employeeRow = sheet.getRow(i);
Employee employee = new Employee();
employee.setState(true);
employee.setUsername(getCellValue(employeeRow.getCell(1)).toString());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parse = sdf.parse(getCellValue(employeeRow.getCell(2)).toString());
employee.setInputtime(parse);
employee.setTel(getCellValue(employeeRow.getCell(3)).toString());
employee.setEmail(getCellValue(employeeRow.getCell(4)).toString());
employee.setPassword("123456");
employeeService.saveEmployee(employee);
}
}catch (Exception e){
e.printStackTrace();
ajaxRes.setMsg("導入失敗!"+e.getMessage());
ajaxRes.setSuccess(false);
}
return ajaxRes;
}
private Object getCellValue(Cell cell){
switch (cell.getCellType()) {
case STRING:
return cell.getRichStringCellValue().getString();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue();
} else {
return cell.getNumericCellValue();
}
case BOOLEAN:
return cell.getBooleanCellValue();
case FORMULA:
return cell.getCellFormula();
}
return cell;
}
配置文件上傳解析器
<!--配置文件上傳解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>1040000</value>
</property>
</bean>