SSM+Redis+Shiro+Maven框架搭建及集成应用
引文:
本文主要讲述项目框架搭建时的一些简单的使用配置,教你如何快速进行项目框架搭建。
技术: Spring+SpringMVC+Mybatis+Redis+Shiro+Maven mybatis、redis都是使用spring集成
技术介绍就不再讲述了,话不多说,急忙上代码了。
1、新建Web项目使用Maven 进行项目管理
具体步骤不进行讲述。。。。
主要配置 web.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"> <display-name></display-name> <welcome-file-list>
<welcome-file>index</welcome-file>
</welcome-file-list> <error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/other/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/jsp/other/500.jsp</location>
</error-page> <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>
<listener>
<listener-class>com.idbk.eastevs.webapi.ApplicationListener</listener-class>
</listener> <!-- shiro 过滤器 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 设置true由servlet容器控制filter的生命周期 -->
<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> <!-- springMVC编码过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- xss攻击防御过滤器 -->
<filter>
<filter-name>MyXssFilter</filter-name>
<filter-class>com.idbk.eastevs.webapi.filter.MyXssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyXssFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.htm</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.json</url-pattern>
<url-pattern>*.svg</url-pattern>
<url-pattern>*.txt</url-pattern>
<url-pattern>*.tiff</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.ico</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.jpeg</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.ttf</url-pattern>
<url-pattern>*.woff</url-pattern>
<url-pattern>*.woff2</url-pattern>
<url-pattern>*.eot</url-pattern>
<url-pattern>/include/*</url-pattern>
</servlet-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:beans-springmvc.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>
</web-app>
2、Spring 配置文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <import resource="classpath*:/beans-mybatis.xml" /> <import resource="classpath*:/beans-jedis.xml" /> <import resource="classpath*:/beans-shiro.xml" /> <context:component-scan base-package="com.idbk.eastevs.webapi"></context:component-scan>
<context:component-scan base-package="com.idbk.eastevs.webapi.service.impl"></context:component-scan>
<context:component-scan base-package="com.idbk.eastevs.webapi.server"></context:component-scan> <bean id="app" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<array>
<value>classpath:app.properties</value>
</array>
</property>
</bean> <bean
class="com.idbk.eastevs.webapi.App">
</bean> <!-- 开启定时任务注解识别 -->
<task:annotation-driven/>
</beans>
3、SpringMVC配置文件
<?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-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.idbk.eastevs.webapi.controller"></context:component-scan>
<context:component-scan base-package="com.idbk.eastevs.webapi.controller.*"></context:component-scan> <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean> <!-- 如果springMVC拦截了根目录,这还需要放行资源目录 <mvc:resources mapping="/include/**" location="/include/"
/> --> <!-- 配置文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600" />
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean> <mvc:annotation-driven>
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven> <!-- 配置请求拦截器 -->
<mvc:interceptors>
<!-- 多个拦截器,顺序执行 -->
<!-- 中电联、曹操专车拦截器 -->
<mvc:interceptor>
<!-- /**的意思是所有文件夹及里面的子文件夹 /*是所有文件夹,不含子文件夹 /是web项目的根目录 -->
<!-- <mvc:mapping path="/*/caocao/**" />
<mvc:mapping path="/caocao/**" /> -->
<mvc:mapping path="/**" />
<!-- 不拦截的地址 -->
<mvc:exclude-mapping path="/login" />
<bean id="CoreInterceptor" class="com.idbk.eastevs.webapi.CoreInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
4、Spring-Mybatis配置文件
<?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: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-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <context:component-scan base-package="com.idbk.eastevs.webapi.pojo" />
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath*:jdbc.properties"
ignore-unresolvable="true" /> <!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" /> <!-- 可同时连接的最大的连接数 -->
<property name="maxActive" value="${jdbc.maxActive}" />
<!-- 最大的空闲的连接数 -->
<property name="maxIdle" value="${jdbc.maxIdle}" />
<!-- 最小的空闲的连接数,低于这个数量会被创建新的连接,默认为0 -->
<property name="minIdle" value="${jdbc.minIdle}" />
<!-- 连接池启动时创建的初始化连接数量,默认值为0 -->
<property name="initialSize" value="${jdbc.initialSize}" />
<!-- 等待连接超时时间,毫秒,默认为无限 -->
<property name="maxWait" value="${jdbc.maxWait}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
<!-- 打开removeAbandoned功能 -->
<property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
<property name="validationQuery" value="SELECT 1" />
</bean> <!-- 会话工厂bean sqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 扫描mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 别名 -->
<property name="typeAliasesPackage" value="com.idbk.eastevs.dal.entity"></property>
<!-- sql映射文件路径 -->
<property name="mapperLocations"
value="classpath*:com/idbk/eastevs/dal/entity/mapper/*Mapper.xml"></property>
</bean> <!-- 自动扫描对象关系映射 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!-- 指定要自动扫描接口的基础包,实现接口 -->
<property name="basePackage" value="com.idbk.eastevs.dal.entity.mapper" />
</bean> <!-- 声明式事务管理 -->
<!--定义事物管理器,由spring管理事务 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!--支持注解驱动的事务管理,指定事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager" /> <!-- 自定义sqlSessionFactory 工具类 -->
<bean id="SqlManager" class="com.idbk.eastevs.dal.SqlManager">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
5、Mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 打印操作日志 -->
<setting name="logImpl" value="LOG4J" />
</settings> <!-- 分页插件 -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 方言 -->
<property name="helperDialect" value="mysql" />
<!-- 该参数默认为false,设置为true时,使用RowBounds分页会进行count查询 -->
<!-- <property name="rowBoundsWithCount" value="true" /> -->
</plugin>
</plugins>
</configuration>
6、Spring-Redis配置文件
<?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"
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-4.1.xsd"
default-lazy-init="false"> <!-- 加载配置文件 -->
<context:property-placeholder location="classpath*:jedis.properties" ignore-unresolvable="true"/> <!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 保留空闲连接数 -->
<property name="minIdle" value="${redis.minIdle}" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean> <!-- Spring-redis连接池管理工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<!-- IP地址 -->
<property name="hostName" value="${redis.host}" />
<!-- 端口号 -->
<property name="port" value="${redis.port}" />
<!-- 密码 -->
<property name="password" value="${redis.password}" />
<!-- 超时时间 默认2000-->
<property name="timeout" value="${redis.timeout}" />
<!-- 连接池配置引用 -->
<property name="poolConfig" ref="poolConfig" />
<!-- usePool:是否使用连接池 -->
<property name="usePool" value="true"/>
</bean> <!-- redis 操作模板,集成序列化和连接管理 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean> <!--自定义redis工具类,在需要缓存的地方注入此类 -->
<bean id="jedis" class="com.idbk.eastevs.dal.jedis.Jedis">
<property name="redisTemplate" ref="redisTemplate" />
</bean> </beans>
7、jdbc配置文件
#mysql jdbc
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=${pom.jdbc.url}
jdbc.username=${pom.jdbc.username}
jdbc.password=${pom.jdbc.password} jdbc.initialSize=1
jdbc.maxActive=60
jdbc.maxIdle=60
jdbc.minIdle=5
jdbc.maxWait=30000 jdbc.removeAbandoned:true
jdbc.removeAbandonedTimeout:1800 jdbc.timeBetweenEvictionRunsMillis:60000
jdbc.minEvictableIdleTimeMillis:300000
8、jedis配置文件
redis.host=${pom.redis.host}
redis.port=${pom.redis.port}
redis.password=${pom.redis.password}
redis.minIdle=10
redis.maxTotal=50
redis.maxWaitMillis=3000
redis.blockWhenExhausted=true
redis.testOnBorrow=true
redis.timeout=5000
9、log4j配置文件
#INFO WARN ERROR DEBUG
log4j.rootLogger=ERROR,console,file log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss,SSS}] [%p] [%t] [%C.%M(%L)] %m%n%n log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=/home/tomcat/logall/WebApi_logs/WebApi.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%d{yyyy-MM-dd HH\:mm\:ss,SSS}] [%p] [%t] [%C.%M(%L)] %m%n%n
log4j.appender.file.encoding=utf-8 log4j.logger.com=ERROR
log4j.logger.org=ERROR
log4j.logger.freemarker=ERROR
log4j.logger.net=ERROR
log4j.logger.com.idbk=DEBUG log4j.logger.org.springframework=DEBUG
log4j.logger.org.apache.ibatis=DEBUG
10、Spring-Shiro配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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"> <!-- 自定义认证和授权管理 -->
<bean id="customRealm" class="com.idbk.eastevs.webapi.shiro.CustomRealm"></bean> <!-- 会话Cookie模板,maxAge=-1表示浏览器关闭时失效此Cookie -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="-1"/>
</bean>
<!-- rememberme相关 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<property name="httpOnly" value="true" />
<property name="maxAge" value="604800" /><!-- 7天 -->
</bean> <!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('EASTEVShua1314520rsdag==')}"/>
<property name="cookie" ref="rememberMeCookie"/>
</bean> <!-- 基于Form表单的身份验证过滤器 -->
<!-- <bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<property name="rememberMeParam" value="rememberMe"/>
</bean> --> <!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID -->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<!-- 设置Cookie名字, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
<property name="name" value="SHIRO-COOKIE"/>
<!-- JSESSIONID的path为/用于多个系统共享JSESSIONID -->
<!-- <property name="path" value="/"/> -->
<!-- 浏览器中通过document.cookie可以获取cookie属性,设置了HttpOnly=true,在脚本中就不能的到cookie,可以避免cookie被盗用 -->
<property name="httpOnly" value="true"/>
</bean> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO" />
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO"/>
<property name="sessionIdCookie" ref="simpleCookie"/>
<!-- 全局的会话信息时间,,单位为毫秒 -->
<property name="globalSessionTimeout" value="1800000"/>
<!-- 检测扫描信息时间间隔,单位为毫秒-->
<property name="sessionValidationInterval" value="60000"/>
<!-- 是否开启扫描 -->
<property name="sessionValidationSchedulerEnabled" value="false"/>
<!-- 去掉URL中的JSESSIONID -->
<property name="sessionIdUrlRewritingEnabled" value="true"/>
</bean> <!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm"></property>
<property name="rememberMeManager" ref="rememberMeManager"/>
<property name="sessionManager" ref="sessionManager" />
</bean> <!-- Shiro生命周期处理器,保证实现了Shiro内部lifecycle函数的bean执行-->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 自定义shiro的filter -->
<bean id="shiroAjaxFilter" class="com.idbk.eastevs.webapi.shiro.ShiroAjaxFilter" /> <!-- 配置ShiroFilter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<!-- 登入页面 -->
<property name="loginUrl" value="/login"></property>
<property name="successUrl" value="/index"></property>
<!-- 未授权的跳转 -->
<property name="unauthorizedUrl" value="other/unauthorized.jsp"/>
<property name="filterChainDefinitions">
<value>
/caocao/** = anon
/evcs/** = anon
/resource/** = anon
/system/** = anon
/pay/** = anon /include/** = anon
/login = anon
/logout = logout
/captcha = anon
/unauthorized = anon
/ajax/login = anon
/ajax/register = anon
/ajax/** = shiroAjaxFilter
/** = user
</value>
</property>
</bean> <!-- 开启Shiro Spring AOP 权限注解的支持 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> </beans>
11、自定义CustomRealm
package com.idbk.eastevs.webapi.shiro; import org.apache.log4j.Logger;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired; import com.idbk.eastevs.webapi.App; /**
* @Author Tophua
* @Date 2018年12月4日
* @Description 自定义shiro认证和授权处理
*/
public class CustomRealm extends AuthorizingRealm { private static final Logger Log = Logger.getLogger(CustomRealm.class); @Autowired
App app; /**
* 授权、权限验证
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// Integer userId = (Integer) principals.getPrimaryPrincipal();
// 数据库获取权限 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//加入角色
info.addRole("super");
// info.setRoles(roles);
// 加入权限
info.addStringPermission("*");
// info.setStringPermissions(stringPermissions);
return info;
} /**
* 身份认证、登录
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken _token = (UsernamePasswordToken) token;
String username = _token.getUsername();
String password = String.valueOf(_token.getPassword());
/**
* 做数据库登录验证,在此只先提供超级用户登录
*
*/
if (password.equals(app.getSuperPassword())) {
Log.info("超级用户登录,用户名:" + username);
} else {
throw new AuthenticationException();
} //此处无需比对,比对的逻辑Shiro会做,我们只需返回一个和令牌相关的正确的验证信息
//说白了就是第一个参数填登录用户名,第二个参数填合法的登录密码(可以是从数据库中取到的)
//这样一来,在随后的登录页面上就只有这里指定的用户和密码才能通过验证
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, getName());
return info;
} }
12、登录模型
package com.idbk.eastevs.webapi.controller.inner.ajax; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import com.idbk.eastevs.webapi.App;
import com.idbk.eastevs.webapi.json.Result; /**
* @Author Tophua
* @Date 2018年11月30日
* @Description
*/
@RestController
@RequestMapping("/ajax")
public class LoginMngController { @Autowired
App app; @RequestMapping("/login")
private Result login(
@RequestParam("loginName") String loginName,
@RequestParam("password") String password,
@RequestParam(name="rememberMe",required=false,defaultValue="false") boolean rememberMe
) {
UsernamePasswordToken token = new UsernamePasswordToken(loginName, password, rememberMe);
Subject subject = SecurityUtils.getSubject();
try
{
subject.login(token);
return Result.ok();
}
catch (UnknownAccountException e)
{
return Result.failed("账号不存在");
}
catch (LockedAccountException e)
{
return Result.failed("账号不可用");
}
catch (AuthenticationException e)
{
}
return Result.failed("账号或密码错误");
}
}
13、全局异常管理
package com.idbk.eastevs.webapi; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.ResponseBody; import com.idbk.eastevs.webapi.json.Result; /**
* @Author Tophua
* @Date 2018年12月5日
* @Description 内部异常处理
*/
@ControllerAdvice("com.idbk.eastevs.webapi.controller.inner")
public class SysInnerExceptionHandle { private static final Logger LOG = Logger.getLogger(SysInnerExceptionHandle.class); @Autowired
App app; @ModelAttribute("app")
public App getMyAppInfo() {
return app;
} @ModelAttribute("user")
public String getUser() {
Subject subject = SecurityUtils.getSubject();
return (String) subject.getPrincipal();
} @ModelAttribute("menu")
public String getMenu(HttpServletRequest request) {
return request.getRequestURI();
} /**
* 权限验证失败时异常
* @param e
* @return
*/
@ExceptionHandler(UnauthorizedException.class)
String handleUnauthorizedException(UnauthorizedException e) {
LOG.error(e.getMessage(), e);
return "other/unauthorized.jsp";
} @ExceptionHandler(Exception.class)
@ResponseBody
Result handleException(Exception e) {
LOG.error(e.getMessage(), e);
return Result.sysBusy();
}
}
总结:
现多项目多用此技术,常用配置足以满足项目要求。如需进一步了解,建议看官方文档!
至此结束!
多多关注!
Shiro参考:https://www.iteye.com/blogs/subjects/shiro
SSM+Redis+Shiro+Maven框架搭建及集成应用的更多相关文章
- (一)springmvc+spring+mybatis+maven框架搭建
(一)springmvc+spring+mybatis+maven框架搭建 1.说明 工作之余,为了学习点东西.先搭建个框架. 以后要往里面加东西,比如rabbitMQ.redis.shiro等. 也 ...
- Hudson+Maven+Svn搭建持续集成环境
Hudson+Maven+Svn搭建持续集成环境 博客分类: 配置管理 mavenSVNTomcat项目管理配置管理 一.所用开发工具 1. Hudson: Hudson 是一种革命性的开放源码 ...
- Docker+Jenkins+Maven+SVN搭建持续集成环境
Docker+Jenkins+Maven+SVN搭建持续集成环境 环境拓扑图(实验项目使用PHP环境) 发布流程图 环境说明 系统:Centos 7.4 x64 Docker版本:18.09.0 Ma ...
- 从零开始--Spring项目整合(1)使用maven框架搭建项目
这些年一直在用spring的框架搭建项目,现在开始我们从零开始利用Spring框架来搭建项目,目前我能想到有Spring.SpringMVC.SpringJDBC.Mybatis.WebSockt.R ...
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...
- SSM(Spring +SpringMVC + Mybatis)框架搭建
SSM(Spring +SpringMVC + Mybatis)框架的搭建 最近通过学习别人博客发表的SSM搭建Demo,尝试去搭建一个简单的SSMDemo---实现的功能是对用户增删改查的操作 参考 ...
- Spring4 mvc+maven 框架搭建(1)
这篇博客其实很早就应该写,早在半年前,因为对SpringMVC感兴趣,便自学了一下Spring.一段时间的学习后,对Spring有了一个基本的了解,于是想着自己动手搭建一个SpringMvc的框架出来 ...
- 基于Maven的ssm(spring+springMvc+Mybatis)框架搭建
前言 本demo是在idea下搭建的maven项目,数据库使用Mysql,jdk版本是1.8.0_171,ideal:2017.3.5 一.新建项目 1.file->new->porjec ...
- Jenkins+Maven+Git搭建持续集成和自动化部署的配置手记
前言 持续集成这个概念已经成为软件开发的主流,可以更频繁的进行测试,尽早发现问题并提示.自动化部署就更不用说了,可以加快部署速度,并可以有效减少人为操作的失误.之前一直没有把这个做起来,最近的新 ...
随机推荐
- 使用原生方法从kafka消费消息
kafka最早是linkedin开发的一套高性能类队列结构,具有发布—订阅功能.现在是apache的项目之一.支持很多种客户端从其中进行consume,网上也有许多第三方的客户端(注1),但下面我们只 ...
- jzoj5894
先前綴和一發,問題表示求[0-l2][0-r2]滿足條件的數的個數 假設可以把某一個數拆分成[前面任意個數][00-0-11-1(個數相同)]的區間 那麼問題會簡單的多,因為任意一個a位的整數分別xo ...
- Depth-first Search-690. Employee Importance
You are given a data structure of employee information, which includes the employee's unique id, his ...
- servlet转发与重定向区别
servlet转发与重定向 HttpServletRequest: 表示浏览器向服务器发送的请求报文,由Tomcat创建然后作为参数传递给我们doget,dopost方法. 功能:getParam ...
- 了解ORACLE培训OCA-OCP-OCM课程表
了解ORACLE培训OCA-OCP-OCM课程表考试号: OCA 1Z0-007$125 Oracle Database 10g:SQL Fundamentals 本课程培养学生必要的SQ ...
- 【DB2】关闭表的日志功能
2018.11.19 客户遇到一个问题,在import数据的时候,产生了大量的日志,客户的数据库是HADR模式,通过评估,这几张表是可以允许在备库上不查询的,表中的数据时临时的. 方案一:修改脚本,将 ...
- 【C#小知识】C#中一些易混淆概念总结(四)---------解析Console.WriteLine() 分类: C# 2014-02-05 17:18 1060人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结 [C#小知识]C#中一些易混淆概念总结(二) [C#小知识]C#中一些易混淆概念总结(三) ------------------------------ ...
- invokespecial与invokevirtual指令的区别
package com.test19; class Father { public void publicMethod() { privateMethod(); // this是Son对象,调用Fat ...
- 关于类型Type
每一个JC语法节点都含有type属性,因为做为所有JC语法节点的父节点JCTree含有type属性.其继承关系如下图. 下面看一下Type类的定义及重要的属性. public class Type i ...
- unity 图片 粉碎效果 破碎效果
效果: 点击按钮后: 这些碎片具有物理碰撞效果,下面会有隐形的支柱垫着碎片,n秒后支柱消失,碎片落下 当然你也可以控制生成的碎片,让他们从下而上一块一块地落下 插件源码: https://github ...