spring boot 1.5.4 整合redis、拦截器、过滤器、监听器、静态资源配置(十六)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

1      Spring Boot整合redis和缓存

Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch, SolrCassandra

 

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库。

redis官网:https://redis.io/

redis中文社区:http://www.redis.cn/

 

1.1  集成redis

项目spring-boot-jsp源码:

spring-boot相关项目源码:

码云地址:https://git.oschina.net/wyait/springboot1.5.4.git

github地址https://github.com/wyait/spring-boot-1.5.4.git

 

1pom文件导入redis依赖

<dependency>

        <!--导入redis依赖 -->

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-redis</artifactId>

        <version>1.3.0.RELEASE</version>

      </dependency>

2,更改配置文件application

# Redis数据库索引(默认为0

spring.redis.database=0

# Redis服务器地址

spring.redis.host=192.168.10.100

# Redis服务器连接端口

spring.redis.port=6379

# Redis服务器连接密码(默认为空)

spring.redis.password=

连接池最大连接数(使用负值表示没有限制)

spring.redis.pool.max-active=10

连接池最大阻塞等待时间(使用负值表示没有限制)

spring.redis.pool.max-wait=-1

连接池中的最大空闲连接

spring.redis.pool.max-idle=8

连接池中的最小空闲连接

spring.redis.pool.min-idle=0

连接超时时间(毫秒)

spring.redis.timeout=0

其中spring.redis.database的配置通常使用0即可,Redis在配置的时候可以设置数据库数量,默认为16,可以理解为数据库的schema

3CatController中新增方法,向redis中设置基本类型数据:

@Autowired

   privateStringRedisTemplate stringRedisTemplate;

 

   @RequestMapping("/setRedis")

   @ResponseBody

   publicString setRedis() {

      //保存字符串

      stringRedisTemplate.opsForValue().set("token:aaa","111");

      return"ok";

   }

4,启动,访问,redis工具查看,已经设置成功!

wKioL1ncTBiz_9n0AAAFwaJh7rs146.png


通过上面这段极为简单的测试案例演示了如何通过自动配置的StringRedisTemplate对象进行Redis的读写操作,该对象从命名中就可注意到支持的是String类型。如果有使用过spring-data-redis的开发者一定熟悉RedisTemplate<K, V>接口,StringRedisTemplate就相当于RedisTemplate<String,String>的实现。

 

除了String类型,实战中我们还经常会在Redis中存储对象,这时候我们就会想是否可以使用类似RedisTemplate<String, User>来初始化并进行操作。但是Spring Boot并不支持直接使用,需要我们自己实现RedisSerializer<T>接口来对传入对象进行序列化和反序列化,下面我们通过一个实例来完成对象的读写操作。

 

redis中保存引用类型数据

,比如cat对象:

1,自定义RedisConfig/RedisService/HashService。参考相关文件

2,编写Controller

   @Autowired

   privateRedisService redisService;

 

   @RequestMapping("/setCatRedis")

   @ResponseBody

   publicString setRedis() {

      try{

        Catcat = new Cat("小黑", 5);

        redisService.set("token:cat1",cat, 5000L);

        Catc = new Cat("小花", 6);

        redisService.set("token:cat2",c, 5000L);

        return"ok";

      }catch (Exception e) {

        e.printStackTrace();

      }

      return"fail";

   }

启动,测试:

wKiom1ncu02yIUPeAAAOKR2zFWk496.png

 

解决redis中保存keyvalue乱码问题:

/**

     * 设置数据存入 redis 的序列化方式

     *

     * @param redisTemplate

     * @param factory

     */

    private voidinitDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate,RedisConnectionFactory factory) {

      //StringRedisSerializer解决key中午乱码问题。//Long类型不可以会出现异常信息;

        redisTemplate.setKeySerializer(newStringRedisSerializer());

        redisTemplate.setHashKeySerializer(newStringRedisSerializer());

       redisTemplate.setHashValueSerializer(newJdkSerializationRedisSerializer());

        //value乱码问题:GenericJackson2JsonRedisSerializer

      //redisTemplate.setValueSerializer(newJdkSerializationRedisSerializer());

        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

       redisTemplate.setConnectionFactory(factory);

    }

 

GenericJackson2JsonRedisSerializer也可以自定义valuejson格式,参考博客:

https://my.oschina.net/superwen/blog/885879

 

2      Spring Boot添加过滤器、拦截器和监听器

 

主要就是两步:

§  1,创建我们自己的拦截器类并实现 HandlerInterceptor 接口

§  2,其实重写WebMvcConfigurerAdapter中的addInterceptors方法把自定义的拦截器类添加进来即可

 

 

内容如下:

 

spring boot过滤器和拦截器 demo

 

项目mybatis-spring-boot 源码:https://git.oschina.net/wyait/springboot1.5.4.git

 

2.1  拦截器

 

@WebServlet

public class ActionInterceptorimplements HandlerInterceptor {

 

    @Override

    public boolean preHandle(HttpServletRequestrequest, HttpServletResponse response, Object handler)

            throws Exception {

        // System.out.println(">>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");

 

        // 获取系统时间

        Calendar ca = Calendar.getInstance();

        int hour =ca.get(Calendar.HOUR_OF_DAY);

        // 设置限制运行时间 0-4

        if (hour < 4) {

            return true;

        }

        return false;

    }

 

    @Override

    public void postHandle(HttpServletRequestrequest, HttpServletResponse response, Object handler,

            ModelAndView modelAndView) throwsException {

        //System.out.println(">>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");

 

    }

 

    @Override

    public voidafterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex)

            throws Exception {

        // System.out.println(">>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet

        // 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");

    }

}

 

拦截器使用:  关于注解我使用的是@Component 其实也可能声明成配置

 

@Component

public class ApplicationConfigextends WebMvcConfigurerAdapter {

 

    @Override

    public voidaddInterceptors(InterceptorRegistry registry) {

        // 多个拦截器组成一个拦截器链

        // addPathPatterns 用于添加拦截规则

        // excludePathPatterns 用户排除拦截

        registry.addInterceptor(newActionInterceptor()).addPathPatterns("/service/extract/json/**");

       super.addInterceptors(registry);

    }

}

 

 

2.2  过滤器

 

定义:

 public class ActionFilter implements Filter {

 

    @Override

    public void init(FilterConfig filterConfig)throws ServletException {

 

    }

 

    @Override

    public void doFilter(ServletRequestrequest, ServletResponse response, FilterChain chain)

            throws IOException,ServletException {

        // 获取系统时间

        Calendar ca = Calendar.getInstance();

        int hour =ca.get(Calendar.HOUR_OF_DAY);

        // 设置限制运行时间 0-4

        if (hour < 4) {

            HttpServletResponse httpResponse =(HttpServletResponse) response;

           httpResponse.setCharacterEncoding("UTF-8");

           httpResponse.setContentType("application/json;charset=utf-8");

           

            // 消息

            Map<String, Object>messageMap = new HashMap<>();

            messageMap.put("status","1");

            messageMap.put("message","此接口可以请求时间为:0-4");

            ObjectMapper objectMapper=newObjectMapper();

            String writeValueAsString =objectMapper.writeValueAsString(messageMap);

           response.getWriter().write(writeValueAsString);

           

        } else {

            chain.doFilter(request, response);

        }

 

    }

 

    @Override

    public void destroy() {

 

    }

 

}

 

使用:

 

@Component

public class ApplicationConfig {

 

 

@Bean

@Order(1)//过滤器执行顺序(优先:小到大)

    public FilterRegistrationBean  filterRegistrationBean() {

        FilterRegistrationBean registrationBean= new FilterRegistrationBean();

        ActionFilter actionFilter = newActionFilter();

       registrationBean.setFilter(actionFilter);

        List<String> urlPatterns = newArrayList<String>();

       urlPatterns.add("/service/extract/json/*");

        registrationBean.setUrlPatterns(urlPatterns);

        return registrationBean;

    }

   

 

}

2.3  监听器

 

监听器(Listener)的注入配置方法和Servlet 一样,有两种方式:代码注入或者注解注入配置

 

2.3.1    代码注入方式【推荐】

 

通过代码方式注入过滤器

  • @Configuration配置类中添加bean:

    @Bean

    public ServletListenerRegistrationBeanservletListenerRegistrationBean(){

        ServletListenerRegistrationBeanservletListenerRegistrationBean = new ServletListenerRegistrationBean();

       servletListenerRegistrationBean.setListener(new IndexListener());

        return servletListenerRegistrationBean;

    }

 

  • 监听器实体IndexListener.Java类:

 

package com.example.Listener;

 

importjavax.servlet.ServletContextEvent;

importjavax.servlet.ServletContextListener;

 

public class IndexListenerimplements ServletContextListener{

 

    @Override

    public void contextDestroyed(ServletContextEventarg0) {

        System.out.println("IndexListenercontextDestroyed method");

       

    }

 

    @Override

    public voidcontextInitialized(ServletContextEvent arg0) {

        System.out.println("IndexListenercontextInitialized method");

       

    }

 

}

 

2.3.2    注解方式

 

  • 通过注解方式注入监听器

 

IndexListener2.Java

 

package com.example.Listener;

 

importjavax.servlet.ServletContextEvent;

importjavax.servlet.ServletContextListener;

importjavax.servlet.annotation.WebListener;

@WebListener

public class IndexListener2implements ServletContextListener{

 

    @Override

    public voidcontextDestroyed(ServletContextEvent arg0) {

        System.out.println("IndexListener2contextDestroyed method");

       

    }

 

    @Override

    public void contextInitialized(ServletContextEventarg0) {

        System.out.println("IndexListener2contextInitialized method");

       

    }

 

}

 

  • 把注解加到入口处启动即可

 

@SpringBootApplication

@ServletComponentScan

public classSpringBootSimpleApplication {

 

    public static void main(String[] args) {

       SpringApplication.run(SpringBootSimpleApplication.class, args);

    }

}

3      spring boot静态资源配置

 

前言

 

本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfigurerAdapter

正文

 

前面章节我们也有简单介绍过SpringBoot中对静态资源的默认支持,今天详细的来介绍下默认的支持,以及自定义扩展如何实现。

默认资源映射

 

Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。

 

建议大家使用Spring Boot的默认配置方式,提供的静态资源映射如下:

 

  • classpath:/META-INF/resources

 

  • classpath:/resources

 

  • classpath:/static

 

  • classpath:/public

 

在工程里面路径是这样:

wKiom1ncu1_B-I5mAADxl0xABV8982.png

 

上面这几个都是静态资源的映射路径,优先级顺序为:META-INF/resources > resources >static > public

 

大家可以自己在上面4个路径下都放一张同名的图片,访问一下即可验证。

 

还有,你可以随机在上面一个路径下面放上index.html,当我们访问应用根目录http://lcoalhost:8080时,会直接映射到index.html页面。

 

对应的配置文件配置如下:

 

wKioL1ncTGWhM-8mAADPINici20744.png

我们可以通过修改spring.mvc.static-path-pattern来修改默认的映射,例如我改成/wyait/**,那运行的时候访问http://lcoalhost:8080/wyait /index.html 才对应到index.html页面。

接管Spring BootWeb配置

如果Spring Boot提供的Sping MVC不符合要求,则可以通过一个配置类(注解有@Configuration的类)加上@EnableWebMvc注解来实现完全自己控制的MVC配置。

当然,通常情况下,Spring Boot的自动配置是符合我们大多数需求的。在你既需要保留Spring Boot提供的便利,有需要增加自己的额外的配置的时候,可以定义一个配置类并继承WebMvcConfigurerAdapter,无需使用@EnableWebMvc注解。

这里我们提到这个WebMvcConfigurerAdapter这个类,重写这个类中的方法可以让我们增加额外的配置,这里我们就介绍几个常用的。

自定义资源映射addResourceHandlers

比如,我们想自定义静态资源映射目录的话,只需重写addResourceHandlers方法即可

/**

 *

 * @项目名称:mybatis-spring-boot

 * @类名称:MyWebMvcConfig

 * @类描述:自定义静态资源映射路径和静态资源存放路径

 * @创建人:wyait

 * @创建时间:2017630上午8:48:33

 * @version

 */

@Configuration

public class MyWebMvcConfigextends WebMvcConfigurerAdapter {

   @Override

   publicvoid addResourceHandlers(ResourceHandlerRegistry registry) {

      registry.addResourceHandler("/images/**").addResourceLocations(

           "/images/");

      super.addResourceHandlers(registry);

   }

}

静态资源存放路径:

wKioL1ncTG6wPZIuAABZq30zIZI403.png

 

通过addResourceHandler添加映射路径,然后通过addResourceLocations来指定路径。我们访问自定义/images文件夹中的logo_t.png 图片的地址为http://127.0.0.1:8080/images/logo_t.png


如果你想指定外部的目录也很简单,直接addResourceLocations指定即可,代码如下:

@Configuration

public class MyWebMvcConfigextends WebMvcConfigurerAdapter {

   @Override

   publicvoid addResourceHandlers(ResourceHandlerRegistry registry) {

//    registry.addResourceHandler("/images/**").addResourceLocations(

//         "/images/");

      registry.addResourceHandler("/images/**").addResourceLocations(

           "file:D:/images/");

      super.addResourceHandlers(registry);

   }

}

 

addResourceLocations指的是文件放置的目录,addResoureHandler指的是对外暴露的访问路径

 

页面跳转addViewControllers

以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurerAdapter中的addViewControllers方法即可达到效果了

wKioL1ncTIPw-Go7AAE6sdwGC9k047.png

值的指出的是,在这里重写addViewControllers方法,并不会覆盖WebMvcAutoConfiguration中的addViewControllers(在此方法中,Spring Boot将“/”映射至index.html),这也就意味着我们自己的配置和Spring Boot的自动配置同时有效,这也是我们推荐添加自己的MVC配置的方式。

 



本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/1971108,如需转载请自行联系原作者

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
12天前
|
SQL Java 数据库连接
(自用)Spring常用配置
(自用)Spring常用配置
15 0
|
23天前
|
Java 调度 Spring
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
44 0
|
1月前
|
SQL Java 数据库连接
springboot中配置mybatis别名该怎么写?
springboot中配置mybatis别名该怎么写?
31 0
|
5天前
|
存储 安全 Java
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
13 0
|
5天前
|
安全 Java 数据库
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(上)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)
28 0
|
6天前
|
安全 Java Spring
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
Spring Security 5.7 最新配置细节(直接就能用),WebSecurityConfigurerAdapter 已废弃
18 0
|
6天前
|
安全 Java 应用服务中间件
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
24 0
江帅帅:Spring Boot 底层级探索系列 03 - 简单配置
|
12天前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
21 1
|
12天前
|
Java 数据库连接 Spring
简化配置,提高灵活性:Spring中的参数化配置技巧
简化配置,提高灵活性:Spring中的参数化配置技巧
19 0
|
12天前
|
Java Shell 测试技术
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析
24 0
一次配置,多场景适用:Spring Boot多套配置文件的深度剖析