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;
    }
}

 

 

 

 

 

 

posted @ 2020-08-03 23:40  Dragon_xl  阅读(475)  评论(0)    收藏  举报