当前位置: 首页 > news >正文

浙江龙元建设集团 网站瑞金市网站建设

浙江龙元建设集团 网站,瑞金市网站建设,广告平台网站有哪些,wordpress新建页面子页面文章目录1. 统一用户登录权限效验1.1 最初用户登录权限效验1.2 Spring AOP 统一用户登录验证1.3 Spring 拦截器1.4 练习#xff1a;登录拦截器1.5 拦截器实现原理1.6 统一访问前缀添加2. 统一异常处理3. 统一数据格式返回3.1 统一数据格式返回的实现3.2 ControllerAdvice 源码… 文章目录1. 统一用户登录权限效验1.1 最初用户登录权限效验1.2 Spring AOP 统一用户登录验证1.3 Spring 拦截器1.4 练习登录拦截器1.5 拦截器实现原理1.6 统一访问前缀添加2. 统一异常处理3. 统一数据格式返回3.1 统一数据格式返回的实现3.2 ControllerAdvice 源码分析本篇将要学习 Spring Boot 统一功能处理模块这也是 AOP 的实战环节统一用户登录权限的效验实现接口 HandlerInterceptor WebMvcConfigurer统一异常处理使用注解 RestControllerAdvice ExceptionHandler统一数据格式返回使用注解 ControllerAdvice 并且实现接口 ResponseBodyAdvice 1. 统一用户登录权限效验 用户登录权限的发展完善过程 最初用户登录效验在每个方法中获取 Session 和 Session 中的用户信息如果存在用户那么就认为登录成功了否则就登录失败了第二版用户登录效验提供统一的方法在每个需要验证的方法中调用统一的用户登录身份效验方法来判断第三版用户登录效验使用 Spring AOP 来统一进行用户登录效验第四版用户登录效验使用 Spring 拦截器来实现用户的统一登录验证 1.1 最初用户登录权限效验 RestController RequestMapping(/user) public class UserController {RequestMapping(/a1)public Boolean login (HttpServletRequest request) {// 有 Session 就获取没有就不创建HttpSession session request.getSession(false);if (session ! null session.getAttribute(userinfo) ! null) {// 说明已经登录进行业务处理return true;} else {// 未登录return false;}}RequestMapping(/a2)public Boolean login2 (HttpServletRequest request) {// 有 Session 就获取没有就不创建HttpSession session request.getSession(false);if (session ! null session.getAttribute(userinfo) ! null) {// 说明已经登录进行业务处理return true;} else {// 未登录return false;}} }这种方式写的代码每个方法中都有相同的用户登录验证权限缺点是 每个方法中都要单独写用户登录验证的方法即使封装成公共方法也一样要传参调用和在方法中进行判断添加控制器越多调用用户登录验证的方法也越多这样就增加了后期的修改成功和维护成功这些用户登录验证的方法和现在要实现的业务几乎没有任何关联但还是要在每个方法中都要写一遍所以提供一个公共的 AOP 方法来进行统一的用户登录权限验证是非常好的解决办法。 1.2 Spring AOP 统一用户登录验证 统一用户登录验证首先想到的实现方法是使用 Spring AOP 前置通知或环绕通知来实现 Aspect // 当前类是一个切面 Component public class UserAspect {// 定义切点方法 Controller 包下、子孙包下所有类的所有方法Pointcut(execution(* com.example.springaop.controller..*.*(..)))public void pointcut(){}// 前置通知Before(pointcut())public void doBefore() {}// 环绕通知Around(pointcut())public Object doAround(ProceedingJoinPoint joinPoint) {Object obj null;System.out.println(Around 方法开始执行);try {obj joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println(Around 方法结束执行);return obj;} }但如果只在以上代码 Spring AOP 的切面中实现用户登录权限效验的功能有这样两个问题 没有办法得到 HttpSession 和 Request 对象我们要对一部分方法进行拦截而另一部分方法不拦截比如注册方法和登录方法是不拦截的也就是实际的拦截规则很复杂使用简单的 aspectJ 表达式无法满足拦截的需求 1.3 Spring 拦截器 针对上面代码 Spring AOP 的问题Spring 中提供了具体的实现拦截器HandlerInterceptor拦截器的实现有两步 创建自定义拦截器实现 Spring 中的 HandlerInterceptor 接口中的 preHandle方法 将自定义拦截器加入到框架的配置中并且设置拦截规则 1 给当前的类添加 Configuration 注解 2实现 WebMvcConfigurer 接口 3重写 addInterceptors 方法 注意一个项目中可以同时配置多个拦截器 1创建自定义拦截器 /*** Description: 自定义用户登录的拦截器* Date 2023/2/13 13:06*/ Component public class LoginIntercept implements HandlerInterceptor {// 返回 true 表示拦截判断通过可以访问后面的接口// 返回 false 表示拦截未通过直接返回结果给前端Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {// 1.得到 HttpSession 对象HttpSession session request.getSession(false);if (session ! null session.getAttribute(userinfo) ! null) {// 表示已经登录return true;}// 执行到此代码表示未登录未登录就跳转到登录页面response.sendRedirect(/login.html);return false;} }2将自定义拦截器添加到系统配置中并设置拦截的规则 addPathPatterns表示需要拦截的 URL**表示拦截所有⽅法excludePathPatterns表示需要排除的 URL 说明拦截规则可以拦截此项⽬中的使⽤ URL包括静态⽂件图⽚⽂件、JS 和 CSS 等⽂件。 /*** Description: 将自定义拦截器添加到系统配置中并设置拦截的规则* Date 2023/2/13 13:13*/ Configuration public class AppConfig implements WebMvcConfigurer {Resourceprivate LoginIntercept loginIntercept;Overridepublic void addInterceptors(InterceptorRegistry registry) { // registry.addInterceptor(new LoginIntercept());//可以直接new 也可以属性注入registry.addInterceptor(loginIntercept).addPathPatterns(/**). // 拦截所有 urlexcludePathPatterns(/user/login). //不拦截登录注册接口excludePathPatterns(/user/reg).excludePathPatterns(/login.html).excludePathPatterns(/reg.html).excludePathPatterns(/**/*.js).excludePathPatterns(/**/*.css).excludePathPatterns(/**/*.png).excludePathPatterns(/**/*.jpg);} }1.4 练习登录拦截器 要求 登录、注册页面不拦截其他页面都拦截当登录成功写入 session 之后拦截的页面可正常访问 在 1.3 中已经创建了自定义拦截器 和 将自定义拦截器添加到系统配置中并设置拦截的规则 1下面创建登录和首页的 html 2创建 controller 包在包中创建 UserController写登录页面和首页的业务代码 RestController RequestMapping(/user) public class UserController {RequestMapping(/login)public boolean login(HttpServletRequest request,String username, String password) {boolean result false;if (StringUtils.hasLength(username) StringUtils.hasLength(password)) {if(username.equals(admin) password.equals(admin)) {HttpSession session request.getSession();session.setAttribute(userinfo,userinfo);return true;}}return result;}RequestMapping(/index)public String index() {return Hello Index;} }3运行程序访问页面对比登录前和登录后的效果 1.5 拦截器实现原理 有了拦截器之后会在调⽤ Controller 之前进⾏相应的业务处理执⾏的流程如下图所示 实现原理源码分析 所有的 Controller 执行都会通过一个调度器 DispatcherServlet 来实现 而所有方法都会执行 DispatcherServlet 中的 doDispatch 调度⽅法doDispatch 源码分析如下 通过源码分析可以看出Sping 中的拦截器也是通过动态代理和环绕通知的思想实现的 1.6 统一访问前缀添加 所有请求地址添加 api 前缀c 表示所有 Configuration public class AppConfig implements WebMvcConfigurer {// 所有的接口添加 api 前缀Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {configurer.addPathPrefix(api, c - true);} }2. 统一异常处理 给当前的类上加 ControllerAdvice 表示控制器通知类给方法上添加 ExceptionHandler(xxx.class)表示异常处理器添加异常返回的业务代码 RestController RequestMapping(/user) public class UserController {RequestMapping(/index)public String index() {int num 10/0;return Hello Index;} }在 config 包中创建 MyExceptionAdvice 类 RestControllerAdvice // 当前是针对 Controller 的通知类增强类 public class MyExceptionAdvice {ExceptionHandler(ArithmeticException.class)public HashMapString,Object arithmeticExceptionAdvice(ArithmeticException e) {HashMapString, Object result new HashMap();result.put(state,-1);result.put(data,null);result.put(msg , 算出异常 e.getMessage());return result;} }也可以这样写效果是一样的 ControllerAdvice public class MyExceptionAdvice {ExceptionHandler(ArithmeticException.class)ResponseBodypublic HashMapString,Object arithmeticExceptionAdvice(ArithmeticException e) {HashMapString, Object result new HashMap();result.put(state,-1);result.put(data,null);result.put(msg , 算数异常 e.getMessage());return result;} }如果再有一个空指针异常那么上面的代码是不行的还要写一个针对空指针异常处理器 ExceptionHandler(NullPointerException.class) public HashMapString,Object nullPointerExceptionAdvice(NullPointerException e) {HashMapString, Object result new HashMap();result.put(state,-1);result.put(data,null);result.put(msg , 空指针异常异常 e.getMessage());return result; }RequestMapping(/index)public String index(HttpServletRequest request,String username, String password) {Object obj null;System.out.println(obj.hashCode());return Hello Index;}但是需要考虑的一点是如果每个异常都这样写那么工作量是非常大的并且还有自定义异常所以上面这样写肯定是不好的既然是异常直接写 Exception 就好了它是所有异常的父类如果遇到不是前面写的两种异常那么就会直接匹配到 Exception 当有多个异常通知时匹配顺序为当前类及其⼦类向上依次匹配 ExceptionHandler(Exception.class) public HashMapString,Object exceptionAdvice(Exception e) {HashMapString, Object result new HashMap();result.put(state,-1);result.put(data,null);result.put(msg , 异常 e.getMessage());return result; }可以看到优先匹配的还是前面写的 空指针异常 3. 统一数据格式返回 3.1 统一数据格式返回的实现 给当前类添加 ControllerAdvice 实现 ResponseBodyAdvice 重写其方法 supports 方法此方法表示内容是否需要重写通过此⽅法可以选择性部分控制器和方法进行重写如果要重写返回 true beforeBodyWrite 方法方法返回之前调用此方法 ControllerAdvice public class MyResponseAdvice implements ResponseBodyAdvice {// 返回一个 boolean 值true 表示返回数据之前对数据进行重写也就是会进入 beforeBodyWrite 方法// 返回 false 表示对结果不进行任何处理直接返回Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}// 方法返回之前调用此方法Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {HashMapString,Object result new HashMap();result.put(state,1);result.put(data,body);result.put(msg,);return result;} }RestController RequestMapping(/user) public class UserController {RequestMapping(/login)public boolean login(HttpServletRequest request,String username, String password) {boolean result false;if (StringUtils.hasLength(username) StringUtils.hasLength(password)) {if(username.equals(admin) password.equals(admin)) {HttpSession session request.getSession();session.setAttribute(userinfo,userinfo);return true;}}return result;}RequestMapping(/reg)public int reg() {return 1;} }3.2 ControllerAdvice 源码分析 通过对 ControllerAdvice 源码的分析我们可以知道上面统一异常和统一数据返回的执行流程 1先看 ControllerAdvice 源码 可以看到 ControllerAdvice 派生于 Component 组件而所有组件初始化都会调用 InitializingBean 接口 2下面查看 initializingBean 有哪些实现类 在查询过程中发现其中 Spring MVC 中的实现子类是 RequestMappingHandlerAdapter它里面有一个方法 afterPropertiesSet方法表示所有的参数设置完成之后执行的方法 3而这个方法中有一个 initControllerAdviceCache 方法查询此方法 发现这个方法在执行时会查找使用所有的 ControllerAdvice 类发送某个事件时调用相应的 Advice 方法比如返回数据前调用统一数据封装比如发生异常是调用异常的 Advice 方法实现的
http://www.dnsts.com.cn/news/116769.html

相关文章:

  • 手绘风格 网站广元网站建设优化
  • 刚建的网站百度搜不到医疗器械公司
  • 制作企业网站素材视频培训班的ui设计
  • 做彩票网站犯法不wordpress极速版
  • 网站首页需求单页网站如何制作
  • o2o网站设计方案长沙关键词排名软件
  • 现在还用dw做网站设计么开创云网站建设支持
  • 山东做网站建设公司网站推广策略
  • 企业做网站有发展么大连学网站制作
  • 各网站网络营销产品价格策略无锡建设局施工许可证网站
  • 怎么在网站上做排名海珠定制型网站建设
  • 网站哪里有做的手机版网站seo怎么做
  • 北京网站建设华网外国企业网站模板免费下载
  • 女生自己做网站雁塔区住房和城乡建设局网站
  • 网站设计和程序员对电子商务网站建设和管理的理解
  • 做网站赚广告费多么网站制作招聘
  • wordpress打开速度株洲seo
  • 如何使用好单库选品库做网站湘潭做网站 搜搜磐石网络
  • 服务提供网站网站200m虚拟主机能放多少东西
  • 河北恒基建设招标有限公司网站石河子农八师建设兵团社保网站
  • 开发app的网站网站开发合同预期
  • 重庆网站开发企业个人主页怎么设置
  • 旅游网站内容东莞大岭山网站建设
  • 公司网站用什么语言开发一家电子商务网站建设心得
  • 招标网站建设申请深圳哪家网站设计比较好
  • 安徽省建设干部网站百度小程序登录
  • iis网站下载南宁本地有几家网站开发
  • 潍坊专业做网站的公司购物网站开发教程中文版
  • 南宁门户网站建设淘宝客怎么在微博做网站
  • 东旭网站建设西昌手机网站