中职院校技能大赛教学能力比赛报名评审平台项目总结

项目地址

项目需求地址:http://www.qiantuxueye.com/projectDetail?classId=31&indexId=118
本人项目代码仓库地址:https://gitee.com/Yuan_Ya_Jie/pingshen-test/tree/master

项目详情

本次项目耗费一周左右,鉴权使用springsecurity+jwt,文件存储使用oss等等。项目需求整体看起来不是特别难,可能MP4的文件处理与excel导入用户时的角色添加会耗费比较多的精力。
本次项目与双选项目需求基本一致,需要管理员控制比赛时间并且接口里做比赛时间的校验。双选时的解决思路是将比赛时间流程存入redis,在接口里拿出来调用做校验,现在想想真是很不妙,重复的代码太多了。所以这个项目就提供了三种解决思路,第一种是将校验包装成一个类,在接口里调用校验方法,如果比赛时间冲突则抛出异常。第二种是将校验包装成一个注解,只需要在接口上添加注解就可以完成比赛时间校验。第三种则是使用AOP完成校验。这三种校验方式后两种我平时基本不会怎么用到,所以之后会将这两种校验方法都实现一下。

项目框架及代码

项目的所有代码我已提交至个人仓库:https://gitee.com/Yuan_Ya_Jie/pingshen-test/tree/master
这里简单说一下本次项目中个人写起来不是很熟练的代码块

jwt登录校验

jwt+springsecurity的原理就是用户登录生成一个token,下次请求带着token过来会先经过jwt的过滤器,如果token有效则在jwt的过滤器中执行springsecurity的登录流程并在之后的spirngsecurity本身的过滤器中跳过校验,如果无效抛出异常,没有携带则跳过执行springsecurity本身的校验过滤器:

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
 
    /**
     * JWT数据的密钥
     */
    private String secretKey = "fgfdsfadsfadsafdsafdsfadsfadsfdsafdasfdsafdsafdsafds4rttrefds";
 
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        System.out.println("JwtAuthenticationFilter.doFilterInternal()");
        System.out.println("清除Spring Security上下文中的数据");
        SecurityContextHolder.clearContext();
        String jwt = request.getHeader("Authorization");
        System.out.println("从请求头中获取到的JWT=" + jwt);
        if (!StringUtils.hasText(jwt)) {
            System.out.println("请求头中无JWT数据,当前过滤器将放行");
            filterChain.doFilter(request, response); // 继续执行过滤器链中后续的过滤器
            return; // 必须
        }
 
        // 注意:此时执行时,如果请求头中携带了Authentication,日志中将输出,且不会有任何响应,因为当前过滤器尚未放行
        // 以下代码有可能抛出异常的
        // TODO 密钥和各个Key应该统一定义
        String username = null;
        String permissionsString = null;
        try {
            System.out.println("请求头中包含JWT,准备解析此数据……");
            Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
            username = claims.get("username").toString();
            permissionsString = claims.get("permissions").toString();
            System.out.println("username=" + username);
            System.out.println("permissionsString=" + permissionsString);
        } catch(Exception e){
        	return;
        }
 
        List<SimpleGrantedAuthority> permissions
                = JSON.parseArray(permissionsString, SimpleGrantedAuthority.class);
        System.out.println("从JWT中获取到的权限转换成Spring Security要求的类型:" + permissions);
        Authentication authentication
                = new UsernamePasswordAuthenticationToken(username, null, permissions);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        System.out.println("将解析得到的用户信息传递给Spring Security");
        // 放行
        System.out.println("JwtAuthenticationFilter 放行");
        filterChain.doFilter(request, response);
    }
 
}

Excel生成

public void getTeacherSample(HttpServletResponse response) throws IOException {
        //创建表
        List<List<String>> list = ListUtils.newArrayList();
        //创建表头
        List<String> head0 = ListUtils.newArrayList();
        List<String> head1 = ListUtils.newArrayList();
        List<String> head2 = ListUtils.newArrayList();
        List<String> head3 = ListUtils.newArrayList();
        List<String> head4 = ListUtils.newArrayList();
        head0.add(JOB_ID);
        head1.add(NAME);
        head2.add(SEX);
        head3.add(FACULTY);
        head4.add(ROLE);

        list.add(head0);
        list.add(head1);
        list.add(head2);
        list.add(head3);
        list.add(head4);
        //创建表内容
        List<List<String>> dataList = ListUtils.newArrayList();
        List<String> data = ListUtils.newArrayList();
        data.add("例:12345678987");
        data.add("张三");
        data.add("男");
        data.add("北京大学");
        data.add("参赛教师");
        dataList.add(data);
        //使用URLEncoder,不然输出时会中文乱码
        String fileName = URLEncoder.encode(TEACHER_SAMPLE, "UTF-8").replaceAll("\\+", "%20");
        //设置内容的颜色
        WriteCellStyle style = new WriteCellStyle();
        WriteFont writeFont = new WriteFont();
        writeFont.setColor(IndexedColors.RED.getIndex());
        style.setWriteFont(writeFont);
        HorizontalCellStyleStrategy cellStyleStrategy = new HorizontalCellStyleStrategy(new WriteCellStyle() , style);
        //设置response信息
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
            EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(cellStyleStrategy)
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(15))
                    .head(list)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet("模板")
                    .doWrite(dataList);
        } catch (Exception e) {
            //重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            //输出错误信息
            R result = R.fail();
            response.getWriter().println(JSON.toJSONString(result));
        }
    }

Excel导入用户的Listener处理

@Slf4j
public class UserListener implements ReadListener<SysUser> {
    //每隔一百条存储数据
    private static final int BATCH_COUNT = 100;
    private List<SysUser> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    public static List<String> list = new ArrayList<>();

    private final UserMapper userMapper;
    private final UserService userService;
    private final PasswordEncoder passwordEncoder;
    private final DeptMapper deptMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMapper roleMapper;

    public UserListener(UserService userService , UserMapper userMapper , PasswordEncoder passwordEncoder,DeptMapper deptMapper,UserRoleMapper userRoleMapper , RoleMapper roleMapper){
        this.userService = userService;
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
        this.deptMapper = deptMapper;
        this.userRoleMapper = userRoleMapper;
        this.roleMapper = roleMapper;
    }



    @Override
    public void invoke(SysUser user, AnalysisContext analysisContext) {

        log.info("解析到一条数据:{}" , JSON.toJSONString(user));
        if(exist(user)){
            list.add(user.getUserName());
        }else{
            String encode = passwordEncoder.encode("123456");
            user.setPassword(encode);
            cachedDataList.add(user);
        }

        if(cachedDataList.size() >= BATCH_COUNT){
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }

        log.info("存储完成");
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if(!cachedDataList.isEmpty()){
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
        log.info("所有数据解析完成!");
    }

    private void saveData(){
        log.info("{}条数据,开始存储数据库!" , cachedDataList.size());
        for (SysUser user : cachedDataList) {
            SysDept dept = deptMapper.selectOne(new QueryWrapper<SysDept>().eq("dept_name", user.getDeptName()));
            user.setDeptId(dept.getDeptId());
            userService.save(user);
            SysRole roleName = roleMapper.selectOne(new QueryWrapper<SysRole>().eq("role_name", user.getRole()));
            userRoleMapper.insert(new SysUserRole(user.getUserId() , roleName.getRoleId()));
        }
        log.info("存储数据库成功!");
    }

    private boolean exist(SysUser user){
        SysUser user1 = userMapper.selectOne(new QueryWrapper<SysUser>().eq("user_name" , user.getUserName()));
        return user1!=null;
    }
}

总结

这次项目复习了springsecurity的使用和原理,收获很大!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
网络空间安全技能大赛C模块是针对网络安全领域的C语言编程技能进行考查和竞赛的一个模块。 首先,在网络空间安全,C语言是一种常用的编程语言,因为它具有高效、快速、可移植性好等特点,所以许多网络安全工具和系统都是用C语言开发的。因此,熟练掌握C语言的编程技能对于从事网络安全工作的人来说是非常重要的。C模块就是为了衡量参赛选手在C语言编程方面的掌握程度而设置的。 在网络空间安全,C语言的编程技能主要包括以下方面: 1. 基本语法和数据类型:参赛选手需要熟悉C语言的基本语法和数据类型,如变量的定义和使用、循环和条件语句的应用等。 2. 函数和指针:C语言的函数和指针是非常重要的概念,参赛选手需要掌握函数的定义和调用、指针的使用等。 3. 数据结构和算法:网络安全常用的一些数据结构和算法,如数组、链表、栈、队列、排序算法等,参赛选手需要掌握它们的实现和应用。 4. 内存管理和安全:C语言的内存管理是一个重要的问题,在网络安全尤为关键。参赛选手需要了解内存分配和释放的方法,并注意防止内存泄漏和缓冲区溢出等安全问题。 5. 文件操作和网络编程:网络安全工具和系统通常会涉及到文件操作和网络编程,参赛选手需要掌握文件的读写操作和网络通信的基本知识。 通过参加网络空间安全技能大赛C模块的竞赛,选手可以通过各种练习和实际项目来提高自己在C语言编程方面的能力,从而更好地应对和解决网络安全领域的挑战和问题。同时,C模块的竞赛结果也可以为企业、机构等招聘单位提供一个评估选手C语言编程技能的参考依据。总的来说,C模块是网络空间安全技能大赛的一个重要环节,对于网络安全人才的培养和选拔有着重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值