SpringBoot项目解决空属性赋值问题与aspect日志、shiro配置
1、解决空属性赋值问题
①、新建一个MyBeanUtils工具类封装空属性赋值方法
public class MyBeanUtils { public static String[] getNullPropertyNames(Object source){ BeanWrapper beanWrapper = new BeanWrapperImpl(source); PropertyDescriptor[] pds = beanWrapper.getPropertyDescriptors(); List<String> nullPropertyNames = new ArrayList<>(); for(PropertyDescriptor pd:pds){ String propertyName = pd.getName(); if(beanWrapper.getPropertyValue(propertyName)==null){ nullPropertyNames.add(propertyName); } } return nullPropertyNames.toArray(new String[nullPropertyNames.size()]); } }
②、在NewsServiceImpl类中的updateNew方法中进行修改,替换原BeanUtils.copyProperties(news, news1)为下面的语句
BeanUtils.copyProperties(news, news1, MyBeanUtils.getNullPropertyNames(news));
并在new1为空时抛出new NotFoundException("该新闻不存在");异常
2、aspect日志
运用到面向切面编程(AOP)的思想。
在AOP的逻辑内,先走@Around注解的方法。然后是@Before注解的方法,然后这两个都通过了,走核心代码,核心代码走完,无论核心有没有返回值,都会走@After方法。然后如果程序无异常,正常返回就走@AfterReturn,有异常就走@AfterThrowing。
①、新建LogAspect类,类注解为@Aspect和@Component
②、在类中编写如下代码
private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("execution(* com.example.news.web.*.*(..))") public void log(){ } @Before("log()") public void deBefore(JoinPoint joinPoint){ //获取request ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request =attributes.getRequest(); //获得url和ip // String url =request.getRequestURI().toString(); //不打印localhost:8080 String url =request.getRequestURL().toString(); //打印localhost:8080 String ip = request.getRemoteAddr(); String classMethod =joinPoint.getSignature().getDeclaringTypeName()+"."; Object[] args = joinPoint.getArgs(); RequestLog requestLog = new RequestLog(url,ip,classMethod,args); logger.info("Request:{}",requestLog); logger.info("-------doBefore-------"); } @After("log()") public void doAfter(){ logger.info("-------doAfter-------"); } @AfterReturning(returning = "result",pointcut = "log()") public void adAfterReturn(Object result){ logger.info("result:{}"+result); } private class RequestLog{ private String url; private String ip; private String classMethod; private Object[] args; public RequestLog(String url, String ip, String classMethod, Object[] args) { this.url = url; this.ip = ip; this.classMethod = classMethod; this.args = args; }
3、使用shiro实现权限管理功能
①、新建Role与Permission两个实体类,用来存放角色权限规则与相应信息
Role(implements Serializable)
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; @ManyToMany(mappedBy = "roles") private Set<User> users = new HashSet<>(0); @ManyToMany(fetch = FetchType.EAGER) private Set<Permission> permissions =new HashSet<>(0);
同时在User中添加相应语句
@ManyToMany(fetch = FetchType.EAGER) private Set<Role> roles = new HashSet<>(0); public Set<Role> getRoles() { return roles; }
Permission
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String code; private String description;
②、导入相应的依赖包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
③、在settings中的inspections中将
项全部勾选
④、在Role类与Permission中自动生成UID如下
private static final long serialVersionUID = 8133201952646995004L;
⑤、新建NewsRealm类(extends AuthorizingRealm)存放用户权限等权限认证
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken; String username = upToken.getUsername(); String password = new String(upToken.getPassword()); User user = userService.checkUsers(username,password); if(user!=null){ return new SimpleAuthenticationInfo(user,user.getPassword(),this.getName()); } return null; } protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取认证用户数据 User user =(User)principalCollection.getPrimaryPrincipal(); //构造认证数据 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); Set<Role> roles = user.getRoles(); for(Role role:roles){ //添加角色信息 info.addRole(role.getName()); for(Permission permission:role.getPermissions()){ //添加权限信息 info.addStringPermission(permission.getCode()); } } return info; }
⑥、新建ShiroConfiguration配置文件
@Configuration public class ShiroConfiguration { //创建realm @Bean public NewsRealm getRealm(){return new NewsRealm();} //创建安全管理器 @Bean public SecurityManager securityManager(NewsRealm realm){ //使用默认的安全管理器 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm); //将自定义的realm交给安全管理器统一调度 return securityManager; } //配置shiro过滤工厂 @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactory =new ShiroFilterFactoryBean(); shiroFilterFactory.setSecurityManager(securityManager); //通用配置 shiroFilterFactory.setLoginUrl("/admin"); shiroFilterFactory.setUnauthorizedUrl("/admin"); /* * key:请求路径 * value:过滤器类型 */ Map<String,String> filterMap = new LinkedHashMap<>(); filterMap.put("/admin/login","anon"); filterMap.put("/admin/**","authc"); shiroFilterFactory.setFilterChainDefinitionMap(filterMap); return shiroFilterFactory; } //开启shiro注解支持 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } }

浙公网安备 33010602011771号