2013-02-15 254 views
3

我有HomeService.java,當我去/test的網址,它打印HomeService::test一次,但當我去/play網址它打印HomeService::play兩次。我怎樣才能讓我的/play方法只被調用一次?爲什麼我的球衣方法會被調用兩次?

我去的網址是

http://127.0.0.1:8080/Home/rest/main/test 
http://127.0.0.1:8080/Home/rest/main/play 

HomeService.java:

@Path("/main") 
public class HomeService 
{ 

    @GET 
    @Path("/test") 
    @Produces("text/plain") 
    public String test() 
    { 
    System.out.println("HomeService::test"); 
    return "Running..."; 
    } 

    @GET 
    @Path("/play") 
    @Produces("video/mpeg") 
    public StreamingOutput play() 
    { 
    System.out.println("HomeService::play"); 
    return new StreamingOutput() 
    { 

    @Override 
    public void write(java.io.OutputStream outputStream) {} 
    } 
} 

的web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 
    <display-name>Home</display-name> 

    <servlet> 
     <servlet-name>jersey-servlet</servlet-name> 
     <servlet-class> 
         com.sun.jersey.spi.container.servlet.ServletContainer 
     </servlet-class> 
     <init-param> 
      <param-name>com.sun.jersey.config.property.packages</param-name> 
      <param-value>com.home</param-value> 
     </init-param> 
     <init-param> 
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>jersey-servlet</servlet-name> 
     <url-pattern>/rest/*</url-pattern> 
    </servlet-mapping> 

</web-app> 

如果有更多的信息需要讓我知道。

編輯:所以,我跑了tcpdump的,這是輸出:

# ./tcpdump -s 128 -A -v -i any port 8080|grep 'play' 
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 128 bytes 
...u...uGET /Home/rest/main/play HTTP/1.1 
.. ... .GET /Home/rest/main/play HTTP/1.1 

,然後再

........GET /Home/rest/main/play HTTP/1.1 
........GET /Home/rest/main/play HTTP/1.1 
+1

你對客戶使用什麼?你是否100%確定客戶只發送一個請求?你有一個簡單的方法來監視HTTP請求來驗證這一點(HTTP日誌,或Wirshark/HTTP嗅探器)。我只問這個,因爲沒有別的東西會跳出來作爲一個可能的原因。 – EJK 2013-02-15 17:22:14

+0

@EJK我已經用tcpdump輸出更新了我的問題,wget也只能擊中它一次 – Grammin 2013-02-15 17:36:34

回答

4

這是因爲客戶端請求兩次。您可能會期望在媒體(音頻/視頻)請求上出現這種情況。大多數媒體播放器會測試服務器是否支持範圍請求,以便通過多個HTTP連接更有效地進行緩衝。如果您仔細查看請求標題,可能會看到RangeIf-Range標題。如果您的服務器支持它,則客戶端將發送多個範圍請求,請求在指定範圍內開始和結束的媒體文件的較小塊。另外,如果客戶端快進到特定時刻(例如1分鐘後),則媒體播放器可以放棄請求併發送新請求,請求從該位置開始的範圍。

您無法阻止客戶端多次請求它。如果你的服務不支持範圍請求,你最好把它做成一個。 servletcontainer的內置默認servlet支持它。因此,如果您將媒體文件放在公共Web內容中,並讓客戶端直接請求而不是通過Web服務,那麼它會擔心這一點。

請注意,這個問題與澤西島完全無關,儘管我有些印象是它是媒體流特定工作的錯誤工具。

相關問題