当前位置: 首页 > 知识库问答 >
问题:

Spring MVC如何使HttpServletRequest字段线程安全?

谷弘致
2023-03-14

代码:

package com.test.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/")
public class Controller {
    private HttpServletRequest request;

    public HttpServletRequest getRequest() {
        return request;
    }
    @Autowired
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }
    @RequestMapping("safe-read")
    public void threadSafeRead() throws InterruptedException {
        System.out.println(request.getHeader("user-agent"));
        Thread.sleep(TimeUnit.MILLISECONDS.convert(5,TimeUnit.SECONDS));
        System.out.println(request.getHeader("user-agent"));
    }
}

当我同时执行两个请求时,执行的结果是:

  1. Mozilla/5.0(Windows NT 6.1; WOW64; rv: 26.0)Gecko/20100101 Firefox/26.0
  2. Mozilla/5.0(Windows NT 6.1; WOW64)AppleWebKit/537.36(KHTML,像壁虎)Chrome/32.0.1700.102Safari /537.36
  3. Mozilla/5.0(Windows NT 6.1; WOW64; rv: 26.0)Gecko/20100101 Firefox/26.0
  4. Mozilla/5.0(Windows NT 6.1; WOW64)AppleWebKit/537.36(KHTML,像壁虎)Chrome/32.0.1700.102Safari /537.36

在运行时字段中有类型com.sun.proxy.$Proxy45。Spring如何使其线程安全读取?

共有1个答案

潘俊楚
2023-03-14

仅对上面M.Deinum的评论进行一点扩展,有几种方法可以用来避免将请求引用作为控制器状态的一部分。

1)如前所述,直接注入请求作为方法签名的一部分。

2) 通过在方法签名中使用@RequestParam注释,只能使用您直接感兴趣的请求参数。

3) 看看RequestContextHolder类的Spring api文档。你可以这样做:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
            .currentRequestAttributes()).getRequest();

这可能对你有用,也可能没用。

希望这有帮助:-)

 类似资料:
  • 问题内容: 为了线程安全,是否应该是故意不可变的Java类’final’的所有字段(包括超字段),还是没有修饰符方法就足够了? 假设我有一个带有非最终字段的POJO,其中所有字段都是某种不可变类的类型。这个POJO有getters- setters和一个设置一些初始值的构造函数。如果我通过敲除修饰符方法来扩展此POJO,从而使其不可变,那么扩展类是否是线程安全的? 问题答案: 为了以线程安全的方式

  • 我有一个简单的静态日志记录类。但是,它肯定不是线程安全的,因为每个调用都试图写入同一个文件。我得到了这些例外情况: 什么是最好的方法使它的线程安全? 作为一个日志记录函数,我希望能够从代码的许多不同部分访问它(因此,我选择它为静态的原因)。然而,我想要使它成为线程安全的,我总是必须向它传递一个公共对象来lock(),我认为这违背了静态函数的目的。还是事实并非如此?

  • 问题内容: 据我所知,这是可变的,因此,如果多个线程试图访问和修改它,则不是线程安全的。我们如何使用客户端锁定或组合(包装器)使其成为线程安全的? 问题答案: 按照从好到坏的顺序: 根本不使用它,请查看Java 8的新Date and Time API。 完全不使用它,请查看jodatime 在所有的,使用不使用或一成不变的原始与代表 纪元时间 封装它。始终返回的防御性副本,从不引用内部对象 在实

  • 问题内容: 我想将Calendar用于某些静态方法并使用一个静态字段: 现在,我读到java.util.Calendar不是线程安全的。如何使该线程安全(应该是 静态的 )? 问题答案: 如果不是,则不能创建线程安全的东西。在的情况下,即使从中 读取 数据也不是线程安全的,因为它可以更新内部数据结构。 如果有可能,我建议改用Joda Time: 大多数类型是不可变的 不可变类型是线程安全的 无论如

  • 本文向大家介绍如何保证线程安全?相关面试题,主要包含被问及如何保证线程安全?时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 通过合理的时间调度,避开共享资源的存取冲突。另外,在并行任务设计上可以通过适当的策略,保证任务与任务之间不存在共享资源,设计一个规则来保证一个客户的计算工作和数据访问只会被一个线程或一台工作机完成,而不是把一个客户的计算工作分配给多个线程去完成。

  • 问题内容: 我是Go的新手,我需要创建一个线程安全的变量。我知道在Java中您只能使用关键字,但是似乎没有类似的东西存在。有什么方法可以同步变量? 问题答案: Java中的一种意思是仅允许单个线程(在任何给定时间)执行代码块。 在Go中,有很多构造可以实现该目标(例如互斥体,通道,等待组,中的原语),但是Go的谚语是: “不要通过共享内存进行通信;而是通过通信来共享内存。” 因此,不要锁定和共享变