所有分类
  • 所有分类
  • 未分类

SpringBoot-使用attribute保存每次请求的用户信息

简介

说明

本文介绍如何使用HttpServletRequest的attribute来保存每次请求的用户信息。

保存之后,后边的操作就可以很方便地获取(Controller或者Service都可以,只要是在一个请求中)。

相关网址

也可以使用ThreadLocal保存每次请求的用户信息,见 :SpringBoot–使用ThreadLocal保存每次请求的用户信息 – 自学精灵

实例

下载源码

此隐藏内容仅限VIP查看升级VIP

代码结构

用户实体类

package com.knife.common.entity;

import lombok.Data;

@Data
public class UserDTO {
    private Long userId;

    private String userName;
}

写入attribute

读取head信息,然后attribute有多种方式,比如:

  1. 过滤器
  2. 拦截器
  3. ControllerAdvice
  4. AOP

本处我使用过滤器,因为从head获取用户数据的话,越早越好,过滤器是最先执行的。

过滤器类

package com.knife.example.common.filter.impl;

import com.knife.example.common.entity.UserDTO;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class TokenFilter implements Filter {
    @Override
    public void init(javax.servlet.FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain)
            throws IOException, ServletException {
        if (servletRequest instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
            String token = httpServletRequest.getHeader("token");
            // 此处实际应该根据header的token解析出用户

            // 本处为了简单,直接虚构一个用户
            UserDTO userDTO = new UserDTO();
            userDTO.setUserId(3L);
            userDTO.setUserName("Tony");

            // 设置attribute
            // 后边不需要手动去清除attribute,因为SpringMVC会自动清除
            httpServletRequest.setAttribute("user", userDTO);
        }

        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    }
}

过滤器配置类

package com.knife.example.common.filter;
import com.knife.example.common.filter.impl.TokenFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<TokenFilter> registrationBean() {
        FilterRegistrationBean<TokenFilter> filterRegistrationBean =
                new FilterRegistrationBean<>(new TokenFilter());
        filterRegistrationBean.addUrlPatterns("/*");

        return filterRegistrationBean;
    }
}

读出attribute

package com.knife.example.business.product.controller;
 
import com.knife.example.business.product.vo.ProductVO;
import com.knife.example.common.entity.UserDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Api(tags = "商品")
@RestController
@RequestMapping("product")
public class ProductController {

    @ApiOperation("查询详情")
    @GetMapping("detail")
    public ProductVO detail(Long id) {
        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();

        UserDTO userDTO = (UserDTO)request.getAttribute("user");
        System.out.println(userDTO.toString());

        //省略查数据库等逻辑
        return new ProductVO();
    }
}

测试

请求:http://localhost:8080/test

结果:后台打印如下内容:

1

评论2

请先

  1. 这个确实不如threadLocal方便
    老安 2023-09-13 0
    • 是的 而且ThreadLocal更通用,不仅仅适用于接口。
      自学精灵 2023-09-13 0
显示验证码
没有账号?注册  忘记密码?

社交账号快速登录