Java阶段三Day07

news2024/11/16 16:42:07

Java阶段三Day07

文章目录

  • Java阶段三Day07
    • Spring Security
      • 自定义UserDetails
      • 密码加密
      • 授权
    • JDK包结构
    • 文档注释规范
    • JDK API
    • String API
      • String是不可变对象
      • String常量池
      • 内存编码及长度
      • 使用indexOf实现检索
      • 使用substring获取子串
      • trim去除两侧空白
      • charAt
      • startsWith和endsWith
      • 大小写变换
      • valueOf
    • StringBuilder API
      • StringBuilder封装可变字符串
      • StringBuilder常用方法
      • StringBuild总结
  • 教师总结
    • 获取当前登录的用户信息
    • 授权

Spring Security

自定义UserDetails

  1. 默认的UserDetails里面只有用户的用户名,没有其它的信息。如果需要用到类似id和nickname等信息的话需要自定义UserDetails
  2. 修改UserDetailServiceImpl中的UserDetails,并把后期需要的id和nickName保存进去
  • UserDetailServiceImpl
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserVO user = userMapper.selectByUsername(username);
        if (user == null) {
            return null;    //默认抛出 AuthenticationException 用户名找不到异常
        }

        List<GrantedAuthority> list = AuthorityUtils.createAuthorityList("权限1", "权限2");
        //创建自定义的UserDetails并把后期需要的id和nickName保存进去
        CustomUserDetails userDetail = new CustomUserDetails(
                user.getId(),
                user.getNickname(),
                username,
                user.getPassword(),
                list
        );
        //如果用户输入的密码和数据库中查询到的密码不一致则会抛出异常
        return userDetail;
    }
}
  • CustomUserDetails
@Getter
@ToString
public class CustomUserDetails extends User {
    private Integer id;
    private String nickname;
    public CustomUserDetails(Integer id,String nickname,String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
        this.id = id;
        this.nickname = nickname;
    }
}
  • WeiboController
@RestController
@RequestMapping("/v1/weibos")
public class WeiboController {

    @Resource
    private WeiboMapper weiboMapper;

    @PostMapping("/insert")
    public ResultVO reg(@RequestBody WeiboDTO weiboDTO, @AuthenticationPrincipal CustomUserDetails userDetails){
        System.out.println("weiboDTO = " + weiboDTO + ", userDetails = " + userDetails);
        Weibo weibo = new Weibo();
        BeanUtils.copyProperties(weiboDTO, weibo);
        weibo.setCreated(new Date());
        //作者id  当前登录的用户id,从Security框架中得到当前登录的用户信息
        weibo.setUserId(userDetails.getId());
        weiboMapper.insert(weibo);
        return new ResultVO(StatusCode.SUCCESS);
    }
}

密码加密

  1. SecurityConfig配置类中配置密码加密方式 return new BCryptPasswordEncoder();
  2. UserController中添加PasswordEncoder自动装配,并在注册功能中对user对象里面的密码进行加密
  • SecurityConfig
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //配置密码加密的方式
    @Bean
    public PasswordEncoder passwordEncoder(){
        //NoOpPasswordEncoder.getInstance()获取一个无加密的实例
        //返回此加密的编码器之后, 用户输入的密码会通过此编码器加密之后再和数据库里面的密码进行比较
        return new BCryptPasswordEncoder();

    }
}
  • UserController
@RestController
@RequestMapping("/v1/users")
public class UserController {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Resource
    private UserMapper userMapper;

    @PostMapping("/reg")
    public ResultVO reg(@RequestBody UserRegDTO userRegDTO){
        UserVO userVO = userMapper.selectByUsername(userRegDTO.getUsername());
        if(userVO!= null){
            return new ResultVO(StatusCode.USERNAME_ALREADY_EXISTS);
        }
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        //对user对象里面的密码进行加密 -- 加密之后得到60个字符长度的密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userMapper.insert(user);
        return new ResultVO(StatusCode.SUCCESS);
    }
}

授权

  1. UserDetailsServicelmpl中用户登录认证时,给当前用户设置拥有的权限
  2. SecurityConfig配置类中添加授权检测的注解@EnableGlobalMethodSecurity(prePostEnabled = true)
  3. WeiboController中处理请求的方法上面添加注解判断当前登录的用户是否拥有此权限,如果有,允许访问。如果没有则抛出异常
  4. 在统一全局异常处理GlobalExceptionHandler处理异常
  • UserDetailsServicelmpl
@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserVO user = userMapper.selectByUsername(username);
        if (user == null) {
            return null;    //默认抛出 AuthenticationException 用户名找不到异常
        }

        //模拟王五是管理员,其他是用户
        String role = username.equals("王五") ? "ADMIN" : "USER";
        List<GrantedAuthority> list = AuthorityUtils.createAuthorityList(role);
        //创建自定义的UserDetails并把后期需要的id和nickName保存进去
        CustomUserDetails userDetail = new CustomUserDetails(
            user.getId(),
            user.getNickname(),
            username,
            user.getPassword(),
            list
        );

        //如果用户输入的密码和数据库中查询到的密码不一致则会抛出异常
        return userDetail;
    }
}
  • SecurityConfig
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启方法授权的检测
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}
  • WeiboController
@RestController
@RequestMapping("/v1/weibos")
public class WeiboController {

    @Resource
    private WeiboMapper weiboMapper;

    @PostMapping("/{id}/delete")
    //@PreAuthorize 当前用户必须拥有 ADMIN 权限才能删除,否则会抛出异常
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    public ResultVO delete(@PathVariable Integer id){
        weiboMapper.deleteById(id);
        return new ResultVO(StatusCode.SUCCESS);
    }
}
  • GlobalExceptionHandler
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 用户无权访问抛出异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResultVO handleAccessDeniedException(AccessDeniedException e){
        log.warn("无权访问!");
        return new ResultVO(StatusCode.FORBIDDEN_ERROR);
    }
}

JDK包结构

  • 为了便于使用和维护,JDK类库按照包结构划分,不同功能的类划分在不同的包中

  • 经常使用的包如下表所示

    功能
    java.langJava程序的基础类,如字符串、多线程等,该包中的类使用的频率非常高,不需要import,可以直接使用
    java.util常用工具类,如集合、随机数产生器、日历、时钟等
    java.io文件操作、输入/输出操作
    java.net网络操作
    java.math数学运算相关操作
    java.security安全相关操作
    java.sql数据库访问
    java.text处理文字、日期、数字、信息的格式

文档注释规范

  • /**开始,以*/结束
  • 加在类和方法的开头,用于说明作者,时间,版本,要实现功能的详细描述等信息
  • 通过javadoc工具,可以轻松的将此注释转换为HTML文档说明;学习者和程序员主要通过文档了解API的功能
  • 文档注释不同于普通的注释(/…或//),普通注释写在程序之中,用于程序员进行代码维护和交流,无法通过工具生成文档;而文档注释(/**…*/)写在类和方法的开头,专门用于生成供API使用者进行参考的文档资料

JDK API

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4hUi6CpC-1685520342998)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530184320691.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ntVB45eO-1685520343022)(C:\Users\DELL\AppData\Roaming\Typora\typora-user-images\image-20230530184329107.png)]

String API

String是不可变对象

  • java.lang.String使用了final修饰,不能被继承
  • 字符串底层封装了字符数组及针对字符数组的操作算法
  • 字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值
  • Java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码

String常量池

  • Java为了提高性能,静态字符串(字面量 / 常量 / 常量连接的结果)在常量池中创建,并尽量使用同一个对象,重用静态字符串
  • 对于重复出现的字符串直接量,JVM会首先在常量池中查找,如果存在即返回该对象。

内存编码及长度

  • String在内存中采用Unicode编码,每个字符占用两个字节
  • 任何一个字符(无论中文还是英文)都算1个字符长度,占用两个字节。

使用indexOf实现检索

  • indexOf方法用于实现在字符串中检索另外一个字符串

  • String提供几个重载的indexOf方法

    方法功能描述
    int indexOf(String str)在字符串中检索str,返回其第一次出现的位置,如果找不到则返回-1
    int indexOf(String str,int fromIndex)从字符串的 fromIndex位置开始检索
  • String还定义了lastIndexOf方法

    方法功能描述
    int lastIndexOf(String str,int from)str在字符串中多次出现时,将返回最后一个出现的位置

使用substring获取子串

  • substring方法用于返回一个字符串的子字符串

  • substring方法常用重载方法定义如下

    方法功能描述
    String substring(int beginIndex,int endIndex)返回字符串中从下标beginlndex(包括)开始到endlndex(不包括)结束的子字符串
    String substring(int beginIndex)返回字符串中从下标beginIndex(包括)开始到字符串结尾的子字符串

trim去除两侧空白

trim方法用于去掉一个字符串的前导和后继空字符

charAt

方法功能描述
char charAt(int index)方法charAt()用于返回字符串指定位置的字符,参数index表示指定的位置

startsWith和endsWith

用于检测一个字符串是否以指定字符串开头或结尾

大小写变换

用于转换字符串中英文字母的大小写形式

valueOf

  • String提供了若干的静态的重载方法valueOf
  • 该方法用于将其他类型转换为字符串类型

StringBuilder API

StringBuilder封装可变字符串

  • StringBuilder封装可变的字符串,对象创建后可以通过调用方法改变其封装的字符序列
  • StringBuilder常用构造方法:
    • public StringBuilder()
    • public StringBuilder(String str)

StringBuilder常用方法

常用方法功能描述
StringBuilder append(String str)追加字符串
StringBuilder append(int dstOffset,String s)插入字符串
StringBuilder append(int start,int end)删除字符串
StringBuilder replace(int start,int end,String str)替换字符串
StringBuilder reverse()字符串反转

StringBuild总结

  • StringBuilder可变字符串。字符串的内容计算,建议采用StringBuilder实现,这样性能会好一些

  • java的字符串连接的过程是利用StringBuilder实现的

    String s = "AB" ;String s1 = s +"DE"+1;
    String s1 = new StringBuilder(s). append ( "DE")append(1).toString () ;
    
  • StringBufferStringBuilder

    • StringBuffer线程安全的,同步处理的,性能稍
    • StringBuilder非线程安全的,并发处理的,性能稍

教师总结

获取当前登录的用户信息

  1. 如果需要获取用户名以外的信息, 需要自定义CustomUserDetails,
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B4YLAVWu-1685520612559)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531154550611.png)]

  2. 在UserDetailServiceImpl里面 把之前创建的UserDetails换成CustomUserDetails

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mQeb27Pi-1685520612561)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531154716332.png)]

  3. 在WeiboController中发微博的方法参数列表处声明CustomUserDetails,获取当前登录用户的信息

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GQap7bkM-1685520612562)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531154917443.png)]

授权

  1. 在UserDetailsServiceImpl中 用户登录认证时,给当前用户设置拥有的权限
    ​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HJGiSQLI-1685520612563)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531155112074.png)]

  2. 在Security配置类中添加授权检测的注解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gq6evYyh-1685520612564)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531155155559.png)]

  3. 在WeiboController中处理请求的方法上面添加注解 判断当前登录的用户是否拥有此权限,如果有,运行访问. 如果没有则抛出异常

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ekobuAXE-1685520612565)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531155322826.png)]

  4. 在全局异常处理类中 处理异常

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WtTrDsVm-1685520612567)(C:\Users\TEACHER\Downloads\jsd-2303-04-teacher-master\文件\笔记\image-20230531155402804.png)]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.1 矩阵连乘问题

博主简介&#xff1a;一个爱打游戏的计算机专业学生博主主页&#xff1a; 夏驰和徐策所属专栏&#xff1a;算法设计与分析 学习目标&#xff1a; 如果我要学习动态规划中的矩阵连乘问题&#xff0c;我会采取以下学习方法&#xff1a; 1. **理解问题的背景和目标&#xff1a;首…

pytorch中分布式Collective通信API学习

随着各种大模型的不断迭出&#xff0c;感觉现在的NLP领域已经来到了大模型的时代。那么怎么来训练一个大模型呢&#xff1f;其中比较关键的一个技术基础就是分布式训练。在阅读GLM源码的时候&#xff0c;感觉其中的分布式训练代码不是很熟悉&#xff0c;看起来有点吃力&#xf…

【Nature 2023】Computational approaches streamlining drug discovery

今天为大家介绍的是一篇发表于“Nature”上面的综述文章“Computational approaches streamlining drug discovery”&#xff0c; Computer-aided drug discovery has been around for decades, although the past few years have seen a tectonic shift towards embracing com…

马尔科夫链 Markov chain

马尔科夫链 1.实例参考文献 马尔科夫链(Markov chain)及其模型在机器学习中应用广泛&#xff0c;本文结合一些参考资料做一个总结。 注意的是&#xff0c;本文中提到的马尔科夫链&#xff0c;要与隐马尔科夫(HMM)作以区分。 1.实例 设某人的训练计划中有以下四项运动&#x…

通过VCP(VMware Certified Professional)认证

文章目录 小结要求考试证书参考 小结 通过VCP(VMware Certified Professional)认证&#xff0c;去年参加了VMware的培训&#xff0c;今年通过VMware Certified Professional (2V0-21.20)的考试&#xff0c;拿到证书。 要求 需要参加VMware的指定的培训&#xff0c;我在去年五…

【数据结构】 数组 array

一、什么是数组 连续内存空间&#xff0c;存储的一组相同类型的元素 二、常用操作 1.原理 access&#xff1a;通过索引直接读取元素的值 时间复杂度&#xff1a;O(1) search&#xff1a;遍历查找某个元素 时间复杂度&#xff1a;O(N) insert&#xff1a;插入位置后的元素依…

Generative AI 新世界 | 大语言模型(LLMs)在 Amazon SageMaker 上的动手实践

在上一篇《Generative AI 新世界&#xff1a;大型语言模型&#xff08;LLMs&#xff09;概述》中&#xff0c;我们一起探讨了大型语言模型的发展历史、语料来源、数据预处理流程策略、训练使用的网络架构、最新研究方向分析&#xff08;Amazon Titan、LLaMA、PaLM-E 等&#xf…

QT超市管理系统

QT超市管理系统 前言QT介绍.pro文件主文件&#xff08;main函数&#xff09;窗口函数&#xff08;mainwindow&#xff09;用户登录&#xff08;user_login&#xff09;超市系统数据库&#xff08;maketsql&#xff09;超市商品的增删改查(dlg_addmak)收款码界面(picture)结语 前…

亚马逊云科技探路可持续,数智创未来

气候变化是全人类的共同挑战。应对气候变化&#xff0c;事关永续发展&#xff0c;关乎人类前途命运。2020年中国在联合国大会上亚马逊云科技作出庄严承诺&#xff0c;要在2030年实现碳达峰&#xff0c;2060年实现碳中和&#xff0c;这是个全球性的规划&#xff0c;也是个庄严的…

Yolov8轻量化:MobileNetV3,轻量级骨架首选

1.轻量化网络简介 轻量化网络是指在保持模型性能的前提下,尽可能减小模型参数量和计算量的神经网络。这种网络通常被用于在移动设备等资源受限的场景中部署,以提高模型的实时性和运行效率。 轻量化网络的设计思路可以包括以下几个方面: 去除冗余层和参数:通过剪枝、蒸馏等技…

MFC(五)菜单栏和工具栏

这篇文章我们来完成菜单设计和工具栏设计 菜单设计 1.点开资源视图>Menu>IDR_MAINFRAME 通过IDR_MAINFRAME我们可以编辑该资源定义&#xff0c;包括主菜单、其他菜单、工具栏等内容&#xff0c;IDR_MAINFRAME即为默认的主窗口的资源标识符 2.右键相应菜单>新插入&…

数据结构 --- 红黑树

红黑树也是一种自平衡的二叉搜索树&#xff0c;和AVL树比较&#xff0c;插入和删除时&#xff0c;旋转的次数更少。 红黑树的特性&#xff1a; 所有节点都有颜色&#xff1a;红色或者黑色所有null均视为黑色红色节点不能相邻根节点是黑色从根节点到任意一个叶子节点&#xff…

5分钟带你了解,SAS硬盘和SATA硬盘的区别?

一、SAS和SATA的关系 SAS的接口技术可以向下兼容SATA。具体来说&#xff0c;二者的兼容性主要体现在物理层和协议层的兼容。 在物理层&#xff0c;SAS接口和SATA接口完全兼容&#xff0c;SATA硬盘可以直接使用在SAS的环境中&#xff0c;从接口标准上而言&#xff0c;SATA是SAS的…

接口隔离原则:接口里的方法,你都用得到吗?

文章目录 前言接口隔离原则1、角色的合理划分2、定制服务3、接口污染 胖接口减肥总结 前言 在前面几篇文章中中&#xff0c;我们讲的设计原则基本上都是关于如何设计一个类。SRP 告诉我们&#xff0c;一个类的变化来源应该是单一的&#xff1b;OCP 说&#xff0c;不要随意修改…

Fiddler抓包工具之fiddler设置断点和简单的并发测试

断点有两种方式&#xff1a; 1、全局断点 2、局部断点 全局断点 全局断点的特点是&#xff1a;不能针对一个请求&#xff0c;是给所有抓到的请求打断点 全局断点如何设置&#xff1a; 1、快速设置断点&#xff1a;直接点击底部状态栏断点处 &#xff1b;点击第一下是请求…

比赛记录:Educational Codeforces Round 149 (Rated for Div. 2) A~D

传送门:CF 前提提要:这场狠狠的掉分.C题刚开始少了一个特判,导致自己对自己的构造方法产生了疑问,然后就一直在做无用思考,后来交的时候排名就贼后面,然后D题的题面简直稀烂(虽然D题看懂之后极其简单…),赛时根本看不懂D题意,最终rating掉完.不亏是教育场,被狠狠的教育了 A题…

Web的基本漏洞--命令执行漏洞

目录 一、命令执行漏洞 1.命令执行漏洞的原理 2.命令执行漏洞分类 3.命令执行漏洞的危害 4.命令执行漏洞的防范措施 5.命令执行漏洞的绕过 一、命令执行漏洞 命令执行漏洞是指攻击者可以随意执行系统命令。它属于高危漏洞之一&#xff0c;也属于代码执行的范畴。命令执行…

内置工具横向移动

IPCSchtasks IPC: IPC$是共享"命令管道"的资源&#xff0c;它是为了让进程通信而开放的命名管道&#xff0c;连接双方可以建立安全的通道并以此通道进行加密数据交换&#xff0c;从而实现对远程计算机的访问。 利用条件&#xff1a; 1、开放139、445 2、目标开启…

Node.js V10.24.1 安装步骤(node、cnpm、yarn、vue)

一、下载node.js 下载地址&#xff1a;Download | Node.js 要下载历史低版本请点击“Previous Releases” Previous Releases 本文章以V10.24.1为例 &#xff0c;下载64位msi 二、安装 下载完成后&#xff0c;一直点击Next直到安装完成&#xff0c;可以自己修改安装位置。…

09.二叉树

09.二叉树 1.树型结构 1.1概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&…