【问题标题】:restlet get is not sending done confirmationrestlet get 没有发送完成确认
【发布时间】:2013-06-11 00:13:26
【问题描述】:

您好,我有一个简单的 restlet get 方法,它返回一个静态字符串。如下所示:

@Get
    public String represent() {
        return "mystring\r\n";
    }

低级 c 应用程序通过进入读取循环调用此 get。它永远不会收到完成确认信号,表明没有更多数据可供读取,并在 20 秒后超时。我需要发送代码来提醒客户端应用程序没有更多数据了吗?还是说get完了?

【问题讨论】:

    标签: http rest get restlet restlet-2.0


    【解决方案1】:

    [注意:下面编写的代码部分基于http://www.restlet.org上的示例]

    HTTP 1.0 和 1.1 有一个名为 Content-Length 的标头。无论该标头的数值是什么,都是 HTTP 响应正文的长度。在 HTTP 1.1 中更进一步,还有另一个标头名称值,Tranfer-Encoding: chunked,它表示响应主体被分成 parts(块),并且每个部分的长度都在一行中提到在交付 part 之前。(我不包括 Transfer-Encoding 的其他值以保持此答案简洁。)

    如果这是我的 restlet 服务器:

    package restletapp;
    
    import org.restlet.Component;
    import org.restlet.data.Protocol;
    import org.restlet.resource.Get;
    import org.restlet.resource.ServerResource;
    
    public class RestletApp extends ServerResource {
    
        public static void main(String[] args) throws Exception {
            Component component = new Component();
            component.getServers().add(Protocol.HTTP, 8182);
            component.getDefaultHost().attach("/trace", RestletApp.class);
            component.start();
        }
    
        @Get
        public String toAtGet() {
            return  "Resource URI  : " + getReference() + '\n'
                  + "Root URI      : " + getRootRef() + '\n'
                  + "Routed part   : " + getReference().getBaseRef() + '\n'
                  + "Remaining part: " + getReference().getRemainingPart()
                    ;
        }
    
    }
    

    这是我的客户端(使用 Java 中的 Sockets 编写。只需发送一个最小的 HTTP 请求,并在控制台上打印响应的每个字符。)

    package restletapp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Requester {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket s=new Socket("localhost", 8182);
            OutputStream os = s.getOutputStream();
            os.write((
                      "GET /trace HTTP/1.1\r\n" //request
                    + "host: localhost:8182\r\n" //request
                    + "Connection-type: close\r\n\r\n" //request
                    ).getBytes());
            InputStream is = s.getInputStream();
            for(int ch;(ch=is.read())!=-1;System.out.flush())
                System.out.write(ch); //response, one char at a time.
            is.close();
            os.close();
            s.close();
        }
    }
    

    客户端进程永远不会结束。但是如果我把我的客户端程序改成这样:

    package restletapp;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Requester {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket s=new Socket("localhost", 8182);
            OutputStream os = s.getOutputStream();
            os.write((
                      "GET /trace HTTP/1.1\r\n"
                    + "host: localhost:8182\r\n"
                    + "Connection-type: close\r\n\r\n"
                    ).getBytes());
            InputStream is = s.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            int bytesRead=0;
            int contentLength=0;
            //response headers.
            for(String line;!(line=br.readLine()).isEmpty();System.out.flush()){
                System.out.println(line);
                String[] tokens = line.split(":| ");
                if(tokens[0].equalsIgnoreCase("content-length")){
                    contentLength=Integer.parseInt(tokens[2]);
                }
            }
            //response separator, between headers and body.
            System.out.println();
            //response body.
            while(bytesRead<contentLength){
                System.out.write(br.read());
                System.out.flush();
                bytesRead++;
            }
            is.close();
            os.close();
            s.close();
        }
    }
    

    在Requester的第二个版本中,可以看到在读取响应体的content-length-number of characters时,连接被客户端关闭。

    这是我使用 curl 得到的:

    command line $ curl -i "http://localhost:8182/trace"
    HTTP/1.1 200 OK
    Date: Fri, 14 Jun 2013 11:54:32 GMT
    Server: Restlet-Framework/2.0.15
    Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
    Content-Length: 148
    Content-Type: text/plain; charset=UTF-8
    
    Resource URI  : http://localhost:8182/trace
    Root URI      : http://localhost:8182/trace
    Routed part   : http://localhost:8182/trace
    Remaining part:
    command line $ 
    

    可以看到,curl阅读完内容就退出了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多