java - Spring Boot 2 - 识别方法是通过 Controller 还是异步服务触发

标签 java spring spring-boot

我有一个 Spring Boot 微服务应用程序。我有一个要求,

  • 如果通过 Controller 调用方法(即某些用户点击 API),则响应应该是登录用户的用户名。
  • 如果从任何非 Controller (例如计划任务、异步方法等)调用方法,则响应应该是默认用户,即系统。

所以,我有一个 UserDetailService 方法,我想在其中编写此逻辑。

@Service
public class UserDetailsService
{
    @Autowired
    WebClient.Builder webClientBuilder;

    @Autowired
    HttpServletRequest request;

    @Value("${common.serverurl}")
    private String reqUrl;

    public UserReturnData getCurrentUser()
    {
        if (request == null)
        {
            UserReturnData userDetails = new UserReturnData();
            userDetails.setId((long) 404);
            userDetails.setUsername("system");
            return userDetails;
        } else
        {
            UserReturnData userDetails = webClientBuilder.build().get().uri(reqUrl + "user/me")
                    .header("Authorization", request.getHeader("Authorization")).retrieve()
                    .bodyToMono(UserReturnData.class).block();
            return userDetails;
        }
    }
}

为了检查方法是否从 Controller 触发,我自动连接 HttpServletRequest 并将其与 null 进行比较。 但是,当从异步服务触发此操作时,它会抛出异常“您是否指的是实际 Web 请求之外的请求属性”

是否有其他方法可以确定该方法从何处触发。逻辑很简单,如果涉及 Controller ,即如果涉及某些 API 调用,则返回登录用户,否则返回默认用户。

最佳答案

SecurityContextHolder可用于检查当前线程是否与登录用户关联。以下方法演示了使用方法。

public String getCurrentUser() {
    String userName="SYSTEM";
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication!=null && !(authentication instanceof AnonymousAuthenticationToken)) {
        userName = authentication.getName();
    }
    return userName;
}

由@Sridhar Patnaik 贡献。引用R.G.的评论,按以下方式处理

  1. 删除了 Autowiring 的 HttpServletRequest
  2. 已创建请求变量 HttpServletRequest 请求 = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest();
  3. 为请求添加了空检查。因此,如果涉及 Controller ,请求将不为空,并且将返回登录用户。否则,系统用户将被返回
@Service
public class UserDetailsService
{
    @Autowired
    WebClient.Builder webClientBuilder;

    /*
     * @Autowired HttpServletRequest request;
     */

    @Value("${common.serverurl}")
    private String reqUrl;

    public UserReturnData getCurrentUser() throws Exception
    {
        try
        {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                    .getRequest();
            if (request == null)
            {
                UserReturnData userDetails = new UserReturnData();
                userDetails.setId((long) 404);
                userDetails.setUsername("system");
                return userDetails;
            }

            else
            {
                UserReturnData userDetails = webClientBuilder.build().get().uri(reqUrl + "user/me")
                        .header("Authorization", request.getHeader("Authorization")).retrieve()
                        .bodyToMono(UserReturnData.class).block();
                return userDetails;
            }

        } catch (Exception e)
        {
            throw new Exception("Something Went Wrong !");
        }}

关于java - Spring Boot 2 - 识别方法是通过 Controller 还是异步服务触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65838291/

相关文章:

java - 使用 spring security 时 Spring boot @Autowired 存储库实例为 null

java - 使用java从Oauth2 Rest api获取访问 token

spring-boot - 无法发布具有许多(超过 256 个)值的表单

java - Android:使用数组项填充 ListView

java - "2D"数组的输出/索引不正确

java - Spring Security JWT 刷新 token 未过期

spring - JPA 查询中的 ClassCastException

Spring:如何将对象从过滤器传递到 Controller

javascript - 获取json字符串请求参数

java - 我的MapReducer无法正常工作-无法获得输出