Java中的HTTP客戶端工具——HttpClient

客戶端http協(xié)議傳輸類庫拐叉。HttpClient被用來發(fā)送和接受Http消息理郑。HttpClient不會(huì)處理Http消息的內(nèi)容,不會(huì)進(jìn)行Javascript解析,不會(huì)關(guān)心ContentType病毡,如果沒有明確設(shè)置,HttpClient也不會(huì)對(duì)請(qǐng)求進(jìn)行格式化屁柏、重定向url啦膜,或者其他任何和http消息傳輸相關(guān)的功能。

HttpClient核心接口

org.apache.http.HttpMessage:HTTP 消息由客戶端到服務(wù)器的請(qǐng)求和服務(wù)器到客戶端的響應(yīng)組成淌喻。
org.apache.http.HttpRequest:從客戶端到服務(wù)器的請(qǐng)求消息在該消息的第一行中包括要應(yīng)用于資源的方法僧家、資源的標(biāo)識(shí)符和正在使用的協(xié)議版本。
org.apache.http.client.HttpClient:這個(gè)接口只代表了 HTTP 請(qǐng)求執(zhí)行的最基本的合約裸删。它對(duì)請(qǐng)求執(zhí)行過程沒有施加任何限制或特定細(xì)節(jié)八拱,并將狀態(tài)管理、身份驗(yàn)證和重定向處理的細(xì)節(jié)留給單獨(dú)的實(shí)現(xiàn)。
org.apache.http.HttpResponse:在接收并解釋請(qǐng)求消息后肌稻,服務(wù)器以 HTTP 響應(yīng)消息進(jìn)行響應(yīng)清蚀。

核心依賴

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

HttpClient入?yún)?/h3>

實(shí)體入?yún)⒌恼?qǐng)求需要繼承HttpEntityEnclosingRequestBase,官方HttpDelete/HttpPatch/HttpPost/HttpPut均支持實(shí)體入?yún)?/strong>

public abstract class HttpEntityEnclosingRequestBase
    extends HttpRequestBase implements HttpEntityEnclosingRequest {

    private HttpEntity entity;

    public HttpEntityEnclosingRequestBase() {
        super();
    }

    @Override
    public HttpEntity getEntity() {
        return this.entity;
    }

    @Override
    public void setEntity(final HttpEntity entity) {
        this.entity = entity;
    }

    @Override
    public boolean expectContinue() {
        final Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE);
        return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue());
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        final HttpEntityEnclosingRequestBase clone =
            (HttpEntityEnclosingRequestBase) super.clone();
        if (this.entity != null) {
            clone.entity = CloneUtils.cloneObject(this.entity);
        }
        return clone;
    }

}

無需實(shí)體入?yún)⒌恼?qǐng)求可以直接繼承HttpRequestBase,官方HttpGet/HttpHead/HttpOptions/HttpTrace均不支持實(shí)體入?yún)⒌罚瑢?shí)在有需要可以自行重寫枷邪,直接繼承HttpEntityEnclosingRequestBase即可

public abstract class HttpRequestBase extends AbstractExecutionAwareRequest
    implements HttpUriRequest, Configurable {

    private ProtocolVersion version;
    private URI uri;
    private RequestConfig config;

    @Override
    public abstract String getMethod();

    /**
     * @since 4.3
     */
    public void setProtocolVersion(final ProtocolVersion version) {
        this.version = version;
    }

    @Override
    public ProtocolVersion getProtocolVersion() {
        return version != null ? version : HttpProtocolParams.getVersion(getParams());
    }

    @Override
    public URI getURI() {
        return this.uri;
    }

    @Override
    public RequestLine getRequestLine() {
        final String method = getMethod();
        final ProtocolVersion ver = getProtocolVersion();
        final URI uriCopy = getURI(); // avoids possible window where URI could be changed
        String uritext = null;
        if (uriCopy != null) {
            uritext = uriCopy.toASCIIString();
        }
        if (uritext == null || uritext.isEmpty()) {
            uritext = "/";
        }
        return new BasicRequestLine(method, uritext, ver);
    }


    @Override
    public RequestConfig getConfig() {
        return config;
    }

    public void setConfig(final RequestConfig config) {
        this.config = config;
    }

    public void setURI(final URI uri) {
        this.uri = uri;
    }

    public void started() {
    }

    public void releaseConnection() {
        reset();
    }

    @Override
    public String toString() {
        return getMethod() + " " + getURI() + " " + getProtocolVersion();
    }

}
HttpEntityEnclosingRequestBase繼承關(guān)系圖

HttpEntity:HTTP 消息發(fā)送或接收的實(shí)體,HttpEntityEnclosingRequestBase中的屬性

public interface HttpEntity {
    //實(shí)體是否能夠多次生成其數(shù)據(jù)诺凡《В可重復(fù)實(shí)體的 getContent() 和 writeTo(OutputStream) 方法可以多次調(diào)用,而不可重復(fù)實(shí)體則不能腹泌。
    boolean isRepeatable();
    //實(shí)體的分塊編碼嘶卧。HTTP1.0不支持分塊。此方法的主要目的是指示在發(fā)送實(shí)體時(shí)是否應(yīng)使用分塊編碼凉袱。對(duì)于接收到的實(shí)體芥吟,它還可以指示是否使用分塊編碼接收到實(shí)體。
    boolean isChunked();
    //內(nèi)容的長度
    long getContentLength();
    //獲取 Content-Type 標(biāo)頭专甩。這是發(fā)送實(shí)體時(shí)應(yīng)使用的標(biāo)頭钟鸵,或者與實(shí)體一起接收的標(biāo)頭。它可以包含一個(gè)字符集屬性配深。
    Header getContentType();
    //獲取 Content-Encoding 標(biāo)頭携添。這是發(fā)送實(shí)體時(shí)應(yīng)使用的標(biāo)頭嫁盲,或者與實(shí)體一起接收的標(biāo)頭篓叶。修改內(nèi)容編碼的包裝實(shí)體應(yīng)相應(yīng)地調(diào)整此標(biāo)頭。
    Header getContentEncoding();
    //實(shí)體的內(nèi)容流羞秤「淄校可Repeatable實(shí)體應(yīng)為每次調(diào)用此方法創(chuàng)建一個(gè)新的InputStream實(shí)例,因此可以多次使用瘾蛋。不可repeatable的實(shí)體應(yīng)返回相同的InputStream實(shí)例俐镐,因此不得多次使用。
    InputStream getContent() throws IOException, UnsupportedOperationException;
    //實(shí)體內(nèi)容寫入輸出流哺哼。重要提示:請(qǐng)注意佩抹,所有實(shí)體實(shí)現(xiàn)必須確保在此方法返回時(shí)正確釋放所有分配的資源。
    void writeTo(OutputStream outStream) throws IOException;
    //實(shí)體是否依賴于基礎(chǔ)流取董。直接從套接字讀取數(shù)據(jù)的流式實(shí)體應(yīng)返回true 棍苹。自包含實(shí)體應(yīng)返回false 。包裝實(shí)體應(yīng)將此調(diào)用委托給被包裝實(shí)體茵汰。
    boolean isStreaming(); // don't expect an exception here
    //自 4.1 版起已棄用枢里。調(diào)用該方法表示不再需要該實(shí)體的內(nèi)容。由于此方法調(diào)用,所有實(shí)體實(shí)現(xiàn)都應(yīng)釋放所有分配的資源栏豺。
    @Deprecated
    void consumeContent() throws IOException;
}
AbstractHttpEntity:實(shí)體的抽象基類彬碱。為HttpEntity的流式和自包含實(shí)現(xiàn)提供常用屬性。
public abstract class AbstractHttpEntity implements HttpEntity {
    protected static final int OUTPUT_BUFFER_SIZE = 4096;
    protected Header contentType;
    protected Header contentEncoding;
    protected boolean chunked;

    protected AbstractHttpEntity() {
        super();
    }

    @Override
    public Header getContentType() {
        return this.contentType;
    }

    @Override
    public Header getContentEncoding() {
        return this.contentEncoding;
    }

    @Override
    public boolean isChunked() {
        return this.chunked;
    }

    public void setContentType(final Header contentType) {
        this.contentType = contentType;
    }

    public void setContentType(final String ctString) {
        Header h = null;
        if (ctString != null) {
            h = new BasicHeader(HTTP.CONTENT_TYPE, ctString);
        }
        setContentType(h);
    }

    public void setContentEncoding(final Header contentEncoding) {
        this.contentEncoding = contentEncoding;
    }

    public void setContentEncoding(final String ceString) {
        Header h = null;
        if (ceString != null) {
            h = new BasicHeader(HTTP.CONTENT_ENCODING, ceString);
        }
        setContentEncoding(h);
    }

    public void setChunked(final boolean b) {
        this.chunked = b;
    }

    @Override
    @Deprecated
    public void consumeContent() throws IOException {
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (contentType != null) {
            sb.append("Content-Type: ");
            sb.append(contentType.getValue());
            sb.append(',');
        }
        if (contentEncoding != null) {
            sb.append("Content-Encoding: ");
            sb.append(contentEncoding.getValue());
            sb.append(',');
        }
        final long len = getContentLength();
        if (len >= 0) {
            sb.append("Content-Length: ");
            sb.append(len);
            sb.append(',');
        }
        sb.append("Chunked: ");
        sb.append(chunked);
        sb.append(']');
        return sb.toString();
    }

}

AbstractHttpEntity下常用實(shí)體
BasicHttpEntity:從InputStream獲取其內(nèi)容的通用流式奥洼、不可重復(fù)實(shí)體
ByteArrayEntity:一個(gè)自包含的巷疼、可重復(fù)的實(shí)體,它從字節(jié)數(shù)組中獲取其內(nèi)容溉卓。
EntityTemplate:將內(nèi)容生成過程委托給ContentProducer的實(shí)體皮迟。
FileEntity:從文件中獲取其內(nèi)容的自包含、可重復(fù)的實(shí)體桑寨。
InputStreamEntity:從InputStream獲取其內(nèi)容的流式伏尼、不可重復(fù)的實(shí)體。
SerializableEntity:從Serializable獲取其內(nèi)容的流式實(shí)體尉尾。從Serializable實(shí)例獲得的內(nèi)容可以選擇緩沖在字節(jié)數(shù)組中爆阶,以使實(shí)體自包含和可重復(fù)。
StringEntity:一個(gè)自包含沙咏、可重復(fù)的實(shí)體辨图,從String獲取其內(nèi)容。
UrlEncodedFormEntity:由 url 編碼對(duì)列表組成的實(shí)體肢藐。這在發(fā)送 HTTP POST 請(qǐng)求時(shí)通常很有用故河。

HttpEntityWrapper:用于包裝實(shí)體的基類。保留一個(gè)wrappedEntity并將所有調(diào)用委托給它吆豹。包裝實(shí)體的實(shí)現(xiàn)可以從此類派生鱼的,并且只需要覆蓋那些不應(yīng)委托給包裝實(shí)體的方法。
public class HttpEntityWrapper implements HttpEntity {
    protected HttpEntity wrappedEntity;

    public HttpEntityWrapper(final HttpEntity wrappedEntity) {
        super();
        this.wrappedEntity = Args.notNull(wrappedEntity, "Wrapped entity");
    }

    @Override
    public boolean isRepeatable() {
        return wrappedEntity.isRepeatable();
    }

    @Override
    public boolean isChunked() {
        return wrappedEntity.isChunked();
    }

    @Override
    public long getContentLength() {
        return wrappedEntity.getContentLength();
    }

    @Override
    public Header getContentType() {
        return wrappedEntity.getContentType();
    }

    @Override
    public Header getContentEncoding() {
        return wrappedEntity.getContentEncoding();
    }

    @Override
    public InputStream getContent()
        throws IOException {
        return wrappedEntity.getContent();
    }

    @Override
    public void writeTo(final OutputStream outStream)
        throws IOException {
        wrappedEntity.writeTo(outStream);
    }

    @Override
    public boolean isStreaming() {
        return wrappedEntity.isStreaming();
    }

    @Override
    @Deprecated
    public void consumeContent() throws IOException {
        wrappedEntity.consumeContent();
    }

}

HttpEntityWrapper下常用實(shí)體
BufferedHttpEntity:必要時(shí)緩沖其內(nèi)容的包裝實(shí)體痘煤。緩沖實(shí)體始終是可重復(fù)的凑阶。如果被包裝的實(shí)體本身是可重復(fù)的,則調(diào)用被傳遞衷快。如果包裝的實(shí)體不可重復(fù)宙橱,則將內(nèi)容一次讀入緩沖區(qū)并根據(jù)需要從那里提供。
DecompressingEntity:用于解壓HttpEntity實(shí)現(xiàn)的通用基類,其子類有支持Deflate的DeflateDecompressingEntity和支持GZip的GzipDecompressingEntity
GzipCompressingEntity:writing時(shí)壓縮內(nèi)容的包裝實(shí)體蘸拔。
ResponseEntityProxy:包含在響應(yīng)消息中的HttpEntity的包裝器類师郑。

HttpClient發(fā)起請(qǐng)求

HTTP 請(qǐng)求執(zhí)行的基本類HttpClient
目前最常用的實(shí)現(xiàn)類的是CloseableHttpClient,以前的DefaultHttpClient在自4.3版本之后作廢了。

@Contract(threading = ThreadingBehavior.SAFE)
public abstract class CloseableHttpClient implements HttpClient, Closeable {

    private final Log log = LogFactory.getLog(getClass());

    protected abstract CloseableHttpResponse doExecute(HttpHost target, HttpRequest request,
            HttpContext context) throws IOException, ClientProtocolException;
    //使用默認(rèn)上下文執(zhí)行 HTTP 請(qǐng)求调窍。
    @Override
    public CloseableHttpResponse execute(
            final HttpHost target,
            final HttpRequest request,
            final HttpContext context) throws IOException, ClientProtocolException {
        return doExecute(target, request, context);
    }

    @Override
    public CloseableHttpResponse execute(
            final HttpUriRequest request,
            final HttpContext context) throws IOException, ClientProtocolException {
        Args.notNull(request, "HTTP request");
        return doExecute(determineTarget(request), request, context);
    }

    private static HttpHost determineTarget(final HttpUriRequest request) throws ClientProtocolException {
        HttpHost target = null;

        final URI requestURI = request.getURI();
        if (requestURI.isAbsolute()) {
            target = URIUtils.extractHost(requestURI);
            if (target == null) {
                throw new ClientProtocolException("URI does not specify a valid host name: "
                        + requestURI);
            }
        }
        return target;
    }

    @Override
    public CloseableHttpResponse execute(
            final HttpUriRequest request) throws IOException, ClientProtocolException {
        return execute(request, (HttpContext) null);
    }

    @Override
    public CloseableHttpResponse execute(
            final HttpHost target,
            final HttpRequest request) throws IOException, ClientProtocolException {
        return doExecute(target, request, null);
    }

    @Override
    public <T> T execute(final HttpUriRequest request,
            final ResponseHandler<? extends T> responseHandler) throws IOException,
            ClientProtocolException {
        return execute(request, responseHandler, null);
    }

    @Override
    public <T> T execute(final HttpUriRequest request,
            final ResponseHandler<? extends T> responseHandler, final HttpContext context)
            throws IOException, ClientProtocolException {
        final HttpHost target = determineTarget(request);
        return execute(target, request, responseHandler, context);
    }

    @Override
    public <T> T execute(final HttpHost target, final HttpRequest request,
            final ResponseHandler<? extends T> responseHandler) throws IOException,
            ClientProtocolException {
        return execute(target, request, responseHandler, null);
    }

    @Override
    public <T> T execute(final HttpHost target, final HttpRequest request,
            final ResponseHandler<? extends T> responseHandler, final HttpContext context)
            throws IOException, ClientProtocolException {
        Args.notNull(responseHandler, "Response handler");

        final CloseableHttpResponse response = execute(target, request, context);
        try {
            final T result = responseHandler.handleResponse(response);
            final HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
            return result;
        } catch (final ClientProtocolException t) {
            // Try to salvage the underlying connection in case of a protocol exception
            final HttpEntity entity = response.getEntity();
            try {
                EntityUtils.consume(entity);
            } catch (final Exception t2) {
                // Log this exception. The original exception is more
                // important and will be thrown to the caller.
                this.log.warn("Error consuming content after an exception.", t2);
            }
            throw t;
        } finally {
            response.close();
        }
    }

}

target(HttpHost):請(qǐng)求的目標(biāo)主機(jī)宝冕。如果實(shí)現(xiàn)仍然可以確定路由,例如到默認(rèn)目標(biāo)或通過檢查請(qǐng)求陨晶,則可以接受null 猬仁。
request:要執(zhí)行的請(qǐng)求帝璧,支持HttpRequestHttpUriRequest
responseHandler(ResponseHandler):響應(yīng)處理程序
context(HttpContext):用于執(zhí)行的上下文,或null使用默認(rèn)上下文

HttpClientsCloseableHttpClient實(shí)例的工廠方法湿刽。
public class HttpClients {

    private HttpClients() {
        super();
    }
    //創(chuàng)建構(gòu)建器對(duì)象以構(gòu)建自定義CloseableHttpClient實(shí)例的烁。
    public static HttpClientBuilder custom() {
        return HttpClientBuilder.create();
    }
    //使用默認(rèn)配置創(chuàng)建CloseableHttpClient實(shí)例。
    public static CloseableHttpClient createDefault() {
        return HttpClientBuilder.create().build();
    }
    //基于系統(tǒng)屬性創(chuàng)建具有默認(rèn)配置的CloseableHttpClient實(shí)例诈闺。
    public static CloseableHttpClient createSystem() {
        return HttpClientBuilder.create().useSystemProperties().build();
    }
    //創(chuàng)建實(shí)現(xiàn)最基本 HTTP 協(xié)議支持的CloseableHttpClient實(shí)例渴庆。
    public static CloseableHttpClient createMinimal() {
        return new MinimalHttpClient(new PoolingHttpClientConnectionManager());
    }
    //創(chuàng)建實(shí)現(xiàn)最基本 HTTP 協(xié)議支持的CloseableHttpClient實(shí)例。
    public static CloseableHttpClient createMinimal(final HttpClientConnectionManager connManager) {
        return new MinimalHttpClient(connManager);
    }

}

HttpClient響應(yīng)

目前最常用的是CloseableHttpResponse

public interface CloseableHttpResponse extends HttpResponse, Closeable {
}

HttpResponse

public interface HttpResponse extends HttpMessage {
    //獲取此響應(yīng)的狀態(tài)行雅镊〗罄祝可以使用setStatusLine方法之一設(shè)置狀態(tài)行,也可以在構(gòu)造函數(shù)中對(duì)其進(jìn)行初始化仁烹。
    StatusLine getStatusLine();
    //設(shè)置此響應(yīng)的狀態(tài)行耸弄。
    void setStatusLine(StatusLine statusline);
    //設(shè)置此響應(yīng)的狀態(tài)行。原因短語將根據(jù)當(dāng)前l(fā)ocale確定卓缰。
    void setStatusLine(ProtocolVersion ver, int code);
    void setStatusLine(ProtocolVersion ver, int code, String reason);
    //使用新的狀態(tài)代碼更新此響應(yīng)的狀態(tài)行计呈。
    void setStatusCode(int code)
        throws IllegalStateException;
    //使用新的原因短語更新此響應(yīng)的狀態(tài)行。
    void setReasonPhrase(String reason)
        throws IllegalStateException;
    //獲取此響應(yīng)的消息實(shí)體(如果有)征唬。該實(shí)體是通過調(diào)用setEntity來提供的捌显。
    HttpEntity getEntity();
    //將響應(yīng)實(shí)體與此響應(yīng)相關(guān)聯(lián)。
    void setEntity(HttpEntity entity);
    //更改此響應(yīng)的語言環(huán)境总寒。
    void setLocale(Locale loc);
}
CloseableHttpResponse繼承關(guān)系圖

HttpClient進(jìn)行POST請(qǐng)求例子:

    private static String sendPOST(String url) throws IOException {
        String result = "";
        HttpPost post = new HttpPost(url);
        List<NameValuePair> urlParameters = new ArrayList<>();
        urlParameters.add(new BasicNameValuePair("username", "abc"));
        urlParameters.add(new BasicNameValuePair("password", "123"));
        post.setEntity(new UrlEncodedFormEntity(urlParameters));
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(post)){
            result = EntityUtils.toString(response.getEntity());
        }
        return result;
    }
HttpURLConnection相關(guān)博客推薦

上傳文件:https://lsqingfeng.blog.csdn.net/article/details/90611686
下載文件:https://blog.csdn.net/WxQ92222/article/details/79896489

調(diào)用鏈路源碼分析可以參考:
https://blog.csdn.net/u012504392/article/details/109432686

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扶歪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子摄闸,更是在濱河造成了極大的恐慌善镰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪薪,死亡現(xiàn)場離奇詭異媳禁,居然都是意外死亡眠副,警方通過查閱死者的電腦和手機(jī)画切,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來囱怕,“玉大人霍弹,你說我怎么就攤上這事⊥薰” “怎么了典格?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長台丛。 經(jīng)常有香客問我耍缴,道長砾肺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任防嗡,我火速辦了婚禮变汪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚁趁。我一直安慰自己裙盾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布他嫡。 她就那樣靜靜地躺著番官,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钢属。 梳的紋絲不亂的頭發(fā)上徘熔,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音淆党,去河邊找鬼近顷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宁否,可吹牛的內(nèi)容都是我干的窒升。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼慕匠,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼饱须!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起台谊,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蓉媳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后锅铅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酪呻,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年盐须,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玩荠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贼邓,死狀恐怖阶冈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情塑径,我是刑警寧澤女坑,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站统舀,受9級(jí)特大地震影響匆骗,放射性物質(zhì)發(fā)生泄漏劳景。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一碉就、第九天 我趴在偏房一處隱蔽的房頂上張望枢泰。 院中可真熱鬧,春花似錦铝噩、人聲如沸衡蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毛甲。三九已至,卻和暖如春具被,著一層夾襖步出監(jiān)牢的瞬間玻募,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工一姿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留七咧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓叮叹,卻偏偏與公主長得像艾栋,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛉顽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容