发表于: 2019-11-11 20:19:09

1 969


一、今天完成的事

1.在shiro中加入数据库的查询

  @Override
   protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       System.out.println("-------执行认证逻辑--------");
       String username = (String) authenticationToken.getPrincipal();
       String pwd = new String((char[]) authenticationToken.getCredentials());
       log.info(pwd);
       log.info(username);
       User user = userService.selectByName(username);
       log.info(user);
       if (user == null) {
           throw new AuthenticationException("用户名错误");
       }else if(!user.getPassword().equals(pwd)){
           log.info("执行了吗");
           throw new AuthenticationException("密码错误");
       }
       log.info("还在运行?");
       return new SimpleAuthenticationInfo(username, user.getPassword(), getName());
   }

使用存在数据库中的账户密码能够登录


密码或者账户错误会报异常

二、遇到的问题

程序中一直捕获不到异常,每次出现异常就是空的

捕获异常的代码是

controller中

 try {
           log.info("执行到了这里");
           subject.login(token);
           log.info("执行到这里?");
       } catch (UnknownAccountException uae) {
           return "未知账户";
       } catch (IncorrectCredentialsException ice) {
           return "密码不正确";
       } catch (LockedAccountException lae) {
           return "账户已锁定";
       } catch (ExcessiveAttemptsException eae) {
           return "用户名或密码错误次数过多";
       } catch (AuthenticationException ae) {
           return "用户名或密码错误";
       }

GlobalExceptionHandler

@ControllerAdvice
public class GlobalExceptionHandler {
   private static final Logger log= LogManager.getLogger(GlobalExceptionHandler.class);
   @ExceptionHandler(value = Exception.class)
   public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
       ModelAndView mav = new ModelAndView();
       log.info(e);
       log.info(req.getRequestURL());
       mav.addObject("exception", e);
       mav.addObject("url", req.getRequestURL());
       mav.setViewName("error");
       return mav;
   }

}

在CustomRealm中

 if (null == user) {
           throw new AuthenticationException();
       }

按道理来说如果查询数据库为空,就会抛出Authentication异常

但是运行之后的情况是

经过两个小时的排查,终于找到了原因

Springboot的全局异常查是通过两个注解@ControllerAdvice和@ExceptionHandler来实现的。

只有代码出错或者throw出来的异常才会被捕捉处理,如果被catch的异常,就不会被捕捉,除非catch之后再throw异常。

@ControllerAdvice:增强型控制器,对于控制器的全局配置放在同一个位置,全局异常的注解,放在类上。

@ControllerAdvice默认只会处理controller层抛出的异常,如果需要处理service层的异常,需要定义一个自定义的MyException来继承RuntimeException类,然后@ExceptionHandler(MyException)即可。

@ExceptionHandler:指明需要处理的异常类型以及子类。注解放在方法上面。

所有controller中修改为

   
       subject.login(token);
       
       

删掉所有的异常处理

在自定义Realm类中加入异常信息

   if (null == user) {
           throw new AuthenticationException("用户名错误");
       }

实现后的效果

三、收获

在使用shiro中,大量的源码都用到了构造函数来初始化,自己对这个不是特别清楚,正好复习了构造函数的基础知识

构造函数的特点:

1.构造函数的命名必须和类名完全相同。在java中普通函数可以和构造函数同名,但是必须带有返回值;

2.构造函数的功能主要用于在类的对象创建时定义初始化的状态。它没有返回值,也不能用void来修饰。这就保证了它不仅什么也不用自动返回,而且根本不能有任何选择。而其他方法都有返回值,即使是void返回值。尽管方法体本身不会自动返回什么,但仍然可以让它返回一些东西,而这些东西可能是不安全的;

3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的;

4.当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函数.此默认构造函数是不带参数的。而一般的方法不存在这一特点;

5.构造函数有回滚的效果,构造函数抛出异常时,构造的是一个不完整对象,会回滚,将此不完整对象的成员释放(c++)

6.当一个类只定义了私有的构造函数,将无法通过new关键字来创建其对象,当一个类没有定义任何构造函数,C#编译器会为其自动生成一个默认的无参的构造函数。

四、明天的计划

做完shiro的demo(授权管理和加盐加密)

学习springboot-elasticesearch搜索工具




返回列表 返回列表
评论

    分享到