智销系统day04

1.懒加载(no Session错误)

为Employee的部门字段添加懒加载
在这里插入图片描述
产生no session异常
在这里插入图片描述
问题分析:
在这里插入图片描述
错误原因:
设置懒加载,会报no Session 错误,原因是EntityManager关闭早了
解决方法:
配置一个openEntityManagerInViewFilter过滤器,这个过滤器是Spring准备好的
过滤器请求的时候创建EntityManager,响应后关闭EntityManager

<!--no session解决(Spring准备好的过滤器)-->
<filter>
  <filter-name>openEntityManagerInViewFilter</filter-name>
  <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>openEntityManagerInViewFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

2.No serializer(不是序列化)

虽然no session错误解决了,但是还有No serializer found for class 错误,前台数据显示不能正确展示
产生原因

  • 因为前台展示的数据是json格式,以往是SpringMVC帮我们把Employee变成json格式数据,但是前提是Employee的所有字段都必须是可序列化的
  • 但是设置懒加载的department,Spring会创建代理对象,它为了实现代理通知,会自主添加一些属性,这些属性不支持序列化

问题分析:
在这里插入图片描述
解决方法①:
通过@JsonIgnoreProperties注解,在转换为json数据时,忽略掉这些不支持序化的属性(每次懒加载都需要加该注解)

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) 
private Department department;

解决方法②:
自定义映射,解决Serializa的问题(一劳永逸)

  • 创建CustomMapper自定义映射类
public class CustomMapper extends ObjectMapper {
    public CustomMapper() {
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}
  • 配置applicationContext-mvc.xml
<!--2.注解支持-->
<!-- Spring MVC 配置 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>application/json; charset=UTF-8</value>
                    <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                </list>
            </property>
            <!-- No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题 -->
            <property name="objectMapper">
                <bean class="com.luo.aisell.common.CustomMapper"></bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

3.n to n(修改oid错误)

错误原因:
不能修改持久化对象的id,一旦修改,就会报 n-to-n错误
在这里插入图片描述
图中Department是持久化对象,修改持久化id报错
在这里插入图片描述
解决方式:
就是,将department持久化对象设为null,他就不是持久化对象了,然后修改id就不会报错了。
在这里插入图片描述

4.权限

  • 权限分为:登录和授权
  • 游客:当你没有登录系统时,你的身份为游客
  • 令牌:一般是用户名和密码组成令牌,通过令牌可以登录系统
    在这里插入图片描述
    用户登录图
    在这里插入图片描述
    在这里插入图片描述
    角色就是一组权限的集合
    在这里插入图片描述

5.Shiro(权限框架)

shiro是一个轻量级强大且易用的java安全框架
RBAC:权限(登录,授权) 用户(n)-角色(n)-权限(n)(资源)

①面试题:shiro和Spring security的区别?

主要是控制权限的粒度不同

  • Spring security:细粒度,重量级安全框架
  • shiro:粗粒度,轻量级安全框

②shiro的四大基石

  • 身份认证(登录) Authentication
  • 授权(权限) Authorization
  • 密码学 Cryptography
  • 会话管理 Session Management
    在这里插入图片描述
    四大基石图解
    在这里插入图片描述

③shiro架构

宏观角度

在这里插入图片描述

微观角度

在这里插入图片描述

6.shiro(Hello案例)

①导包

<!--使用shiro需要先导包-->
<dependencies>
    <!--shiro的核心包-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-core</artifactId>
        <version>1.4.0</version>
    </dependency>
    <!--日志包-->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <!--测试包-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
    </dependency>
</dependencies>

②配置ini文件

文件中配置用户名,密码和角色权限

# -----------------------------------------------------------------------------
# users:代表下面都是用户
# root:用户名,123456:密码,admin:角色
#
#
# -----------------------------------------------------------------------------
[users]
root = 123456, admin
guest = 123, gg
gu = 2333,it

# -----------------------------------------------------------------------------
#roles:下面代表角色
# admin = *:表示admin角色可以做任何事
# guest = employee:*:表示gg角色可以对员工进行任何操作
# gu = employee:save:表示it角色只能对员工进行添加
# -----------------------------------------------------------------------------
[roles]
admin = *
gg = employee:*
it = employee:save

③测试登录

想要使用shiro必须先获取权限管理对象SecurityManager

  • UnknownAccountException 不知道用户异常(用户名不存在)
  • IncorrectCredentialsException(不正确凭证(密码错误)异常)
@Test
public class ShiroTest {
    @Test
    public void test() throws Exception{
        //获取权限管理器工厂
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //通过工厂获取权限管理器对象
        SecurityManager securityManager = factory.getInstance();
        /*
         *将权限管理器对象放入工具类,不然工具类功能用不了(放进来securityManager才可以在整个项目中都使用)
         *      所有功能都在权限管理器中,所以我要把这个管理器交给工具类
         *      工具类就可以直接实现相应的功能
         **/
        SecurityUtils.setSecurityManager(securityManager);
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //判断当前用户是否登录
        System.out.println("用户是否登录:"+subject.isAuthenticated());


        //如果用户没有登录,让他登录
        if(!subject.isAuthenticated()){
            try {
                //登录需要令牌(准备用户名密码令牌)
                AuthenticationToken token = new UsernamePasswordToken("root","123456");
                //用户登录
                subject.login(token);

                //判断用户是否有该角色
                System.out.println("判断用户是否有该角色"+subject.hasRole("admin"));

                //判断是否有某个权限
                System.out.println("判断用户是否有employee:save权限"+subject.isPermitted("employee:save"));
                System.out.println("判断用户是否有employee:update权限"+subject.isPermitted("employee:update"));
                System.out.println("判断用户是否有employee:delete权限"+subject.isPermitted("employee:delete"));
                System.out.println("判断用户是否有department:save权限"+subject.isPermitted("department:save"));
            } catch (UnknownAccountException e) {
                //UnknownAccountException(不知道用户异常)
                System.out.println("用户名错误!!!");
                e.printStackTrace();
            }catch (IncorrectCredentialsException e){
                //IncorrectCredentialsException(不正确凭证(密码错误)异常)
                System.out.println("密码错误!!!");
                e.printStackTrace();
            }catch (AuthenticationException e){
                System.out.println("sorry!!!");
                e.printStackTrace();
            }
        }
        //判断当前用户是否登录
        System.out.println("用户是否登录:"+subject.isAuthenticated());

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值