Merge remote-tracking branch 'origin/书籍中心zgj' into 书籍中心zgj

书籍中心zgj
zgj 8 months ago
commit 1575a5baf0

@ -9,22 +9,39 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.tamguo.modules.sys.interceptor.SettingsInterceptor; import com.tamguo.modules.sys.interceptor.SettingsInterceptor;
// 表明这是一个Spring的配置类Spring会扫描这个类并处理其中实现了WebMvcConfigurer接口的方法用于对Spring Web相关功能进行配置比如添加拦截器、配置资源处理器等。
@Configuration @Configuration
public class WebConfig implements WebMvcConfigurer { public class WebConfig implements WebMvcConfigurer {
// 使用@Value注解从配置文件通常是application.properties或application.yml等中读取名为"file.storage.path"的配置项的值并注入到fileStoragePath变量中
// 该变量用于存储文件存储的路径信息,后续在配置资源处理器时会用到这个路径来指定静态资源的实际存放位置。
@Value("${file.storage.path}") @Value("${file.storage.path}")
private String fileStoragePath; private String fileStoragePath;
// 通过@Autowired注解自动注入SettingsInterceptor实例SettingsInterceptor应该是自定义的拦截器类
// 用于在请求处理过程中进行一些通用的业务逻辑处理,比如权限验证、设置一些通用的请求参数等,具体功能取决于该拦截器类的实现逻辑。
@Autowired @Autowired
private SettingsInterceptor settingsInterceptor; private SettingsInterceptor settingsInterceptor;
/**
* WebMvcConfigureraddInterceptorsSpring Web
* SettingsInterceptor"/**"
*
*/
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(settingsInterceptor).addPathPatterns("/**"); registry.addInterceptor(settingsInterceptor).addPathPatterns("/**");
} }
@Override /**
public void addResourceHandlers(ResourceHandlerRegistry registry) { * WebMvcConfigureraddResourceHandlersSpring Web使访
registry.addResourceHandler("/files/**").addResourceLocations("file:"+fileStoragePath); * "/files/**"addResourceLocations
} * "file:" + fileStoragePathfileStoragePath
* "/files/"URL访
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/files/**").addResourceLocations("file:" + fileStoragePath);
}
} }

@ -10,24 +10,43 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* , * MyBatis PlusMetaObjectHandler
*
* @ComponentSpring便
*/ */
//@Component //@Component
public class MyMetaObjectHandler extends MetaObjectHandler { public class MyMetaObjectHandler extends MetaObjectHandler {
// 创建一个名为logger的静态常量用于记录日志LoggerFactory根据当前类的类型MyMetaObjectHandler.class创建对应的Logger实例方便后续在代码中输出相关的日志信息。
protected final static Logger logger = LoggerFactory.getLogger(MyMetaObjectHandler.class); protected final static Logger logger = LoggerFactory.getLogger(MyMetaObjectHandler.class);
/**
* insertFill
*
* @param metaObject MyBatisMetaObject
*/
@Override @Override
public void insertFill(MetaObject metaObject) { public void insertFill(MetaObject metaObject) {
setFieldValByName("createBy", ShiroUtils.getUserCode() , metaObject); // 使用MyBatis Plus提供的方法setFieldValByName通过字段名"createBy"将值从ShiroUtils.getUserCode()获取可能是获取当前用户的代码等标识信息设置到metaObject所对应的实体对象中实现自动填充创建者字段的功能。
setFieldValByName("updateBy", ShiroUtils.getUserCode() , metaObject); setFieldValByName("createBy", ShiroUtils.getUserCode(), metaObject);
setFieldValByName("createDate", new Date() , metaObject); // 同样的方式,为更新者字段"updateBy"也设置为当前用户的代码,因为在插入时,创建者和首次更新者可能是同一个人,具体可根据业务逻辑调整。
setFieldValByName("updateDate", new Date() , metaObject); setFieldValByName("updateBy", ShiroUtils.getUserCode(), metaObject);
// 通过字段名"createDate"将当前的日期时间new Date()获取当前系统时间)设置到实体对象中,自动填充创建时间字段。
setFieldValByName("createDate", new Date(), metaObject);
// 为更新时间字段"updateDate"也设置为当前系统时间,插入操作时可以认为首次更新时间就是创建时间,后续更新操作会再次触发更新时间的更新逻辑。
setFieldValByName("updateDate", new Date(), metaObject);
} }
/**
* updateFill
*
* @param metaObject MyBatisMetaObject
*/
@Override @Override
public void updateFill(MetaObject metaObject) { public void updateFill(MetaObject metaObject) {
setFieldValByName("updateBy", ShiroUtils.getUserCode() , metaObject); // 使用setFieldValByName方法通过字段名"updateBy"将值从ShiroUtils.getUserCode()获取当前用户代码设置到metaObject对应的实体对象中自动填充更新者字段确保记录更新操作是谁执行的。
setFieldValByName("updateDate", new Date() , metaObject); setFieldValByName("updateBy", ShiroUtils.getUserCode(), metaObject);
// 通过字段名"updateDate"将当前系统时间new Date()获取)设置到实体对象中,自动更新更新时间字段,保证更新时间的准确性。
setFieldValByName("updateDate", new Date(), metaObject);
} }
} }

@ -5,23 +5,35 @@ import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
//这个类用配置redis服务器的连接 // 这个类用于配置redis服务器的连接通过该类可以设置与Redis服务器建立连接所需的各项参数如主机名、端口、密码等并创建对应的Jedis连接工厂对象。
@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 1800) @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
// @EnableRedisHttpSession注解用于启用Spring Session基于Redis的HTTP会话管理功能。
// maxInactiveIntervalInSeconds属性设置了会话的最大非活动时间间隔这里设置为1800秒即30分钟表示如果一个会话在30分钟内没有任何活动将会被视为过期并失效。
public class SessionConfig { public class SessionConfig {
// 使用@Value注解从配置文件通常是application.properties或application.yml等中读取名为"redis.hostname"的配置项的值并注入到HostName变量中该变量用于存储Redis服务器的主机名。
@Value("${redis.hostname}") @Value("${redis.hostname}")
String HostName; String HostName;
// 同样通过@Value注解从配置文件中读取"redis.port"配置项的值注入到Port变量中用于存储Redis服务器的端口号。
@Value("${redis.port}") @Value("${redis.port}")
int Port; int Port;
// 从配置文件读取"redis.password"配置项的值注入到password变量中用于存储连接Redis服务器所需的密码如果有的话
@Value("${redis.password}") @Value("${redis.password}")
String password; String password;
// @SuppressWarnings("deprecation")注解用于抑制编译器对于使用已过时方法或类等情况的警告提示。
// 这里定义了一个名为connectionFactory的方法并使用@Bean注解将该方法返回的对象注册为Spring容器中的一个Bean该Bean就是Jedis连接工厂对象用于创建与Redis服务器的连接。
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Bean @Bean
public JedisConnectionFactory connectionFactory() { public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory(); JedisConnectionFactory connection = new JedisConnectionFactory();
// 设置Jedis连接工厂对象的端口号使用之前从配置文件中读取并注入的Port变量来指定具体的端口值。
connection.setPort(Port); connection.setPort(Port);
// 设置Jedis连接工厂对象的主机名使用HostName变量来指定连接的Redis服务器的主机名称。
connection.setHostName(HostName); connection.setHostName(HostName);
// 设置Jedis连接工厂对象的密码通过password变量来传入连接Redis服务器所需的密码确保连接的安全性如果有密码要求的话
connection.setPassword(password); connection.setPassword(password);
return connection; return connection;
} }

@ -2,8 +2,14 @@ package com.tamguo.config.redis;
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
//初始化Session配置 // 这个类用于初始化Session配置它继承自Spring框架提供的AbstractHttpSessionApplicationInitializer类
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer{ // 通过继承该抽象类并实现相应的构造函数等逻辑来协助完成与Http Session相关配置的初始化工作确保Session相关功能能够正常启用和配置生效。
public class SessionInitializer extends AbstractHttpSessionApplicationInitializer {
// 定义构造函数在创建SessionInitializer类的实例时会调用该构造函数。
// 这里调用父类AbstractHttpSessionApplicationInitializer的构造函数并传入SessionConfig.class作为参数。
// 其目的是告知Spring框架要使用SessionConfig这个配置类来初始化Http Session相关的配置
// 使得在整个应用启动过程中基于之前在SessionConfig类中定义的如Redis连接等相关配置能够正确地应用到Http Session的管理中从而保证Session功能的正常运行。
public SessionInitializer() { public SessionInitializer() {
super(SessionConfig.class); super(SessionConfig.class);
} }

@ -11,15 +11,24 @@ import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreato
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
// 表明这是一个Spring的配置类Spring会扫描这个类并处理其中带有@Bean注解的方法将这些方法返回的对象注册为Spring容器中的Bean用于配置Shiro相关的功能组件。
@Configuration @Configuration
public class ShiroConfiguration { public class ShiroConfiguration {
// 创建一个静态的LinkedHashMap用于存储Shiro的过滤链定义。LinkedHashMap可以保证元素的插入顺序便于按照定义顺序来匹配过滤规则。
// 键为请求的URL路径模式值为对应的访问控制规则如"anon"表示匿名可访问,"authc"表示需要认证后才能访问等)。
private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); private static Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 定义一个名为"shiroRealm"的Bean该Bean返回一个UserRealm实例。UserRealm通常是自定义的实现了Shiro的Realm接口的类
// 用于从数据源如数据库中获取用户认证和授权相关的信息是Shiro进行身份验证和权限验证的核心逻辑所在。
@Bean(name = "shiroRealm") @Bean(name = "shiroRealm")
public UserRealm getShiroRealm() { public UserRealm getShiroRealm() {
return new UserRealm(); return new UserRealm();
} }
// 定义一个名为"shiroEhcacheManager"的Bean用于创建并配置EhCacheManager实例。EhCacheManager是Shiro用于缓存的管理器
// 在这里通过设置缓存配置文件classpath:ehcache-shiro.xml来指定缓存的相关配置信息比如缓存的存活时间、缓存区域划分等
// 以提高Shiro在处理认证和授权过程中的性能避免频繁地从数据源获取相同的数据。
@Bean(name = "shiroEhcacheManager") @Bean(name = "shiroEhcacheManager")
public EhCacheManager getEhCacheManager() { public EhCacheManager getEhCacheManager() {
EhCacheManager em = new EhCacheManager(); EhCacheManager em = new EhCacheManager();
@ -27,11 +36,17 @@ public class ShiroConfiguration {
return em; return em;
} }
// 定义一个名为"lifecycleBeanPostProcessor"的Bean创建并返回一个LifecycleBeanPostProcessor实例。
// LifecycleBeanPostProcessor是Shiro提供的一个用于管理Shiro相关Bean生命周期的后置处理器
// 它能确保Shiro的各种组件如Realm、SecurityManager等在Spring容器中的生命周期方法如初始化、销毁等得到正确调用。
@Bean(name = "lifecycleBeanPostProcessor") @Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor(); return new LifecycleBeanPostProcessor();
} }
// 定义一个名为"defaultAdvisorAutoProxyCreator"的Bean创建并配置DefaultAdvisorAutoProxyCreator实例。
// 它是Spring AOP中的一个自动代理创建器用于根据Advisor通知器包含了切点和增强逻辑来自动创建代理对象
// 设置proxyTargetClass为true表示使用基于类的代理方式而不是基于接口的代理这样可以确保Shiro的安全切面等逻辑能够正确应用到目标对象上。
@Bean @Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator(); DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
@ -39,6 +54,9 @@ public class ShiroConfiguration {
return daap; return daap;
} }
// 定义一个名为"securityManager"的Bean创建并返回一个DefaultWebSecurityManager实例它是Shiro在Web环境下的核心安全管理器。
// 在这里配置了它所使用的Realm通过调用getShiroRealm()方法获取自定义的UserRealm实例以及缓存管理器通过调用getEhCacheManager()方法获取EhCacheManager实例
// 负责协调Shiro的各个组件如认证、授权、会话管理等功能的执行是整个Shiro安全框架在应用中的核心控制组件。
@Bean(name = "securityManager") @Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager() { public DefaultWebSecurityManager getDefaultWebSecurityManager() {
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager(); DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
@ -47,6 +65,9 @@ public class ShiroConfiguration {
return dwsm; return dwsm;
} }
// 定义一个名为"authorizationAttributeSourceAdvisor"的Bean创建并返回一个AuthorizationAttributeSourceAdvisor实例。
// 它是Shiro与Spring AOP结合的一个通知器用于在方法级别进行权限控制通过设置安全管理器调用getDefaultWebSecurityManager()方法获取),
// 可以基于方法上的权限注解(如@RequiresPermissions等来自动进行权限验证实现细粒度的访问控制。
@Bean @Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
@ -54,12 +75,20 @@ public class ShiroConfiguration {
return new AuthorizationAttributeSourceAdvisor(); return new AuthorizationAttributeSourceAdvisor();
} }
// 定义一个名为"shiroFilter"的Bean创建并返回一个ShiroFilterFactoryBean实例它是Shiro在Web应用中用于配置过滤链的核心组件。
// 首先设置了安全管理器通过调用getDefaultWebSecurityManager()方法获取),确定了整个过滤链的安全控制基础。
// 然后设置了登录页面的URL"/login"),即当用户未认证访问受保护资源时,会被重定向到该登录页面进行认证操作。
// 接着设置了认证成功后的跳转页面URL"/index"),用于用户成功登录后自动跳转到相应的页面。
// 之后通过往filterChainDefinitionMap中添加一系列的URL路径模式和对应的访问控制规则来定义哪些资源是匿名可访问如各种前端框架相关的静态资源路径哪些资源需要认证访问"/**"表示除了前面配置的匿名可访问路径外的其他所有路径)。
// 最后将配置好的过滤链定义Map设置到ShiroFilterFactoryBean中使其生效从而实现整个Web应用基于Shiro的访问控制。
@Bean(name = "shiroFilter") @Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean() { public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager()); shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index"); shiroFilterFactoryBean.setSuccessUrl("/index");
// 以下是配置各种静态资源路径为匿名可访问,这些资源通常是前端框架的相关文件,不需要进行认证就能访问,方便页面正常加载和展示。
filterChainDefinitionMap.put("/jquery/**", "anon"); filterChainDefinitionMap.put("/jquery/**", "anon");
filterChainDefinitionMap.put("/adminlte/**", "anon"); filterChainDefinitionMap.put("/adminlte/**", "anon");
filterChainDefinitionMap.put("/bootstrap/**", "anon"); filterChainDefinitionMap.put("/bootstrap/**", "anon");
@ -87,10 +116,11 @@ public class ShiroConfiguration {
filterChainDefinitionMap.put("/favicon.ico", "anon"); filterChainDefinitionMap.put("/favicon.ico", "anon");
filterChainDefinitionMap.put("/global.min.js", "anon"); filterChainDefinitionMap.put("/global.min.js", "anon");
// 将除了上述配置的匿名可访问路径之外的所有请求路径都设置为需要认证访问("authc"表示需要认证实现了对整个Web应用的基本访问控制。
filterChainDefinitionMap.put("/**", "authc"); filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean; return shiroFilterFactoryBean;
} }
} }

@ -17,55 +17,66 @@ import com.tamguo.modules.sys.model.enums.SysUserStatusEnum;
import com.tamguo.modules.sys.service.ISysUserService; import com.tamguo.modules.sys.service.ISysUserService;
/** /**
* * `UserRealm` `AuthorizingRealm`Shiro
* Shiro
* *
*/ */
public class UserRealm extends AuthorizingRealm { public class UserRealm extends AuthorizingRealm {
// 通过Spring的依赖注入@Autowired注解自动注入 `ISysUserService` 接口的实现类实例,
// 用于后续从业务层获取用户相关信息,比如根据用户名查询用户实体对象等操作,实现与业务逻辑层的交互,以完成认证和授权的具体业务判断。
@Autowired @Autowired
private ISysUserService sysUserService; private ISysUserService sysUserService;
/** /**
* () * ()
* Shiro访Shiro
* `SimpleAuthorizationInfo` `info` Shiro
*/ */
@Override @Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// info.setStringPermissions(permsSet); // info.setStringPermissions(permsSet); // 此处可能原本计划设置用户的权限集合,但目前未实现具体逻辑,可能需要根据实际业务从数据库查询用户权限并设置进来
return info; return info;
} }
/** /**
* () * ()
*/ * ShiroShiro
@Override */
protected AuthenticationInfo doGetAuthenticationInfo( @Override
AuthenticationToken token) throws AuthenticationException { protected AuthenticationInfo doGetAuthenticationInfo(
String username = (String) token.getPrincipal(); AuthenticationToken token) throws AuthenticationException {
// 从传入的 `AuthenticationToken` 对象中获取用户名(通常作为登录的标识),这里将其强制转换为 `String` 类型,因为在实际应用中一般用户名是以字符串形式存在的。
String username = (String) token.getPrincipal();
// 从 `AuthenticationToken` 对象中获取用户输入的密码,并将其从字符数组转换为 `String` 类型,以便后续与数据库中存储的密码进行比对。
String password = new String((char[]) token.getCredentials()); String password = new String((char[]) token.getCredentials());
//查询用户信息 // 通过注入的 `ISysUserService` 实例,调用其 `queryByLoginCode` 方法,根据用户名去查询对应的用户信息,该方法会与业务层的数据访问层交互,从数据库中获取用户实体对象(如果存在的话)。
SysUserEntity user = sysUserService.queryByLoginCode(username); SysUserEntity user = sysUserService.queryByLoginCode(username);
//账号不存在 // 如果查询到的用户对象为 `null`,说明输入的用户名不存在,此时抛出 `UnknownAccountException` 异常Shiro会捕获该异常并根据配置进行相应的处理比如提示用户账号不存在等)。
if(user == null) { if (user == null) {
throw new UnknownAccountException("账号或密码不正确"); throw new UnknownAccountException("账号或密码不正确");
} }
//密码错误 // 将用户输入的密码与从数据库中查询到的用户实体对象中存储的密码进行比对,如果不一致,说明密码错误,抛出 `IncorrectCredentialsException` 异常Shiro同样会根据配置进行处理例如提示密码错误等
if(!password.equals(user.getPassword())) { if (!password.equals(user.getPassword())) {
throw new IncorrectCredentialsException("账号或密码不正确"); throw new IncorrectCredentialsException("账号或密码不正确");
} }
//账号锁定 // 判断用户账号的状态,如果状态为 `SysUserStatusEnum.LOCKED`(表示账号已被锁定,这里 `SysUserStatusEnum` 应该是一个自定义的枚举类型,用于表示用户账号的不同状态),
if(user.getStatus() == SysUserStatusEnum.LOCKED){ // 则抛出 `LockedAccountException` 异常告知用户账号已被锁定需联系管理员处理Shiro会相应地进行处理比如禁止登录等操作。
throw new LockedAccountException("账号已被锁定,请联系管理员"); if (user.getStatus() == SysUserStatusEnum.LOCKED) {
throw new LockedAccountException("账号已被锁定,请联系管理员");
} }
// 如果上述验证都通过,创建一个 `SimpleAuthenticationInfo` 对象,将查询到的用户对象、密码以及当前 `Realm` 的名称(通过 `getName()` 方法获取)传入构造函数。
// 这个对象会被Shiro用于后续的认证相关处理表示当前用户的认证信息已通过验证后续在会话等相关处理中会用到这些信息。
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
return info; return info;
} }
} }

@ -10,12 +10,28 @@ import org.springframework.web.servlet.ModelAndView;
import com.tamguo.modules.sys.utils.Setting; import com.tamguo.modules.sys.utils.Setting;
// 使用@Component注解将这个类标记为Spring组件使得Spring能够扫描并管理这个类在需要的时候可以自动将其实例注入到其他依赖它的类中。
// 这个类实现了HandlerInterceptor接口用于拦截Spring Web应用中的请求在请求处理的不同阶段执行自定义的逻辑比如在请求前做一些准备工作、在请求处理后设置一些属性或者在整个请求结束后进行资源清理等。
@Component @Component
public class SettingsInterceptor implements HandlerInterceptor { public class SettingsInterceptor implements HandlerInterceptor {
@Resource // 使用@Resource注解进行依赖注入将名为"setting"的Bean从Spring容器中查找这里应该是一个实现了相关业务逻辑的Setting类的实例可能用于获取系统相关的设置信息等注入到当前类的setting属性中
private Setting setting; // 以便后续在拦截器的各个方法中使用这些设置信息来完成相应的功能,比如传递给视图层等操作。
@Resource
private Setting setting;
/**
* Controller
*
* trueControllerfalseController
* true
*
* @param request HttpServletRequest
* @param response HttpServletResponse
* @param handler Controller
* @return boolean truefalse
* @throws Exception Spring
*/
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { throws Exception {
@ -23,17 +39,39 @@ public class SettingsInterceptor implements HandlerInterceptor {
return true; return true;
} }
/**
* Controller
* 使
* Settingrequest.setAttribute"setting"JSPThymeleaf
*
* @param request HttpServletRequest使
* @param response HttpServletResponse
* @param handler Controller使
* @param modelAndView ControllerModelAndViewControllerModelAndViewnull
* @throws Exception Spring
*/
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception { ModelAndView modelAndView) throws Exception {
// 设置系统变量 // 设置系统变量
request.setAttribute("setting", setting); request.setAttribute("setting", setting);
} }
/**
* DispatcherServlet
* 使
* 线HandlerInterceptor
*
* @param request HttpServletRequest便
* @param response HttpServletResponse
* @param handler Controller
* @param ex null
* @throws Exception Spring
*/
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception { throws Exception {
//在整个请求结束之后被调用也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作) //在整个请求结束之后被调用也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
} }
} }

@ -4,7 +4,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* Setting - * Setting便使
* @ComponentSpringSpring Bean使
* final
* *
* @author candy.tam * @author candy.tam
* *
@ -12,21 +14,52 @@ import org.springframework.stereotype.Component;
@Component @Component
public final class Setting { public final class Setting {
/** 域名 */ /**
@Value(value="${domain.name}") * 使
* @Valueapplication.propertiesapplication.yml"domain.name"domain
* URL
*/
@Value(value = "${domain.name}")
public String domain; public String domain;
/** 静态资源地址*/
@Value(value="${static.domain}") /**
*
* 使@Value"static.domain"staticDomain
* 访
*/
@Value(value = "${static.domain}")
public String staticDomain; public String staticDomain;
@Value(value="${version}")
/**
*
* @Value"version"version
*
*/
@Value(value = "${version}")
public String version; public String version;
/** 真题 */
/**
* "1"
* 便
*/
public final String PAPER_TYPE_ZHENTI = "1"; public final String PAPER_TYPE_ZHENTI = "1";
/** 模拟*/
/**
* "2"
*
*/
public final String PAPER_TYPE_MONI = "2"; public final String PAPER_TYPE_MONI = "2";
/** 押题*/
/**
* "3"
*
*/
public final String PAPER_TYPE_YATI = "3"; public final String PAPER_TYPE_YATI = "3";
/** 名校 */
/**
* "4"
*
*/
public final String PAPER_TYPE_MINGXIAO = "4"; public final String PAPER_TYPE_MINGXIAO = "4";
} }

@ -6,43 +6,99 @@ import org.apache.shiro.subject.Subject;
import com.tamguo.modules.sys.model.SysUserEntity; import com.tamguo.modules.sys.model.SysUserEntity;
// 这个类是一个工具类提供了一系列与Shiro框架交互的便捷方法用于获取Shiro相关的对象如会话、当前用户等以及执行一些常见的操作如设置会话属性、判断登录状态、注销等方便在项目的不同地方复用这些操作逻辑避免重复编写获取Shiro相关信息的代码。
public class ShiroUtils { public class ShiroUtils {
/**
* Shiro
* ShiroSecurityUtilsgetSubject()SubjectgetSession()
*
* @return Shiro
*/
public static Session getSession() { public static Session getSession() {
return SecurityUtils.getSubject().getSession(); return SecurityUtils.getSubject().getSession();
} }
/**
* Subject
* Subject
* ShiroShiroSubject
* @return Subject
*/
public static Subject getSubject() { public static Subject getSubject() {
return SecurityUtils.getSubject(); return SecurityUtils.getSubject();
} }
/**
* SysUserEntity
* SecurityUtils.getSubject().getPrincipal()
* SysUserEntity便使
* @return SysUserEntity使
*/
public static SysUserEntity getUser() { public static SysUserEntity getUser() {
return (SysUserEntity)SecurityUtils.getSubject().getPrincipal(); return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
} }
/**
* SysUserEntityuserCode
* getUser()SysUserEntitygetUserCode()便使
* @return
*/
public static String getUserCode() { public static String getUserCode() {
return getUser().getUserCode(); return getUser().getUserCode();
} }
/**
*
* getSession()使setAttribute()key-value
*
* @param key
* @param value
*/
public static void setSessionAttribute(Object key, Object value) { public static void setSessionAttribute(Object key, Object value) {
getSession().setAttribute(key, value); getSession().setAttribute(key, value);
} }
/**
*
* getSession()使getAttribute()key
* null使
* @param key
* @return null
*/
public static Object getSessionAttribute(Object key) { public static Object getSessionAttribute(Object key) {
return getSession().getAttribute(key); return getSession().getAttribute(key);
} }
/**
*
* SecurityUtils.getSubject().getPrincipal()null
* nulltruenullfalse便访
* @return truefalse
*/
public static boolean isLogin() { public static boolean isLogin() {
return SecurityUtils.getSubject().getPrincipal() != null; return SecurityUtils.getSubject().getPrincipal()!= null;
} }
/**
*
* SecurityUtils.getSubject().logout()使退
* 退
*/
public static void logout() { public static void logout() {
SecurityUtils.getSubject().logout(); SecurityUtils.getSubject().logout();
} }
/**
*
* getSessionAttribute(key)
* getSession().removeAttribute(key)使
* @param key 使
* @return 使
*/
public static String getKaptcha(String key) { public static String getKaptcha(String key) {
String kaptcha = getSessionAttribute(key).toString(); String kaptcha = getSessionAttribute(key).toString();
// getSession().removeAttribute(key); // getSession().removeAttribute(key);
return kaptcha; return kaptcha;
} }

Loading…
Cancel
Save