java - Springmvc中在controller注入request会有线程安全问题吗
高洛峰
高洛峰 2017-04-17 17:57:04
0
10
579
@Controller
public class AController{

    @Autowire
    HttpServletRequest request;
    
    @RequestMapping("/test")
    public Result test(){
        System.out.println(request.toString());
        request.getHeader("uid");
    }
}

例如上述代码,
我使用Autowire注入request后,直接在controller的方法中使用request
由于controller默认是单例的,我在想是否会有线程安全问题。
因为我输出了requesthashcode发现每次请求hashcode都是一样的。
那么后面的request是否会覆盖当前request导致信息失真?

·····························补充··························

1、我想在controller的每个方法里都使用HttpServletRequest,那么每次在方法里都要声明我觉得就比较麻烦了?不知道大家怎么解决这个问题?
2、我这样写的原因是,我想通过继承一个父类的方式,让request作为父类的一个成员变量,这样可以在方法里直接使用。
3、我通过楼下叉叉哥的方式(之前就是这样写的)

public Result test(HttpServletRequest request){

    System.out.println(request.toString());
}

同样不断访问,或者用不同客户端访问。发现打印出来的每个请求的request的hashcode居然也是相同的,为什么?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

membalas semua(10)
巴扎黑

Terima kasih atas jawapan anda
Selepas ujian dan penerokaan saya.
Kesimpulannya ialah
menyuntik HttpServletRequest menggunakan @autowire adalah selamat untuk benang.
Saya menulis blog tentang proses pengesahan khusus
Jika anda berminat, anda boleh lihat Jika ada apa-apa yang salah, sila nyatakan.
Terima kasih sekali lagi kepada pengaturcara di tingkat atas yang dengan penuh semangat menjawab soalan saya

Klik saya untuk alamat blog

ps: Perbincangan di atas adalah mengenai Pengawal dalam mod tunggal

···

大家讲道理

Pertama sekali, pada dasarnya, Permintaan tidak boleh ditakrifkan sebagai ahli Pengawal, kerana kitaran hayat kedua-duanya terputus sepenuhnya Ini hanya akan menyebabkan Pengawal tidak dapat memanggil objek Permintaan yang betul.

Kedua, @Autowire ialah tugasan sekali sahaja, dan terdapat banyak objek Permintaan, jadi jika anda menulisnya seperti ini, Spring tidak akan tahu apa yang perlu dilakukan. Kerana tiada objek Permintaan apabila aplikasi bermula, ini akan menyebabkan permulaan gagal.

Ty80

Em, saya memperbodohkan diri sendiri dengan menumpukan pada menyelesaikan masalah kecil request masalah yang sama setiap kali dan terlupa topik itu.
Tambah@ModelAttributeMemang benar akan ada isu keselamatan benang!
...

Jika anda ingin menggunakan atribut objek dan mengendalikan keselamatan benang, terdapat kaedah yang sangat mudah, tetapi sangat kasar Gunakannya terus @Scope("prototype") untuk membenarkan Spring MVC menjana yang baharu setiap permintaan kelas Entiti...
Tetapi mengapa Spring MVC memerlukan singleton secara lalai? Sememangnya, kerana prestasi dan kelebihan kos bujang,
dan menulis @Scope("prototype") bermakna melepaskan kelebihan bujang.

Jadi ini memang cara, tetapi ia tidak baik saya memalukan semua orang, maaf.

@Controller
// @Scope("prototype")
public class AController{

    //@Autowired //如果采用非单例模式的话,用autowried也一样。
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    
    @ModelAttribute
    public void bindRequestObject(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }
    
    @RequestMapping("/test")
    public Result test(){
        System.out.println(request.toString());
        request.getHeader("uid");
    }
}
迷茫

1. Selepas Autowire menyuntik permintaan, akan ada masalah keselamatan apabila menggunakan pembolehubah instance
2 Ia akan menimpa permintaan
3

Saya fikir ia menyusahkan untuk menulis parameter dalam kaedah, jadi anda boleh melakukan ini:

@Controller
public class AControllre extends AbstractController {

    @RequestMapping("/test")
    public String test(){
        //使用
        String name = getRequest().getParameter("username");
        return "";
    }
}

class AbstractController {
    protected HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) 
                RequestContextHolder.getRequestAttributes()).getRequest();
    }
    protected HttpServletResponse getResponse() {
        return new ServletWebRequest(((ServletRequestAttributes) 
                RequestContextHolder.getRequestAttributes()).getRequest()).getResponse();
    }
}
PHPzhong

Ini adalah kali pertama saya melihat cara penulisan ini. Mengapa tidak menulis seperti ini?

@Controller
public class AController{
    
    @RequestMapping("/test")
    public Result test(HttpServletRequest request){
        System.out.println(request.toString());
        request.getHeader("uid");
    }
}

Malah, dalam kebanyakan kes, permintaan tidak perlu diluluskan sebagai parameter Contohnya, jika anda ingin mendapatkan uid dalam pengepala permintaan, anda boleh menulis seperti ini:

@Controller
public class AController{
    
    @RequestMapping("/test")
    public Result test(@RequestHeader("uid") String uid) {
        System.out.println(uid); // 相当于request.getHeader("uid")
    }
}
阿神

Jika anda menulisnya seperti itu, isu keselamatan benang pasti akan berlaku, kerana setiap pengawal pada musim bunga adalah tunggal secara lalai, jadi permintaan anda akan dikongsi oleh urutan lain, jadi anda disyorkan untuk menulisnya dengan cara yang sama seperti @ChaCha哥.

伊谢尔伦

Akan ada. Dalam Servlet, parameter atribut ditulis dalam kaedah supaya ia tidak akan dikongsi

洪涛

Jika anda menulis seperti ini, pasti akan ada isu keselamatan benang, kerana pengawal adalah tunggal secara lalai, yang bermaksud bahawa berbilang permintaan akan berkongsi objek HttpServletRequest Jika anda menambah @Scope("prototaip"), akan ada tiada masalah

Ty80

Akan ada isu keselamatan benang, saya cadangkan anda membaca artikel inihttp://www.xuebuyuan.com/1628190.html

巴扎黑

Mana-mana pembolehubah contoh kelas mempunyai potensi risiko keselamatan urutan Kod perlu memastikan bahawa pembolehubah contoh selamat di bawah berbilang urutan atau memastikan kelas itu diakses oleh hanya satu urutan pada masa yang sama.
Masalah berbilang benang dalam contoh anda tidak dapat dielakkan Anda harus mengikuti tutorial Spring dan menulisnya dengan cara yang betul dan memahaminya terlebih dahulu, kemudian lakukan yang rumit.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan