2014-02-05 34 views
0

代碼:Spring MVC如何使HttpServletRequest字段線程安全?

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")); 
    } 
} 

當我在同時2個請求,該執行的結果是:

  1. 的Mozilla/5.0(Windows NT的6.1; WOW64; RV:26.0)壁虎/ 20100101 火狐/ 26.0
  2. 的Mozilla/5.0(Windows NT的6.1; WOW64)爲AppleWebKit/537.36(KHTML,像壁虎 )的Chrome/Safari的32.0.1700.102/537.36
  3. 的Mozilla/5.0(Windows NT的6.1; WOW64; RV:26.0 )壁虎/ 201 00101 Firefox/26.0
  4. Mozilla/5.0(Windows NT 6.1; WOW64)爲AppleWebKit/537.36(KHTML,像 壁虎)鉻/ 32.0.1700.102 Safari瀏覽器/ 537.36

在運行時字段具有類型com.sun.proxy.$Proxy45。 春天如何使它可以線程安全地閱讀?

+0

它注入的實際對象的代理和確實需要時(實際請求被綁定到當前執行的線程)的查找。但是,爲什麼你要注入'HttpServletRequest'?您可以簡單地將它作爲參數添加到您的方法中。我會認爲後者是一種更好的方法,然後注入它。 –

+0

謝謝,我認爲如此。它很有趣,它是如何工作的。 – user2187298

回答

0

只是爲了擴展上面M. Deinum的評論,可以使用一些方法來避免將請求的引用作爲控制器狀態的一部分。

1)如前所述,直接注入請求作爲方法簽名的一部分。

2)只能通過在方法簽名中使用@RequestParam註釋直接使用您直接感興趣的請求參數。

3)查看RequestContextHolder類的Spring API文檔。你可以做這樣的事情:

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

這可能會或可能不會對你有用。

希望這有助於:-)