爆破专栏丨SpringBoot2(3),2024年最新复习指南

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
img

正文

 ObjectMapper是Jackson操作的核心,Jackson所有的json操作都是在ObjectMapper中实现的。

om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
设置所有访问权限以及所有的实际类型都可序列化和反序列化

om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Jackson的ObjectMapper.DefaultTyping.NON_FINAL属性的作用。

4.4 Jackson序列化特性简介

在JDK1.8中的时间类,采用了一套了新的API,但是在反序列化中,会出现异常。

com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Cannot construct instance of  java.time.LocalDate (no Creators, like default construct, exist):
cannot deserialize from Object value (no delegate- or property-based Creator)

5. 创建RedisConfig配置类

我们需要创建一个RedisConfig,在这个类中对Redis进行配置,创建一个RedisTemplate对象,并对Redis的缓存进行设置。

package com.yyg.boot.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/8
 * @Description Description
 */
@Configuration
public class RedisConfig {

    @Value("${spring.redis.timeout}")
    private Duration timeToLive = Duration.ZERO;

    /**
     * 由于原生的redis自动装配,在存储key和value时,没有设置序列化方式,故自己创建redisTemplate实例
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        // 值采用json序列化
        template.setValueSerializer(jacksonSeial);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        // 设置hash key 和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jacksonSeial);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 解决jdk1.8中新时间API的序列化时出现com.fasterxml.jackson.databind.exc.InvalidDefinitionException的问题
     */
    @Bean
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // 配置序列化(解决乱码的问题)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(timeToLive)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        return  RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

}

6. 创建SpringContextUtil工具类

为了方便获取ApplicationContext对象,这里我封装了一个SpringContextUtil工具类。

package com.yyg.boot.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/8
 * @Description Description
 */
@Service
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.context = applicationContext;
    }

    public static <T> T getBean(String name, Class<T> requiredType) {
        return context.getBean(name, requiredType);
    }

}
7. 创建RedisUtil工具类

RedisTemplate模板类可以对Redis进行添加,删除,设置缓存过期时间等设置。
RedisTemplate中主要的API是:
opsForValue()集合使用说明

  • set(K key,V value) 新建缓存
    redisTemplate.opsForValue().set(“key”,“value”);
  • get(Object key) 获取缓存
    redisTemplate.opsForValue().get(“key”);
package com.yyg.boot.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.TimeUnit;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/8
 * @Description Description
 */
@Slf4j
public class RedisUtil {

    //@Autowired
    //private static RedisTemplate<String, Object> redisTemplate;

    private static final RedisTemplate<String, Object> redisTemplate = SpringContextUtil.getBean("redisTemplate", RedisTemplate.class);

    /**********************************************************************************
     * redis-公共操作
     **********************************************************************************/

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public static boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("【redis:指定缓存失效时间-异常】", e);
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效;如果该key已经过期,将返回"-2";
     */
    public static long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public static boolean exists(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("【redis:判断{}是否存在-异常】", key, e);
            return false;
        }
    }


    /**********************************************************************************
     * redis-String类型的操作
     **********************************************************************************/

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public static boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            log.error("【redis:普通缓存放入-异常】", e);
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public static boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            log.error("【redis:普通缓存放入并设置时间-异常】", e);
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return
     */
    public static long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return
     */
    public static long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public static void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }


    /**
     * 获取缓存
     *
     * @param key   redis的key
     * @param clazz value的class类型
     * @param <T>
     * @return value的实际对象
     */
    public  static <T> T get(String key, Class<T> clazz) {
        Object obj = key == null ? null : redisTemplate.opsForValue().get(key);
        if (!obj.getClass().isAssignableFrom(clazz)) {
            throw new ClassCastException("类转化异常");
        }
        return (T) obj;
    }

    /**
     * 获取泛型
     *
     * @param key 键
     * @return 值
     */
    public static Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
}
8. 创建RedisService及其实现类

为了操作方便,我封装一个RedisService接口类,在这里封装存值和取值方法。

8.1 RedisService接口

package com.yyg.boot.service;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/8
 * @Description Description
 */
public interface RedisService {

    void setObj(String key, Object obj, long timeout);

    Object getObj(String key);

}

8.2 RedisServiceImpl类

然后对RedisService接口进行实现。

package com.yyg.boot.service.impl;

import com.yyg.boot.service.RedisService;
import com.yyg.boot.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/4/8
 * @Description Description
 */
@Service
public class RedisServiceImpl implements RedisService {

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void setObj(String key, Object obj, long timeout) {
        redisUtil.set(key,obj,timeout);
    }

    @Override
    public Object getObj(String key) {
        return redisUtil.get(key);
    }
}
9. 创建UserController测试接口

接着我创建一个UserController,编写几个URL接口进行测试。

package com.yyg.boot.web;

import com.yyg.boot.domain.User;
import com.yyg.boot.repository.UserRepository;
import com.yyg.boot.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author 一一哥Sun
 * @Date Created in 2020/3/31
 * @Description Description
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RedisService redisService;

    @GetMapping("/{id}")
    public User findUserById(@PathVariable("id") Long id) {
        User user = (User) redisService.getObj("user" + id);
        if (user == null) {
            user = userRepository.findById(id).get();
            redisService.setObj("user" + id, user, 1000 * 60 * 2);
            return user;
        }
        return user;
    }

}

10. 创建入口类

最后我们再编写一个程序入口类,启动项目进行测试。

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

😝朋友们如果有需要的话,可以联系领取~

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

2️⃣视频配套工具&国内外网安书籍、文档
① 工具

② 视频

image1

③ 书籍

image2

资源较为敏感,未展示全面,需要的最下面获取

在这里插入图片描述在这里插入图片描述

② 简历模板

在这里插入图片描述

因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

源较为敏感,未展示全面,需要的最下面获取

在这里插入图片描述在这里插入图片描述

② 简历模板

在这里插入图片描述

因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-sLFaf8U8-1713374651964)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值