一、spring中的异常处理

1、在异常发生的controller中来处理

(1)步骤:

1)在controller中定义一个处理异常的方法,注意方法的返回值为ModelAndView
2)方法接收一个Exception类型的参数:该对象最终为异常对象;
3)在该方法中完成异常发生时的业务逻辑;
4)在该方法中添加注解:@ExceptionHandler,在注解的value值中声明要处理的异常类型(类的类对象)。

(2)缺点

1)系统中可能产生的异常多种多样,如果都需要捕获,则需在controller层设置多个异常处理器;
2)针对每个controller下的请求发生异常都需要通过@ExceptinHandler处理,会有冗余代码产生;

(3)解决办法

使用全局异常处理器

2、全局异常处理器

步骤:

(1)定义一个全局异常处理器的类,该类处理各种异常;
(2)在定义的这个类上添加@ControllerAdvice注解;
(3)在这个类中定义不同的方法,提供不同的异常处理业务逻辑;
1)处理异常的方法的返回值为ModelAndView;
2)在方法上添加注解:@ExceptionHandler({异常的类的类对象});
(4)在springmvc的配置文件中配置全局一场处理器的包扫描
扫描ControllerAdvice类。

二、权限管理

1、权限管理理论概念

(1)权限管理的概念

控制一个用户对于所访问的资源是否有对应的权限;根据安全策略来约束用户只能访问被授权的资源。

(2)权限的粒度划分

粗颗粒度:类型资源,通常对应表的操作,通常从系统架构层面进行处理;
细颗粒度:实力资源,通常御用记录的操作,通常在业务逻辑中进行处理;

(3)权限管理的组成

(1)认证:判断用户身份是否合法;
(2)授权:判断用于对于请求的资源是否有相应的权限。

(4)两种授权方式

1)基于角色授权

根据角色的不同,分配不同的访问权限;
比如:董事长和总经理是不同的角色,给予分配不同的权限;

2)基于资源授权

基于每个账户分配资源;
比如:有增加、删除、修改、查询4个资源,对于每个人分配不同的资源;

3、授权的实现

(1)使用拦截器
(2)自定义注解+拦截器

4、授权的思路

授权一定是在认证通过的基础之上;
在拦截器的preHandler方法中执行。
思路:在用户登陆成功之后,应该将当前用户信息存进session作用域;其次,还应该在数据库中查询该用户对应的资源权限,存进session作用域,在preHandler方法中取到当前请求的url路径,与session作用域中的资源权限进行比对,确认是否具有权限。

5、权限管理相关表格

(1)user表

id、username、password(加密);

(2)用户_角色中间表

维护用户和角色实体之间的关系;

(3)角色表

id、name(角色的名字)、type(角色的类型);
存在意义:角色是为了针对某一类用户进行批量的授权,真正在业务中还是基于资源进行授权;

(4)角色_资源中间表

描述了每个角色拥有的资源;

(5)资源表

记录了项目中所有的资源路径;
id;
name:描述该资源所做的事情;
module id:描述该资源所属的模块,外键;
url:对应的资源的业务方法上的requestMapping注解中的value值;
type:表名是菜单资源还是按钮资源,方便动态加载菜单。

三、拦截器权限管理

1、自定义拦截器

(1)判断用户是否登陆

从session中取当前登陆的用户activeUser;
activeUser=null:没有登陆à请求转发到登陆页面,return false;
activeUser !=null:已登陆à放行,return true;

(2)用户已登录,判断当前请求是否具有权限

1)获取当前请求的资源
String servletPath = request.getServletPath():获取到根目录后,参数前的url,
例如:/course/deleteCourse;
2)从session中获取已查询到的当前用户资源权限集合List permissions;
3)比对当前用户是否有本次请求的权限
permissions.contains(servletPath);
有权限:放行,return true;
没有权限:请求转发到没有权限的地址,return false;

2、将拦截器配置到springmvc的配置文件

排出:跟登陆有关的页面、公共能访问的页面、静态资源等;

3、联通测试

四、自定义注解权限管理

1、自定义添加权限管理的注解RequirePermission

(1)作用位置target:方法上;
(2)作用有效期retention:运行期间RunTime;
(3)属性:String value();

2、在handler方法上添加自定义的注解

注解的value值为权限码,比如:course:deleteCourse;

3、自定义拦截器

在拦截器的preHandler()方法中拦截请求,进行判断是否有权限;

(1)判断用户是否登陆

从session中取当前登陆的用户activeUser;
activeUser=null:没有登陆à请求转发到登陆页面,return false;
activeUser !=null:已登陆à放行,return true;

(2)用户已登录,判断当前请求是否具有权限

1)判断当前请求的handler是否为HandlerMethod
handler instanceof HandlerMethod
不是:表示是静态资源,放行,return true;
2)当前请求的handler为HandlerMethod
①将handler向下转型为HandlerMethod handlerMethod;
②获取当前请求的方法
Method currentMethod = handlerMethod.getMethod();
③查看当前方法上是否有自定义的注解
currentMethod.isAnnotationPresent(自定义注解类的类对象);
没有:表示不需要权限即可访问,直接放行,return true;
有:表示需要权限才能访问;
④有注解时,判断当前用户是否有权限
a.获取该方法上添加的自定义注解requirePermission:
currentMethod.getAnnotation(自定义注解的类的类对象);
b.获取注解的value值,即是需要的权限码permissionCode:
requirePermission.value();
c.从session中获取从数据库查询到的当前用户的权限码集合;
3)比对当前用户是否有本次请求的权限
permissions.contains(servletPath);
有权限:放行,return true;
没有权限:请求转发到没有权限的地址,return false;

4、联通测试

五、mybatis-generator逆向生成

mybatis-generator逆向生成可以将数据库的表,逆向生成对应的Java bean,mapper接口和sqlMapper.xml映射文件。这些自动生成的文件中定义了最基础的应用。

1、导入jar包

mybatis-generator-core;

2、配置generator的配置文件

generator配置文件配置了数据库表格到Java中的一些配置:
(1)数据库表映射的Java bean 存放的位置及字段对应的属性名;
(2)数据库表格对应的mapper接口;
(3)数据库表格对应的sqlmapper.xml映射文件;

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE generatorConfiguration
  3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  5. <generatorConfiguration>
  6. <!-- classpathentry 导入jar 因为已经手动导入jar包了, 这里就不要了 -->
  7. <context id="DB2Tables" targetRuntime="MyBatis3">
  8. <!-- 指定如何连接数据库 : 配置数据源信息 -->
  9. <jdbcConnection driverClass="com.mysql.jdbc.Driver"
  10. connectionURL="jdbc:mysql://localhost:3306/shiro?allowMultiQueries=true"
  11. userId="root"
  12. password="root">
  13. </jdbcConnection>
  14. <!-- java类型解析器 使用默认的就可以 -->
  15. <javaTypeResolver >
  16. <property name="forceBigDecimals" value="false" />
  17. </javaTypeResolver>
  18. <!-- 指定 生成的java bean 所在的工程 及包路径 -->
  19. <javaModelGenerator targetPackage="com.chen.model" targetProject=".\src">
  20. <property name="enableSubPackages" value="true" />
  21. <property name="trimStrings" value="true" />
  22. </javaModelGenerator>
  23. <!-- 指定sql映射文件生成在哪里 -->
  24. <sqlMapGenerator targetPackage="mapper" targetProject=".\config">
  25. <property name="enableSubPackages" value="true" />
  26. </sqlMapGenerator>
  27. <!-- 指定mapper接口生成在哪里 -->
  28. <javaClientGenerator type="XMLMAPPER" targetPackage="com.chen.mapper" targetProject=".\src">
  29. <property name="enableSubPackages" value="true" />
  30. </javaClientGenerator>
  31. <!-- 指定要为哪些表生成数据 同时指定 类名 -->
  32. <table tableName="sys_module" domainObjectName="SysModule" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
  33. <table tableName="sys_acl" domainObjectName="SysAcl" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
  34. <table tableName="sys_role" domainObjectName="SysRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
  35. <table tableName="sys_user" domainObjectName="SysUser" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
  36. </context>
  37. </generatorConfiguration>

注意:文件中只自动生成了一些基础的配置,自己业务相关的代码需自己定义。

3、新建测试类,加载配置文件,逆向生成

  1. public static void main(String[] args) throws Exception {
  2. List<String> warnings = new ArrayList<String>();
  3. boolean overwrite = true;
  4. File configFile = new File("generator.xml");
  5. ConfigurationParser cp = new ConfigurationParser(warnings);
  6. Configuration config = cp.parseConfiguration(configFile);
  7. DefaultShellCallback callback = new DefaultShellCallback(overwrite);
  8. MyBatisGenerator myBatisGenerator =new MyBatisGenerator(config, callback, warnings);
  9. myBatisGenerator.generate(null);
  10. }