发表于: 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搜索工具
评论